Add D3DRMFrame parent <-> child relation (#161)

* Add D3DRMFrame parent <-> child relation

* Apply suggestions from code review
This commit is contained in:
Anonymous Maarten 2025-05-25 07:18:53 +02:00 committed by GitHub
parent 61c2ca27c2
commit bdbd0e31d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 164 additions and 80 deletions

View File

@ -101,6 +101,7 @@ add_library(miniwin STATIC EXCLUDE_FROM_ALL
miniwin/miniwin/src/miniwin_d3drmframe.cpp
miniwin/miniwin/src/miniwin_d3drmlight.cpp
miniwin/miniwin/src/miniwin_d3drmmesh.cpp
miniwin/miniwin/src/miniwin_d3drmtexture.cpp
miniwin/miniwin/src/miniwin_d3drmviewport.cpp
)
# Force reported render mods from MiniWin

View File

@ -22,10 +22,10 @@ Result CameraImpl::SetTransformation(FloatMatrix4& matrix)
Result result;
Result result2;
result2 = ResultVal(m_data->GetPosition(0, &position));
result2 = ResultVal(m_data->GetPosition(NULL, &position));
result = ResultVal(m_data->AddTransform(D3DRMCOMBINE_REPLACE, *pTransformation));
// The did this second call just to assert on the return value
result2 = ResultVal(m_data->GetPosition(0, &position));
result2 = ResultVal(m_data->GetPosition(NULL, &position));
return result;
}

View File

@ -129,10 +129,7 @@ typedef struct D3DRMIMAGE {
DWORD format;
} D3DRMIMAGE;
typedef struct D3DRMMATRIX4D {
double* operator[](size_t i) { abort(); }
const double* operator[](size_t i) const { abort(); }
} D3DRMMATRIX4D;
typedef D3DVALUE D3DRMMATRIX4D[4][4];
struct D3DRMBOX {
D3DVECTOR min;
@ -229,7 +226,7 @@ struct IDirect3DRMFrame : public IDirect3DRMVisual {
virtual HRESULT AddLight(IDirect3DRMLight* light) = 0;
virtual HRESULT GetLights(IDirect3DRMLightArray** lightArray) = 0;
virtual HRESULT AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix) = 0;
virtual HRESULT GetPosition(int index, D3DVECTOR* position) = 0;
virtual HRESULT GetPosition(IDirect3DRMFrame* reference, D3DVECTOR* position) = 0;
virtual HRESULT AddVisual(IDirect3DRMVisual* visual) = 0;
virtual HRESULT DeleteVisual(IDirect3DRMVisual* visual) = 0;
virtual HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) = 0;

View File

@ -11,33 +11,34 @@ typedef struct PositionColorVertex {
Uint8 r, g, b, a;
} PositionColorVertex;
template <typename InterfaceType, typename ArrayInterface>
template <typename InterfaceType, typename ActualType, typename ArrayInterface>
class Direct3DRMArrayBase : public ArrayInterface {
public:
~Direct3DRMArrayBase() override
{
for (auto* item : items) {
for (auto* item : m_items) {
if (item) {
item->Release();
}
}
}
DWORD GetSize() override { return static_cast<DWORD>(items.size()); }
DWORD GetSize() override { return static_cast<DWORD>(m_items.size()); }
HRESULT AddElement(InterfaceType* in) override
{
if (!in) {
return DDERR_INVALIDPARAMS;
}
in->AddRef();
items.push_back(in);
auto inImpl = static_cast<ActualType*>(in);
inImpl->AddRef();
m_items.push_back(inImpl);
return DD_OK;
}
HRESULT GetElement(DWORD index, InterfaceType** out) override
{
if (index >= items.size()) {
if (index >= m_items.size()) {
return DDERR_INVALIDPARAMS;
}
*out = static_cast<InterfaceType*>(items[index]);
*out = static_cast<InterfaceType*>(m_items[index]);
if (*out) {
(*out)->AddRef();
}
@ -45,32 +46,16 @@ class Direct3DRMArrayBase : public ArrayInterface {
}
HRESULT DeleteElement(InterfaceType* element) override
{
auto it = std::find(items.begin(), items.end(), element);
if (it == items.end()) {
auto it = std::find(m_items.begin(), m_items.end(), element);
if (it == m_items.end()) {
return DDERR_INVALIDPARAMS;
}
(*it)->Release();
items.erase(it);
m_items.erase(it);
return DD_OK;
}
protected:
std::vector<InterfaceType*> items;
};
struct Direct3DRMFrameArrayImpl : public Direct3DRMArrayBase<IDirect3DRMFrame, IDirect3DRMFrameArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};
struct Direct3DRMLightArrayImpl : public Direct3DRMArrayBase<IDirect3DRMLight, IDirect3DRMLightArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};
struct Direct3DRMViewportArrayImpl : public Direct3DRMArrayBase<IDirect3DRMViewport, IDirect3DRMViewportArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};
struct Direct3DRMVisualArrayImpl : public Direct3DRMArrayBase<IDirect3DRMVisual, IDirect3DRMVisualArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
std::vector<ActualType*> m_items;
};

View File

@ -1,10 +1,14 @@
#pragma once
#include "miniwin_d3drm_p.h"
#include "miniwin_d3drmobject_p.h"
class Direct3DRMTextureImpl;
class Direct3DRMLightArrayImpl;
class Direct3DRMVisualArrayImpl;
class Direct3DRMFrameArrayImpl;
struct Direct3DRMFrameImpl : public Direct3DRMObjectBase<IDirect3DRMFrame2> {
Direct3DRMFrameImpl();
Direct3DRMFrameImpl(Direct3DRMFrameImpl* parent = nullptr);
~Direct3DRMFrameImpl() override;
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
HRESULT AddChild(IDirect3DRMFrame* child) override;
@ -13,7 +17,7 @@ struct Direct3DRMFrameImpl : public Direct3DRMObjectBase<IDirect3DRMFrame2> {
HRESULT AddLight(IDirect3DRMLight* light) override;
HRESULT GetLights(IDirect3DRMLightArray** lightArray) override;
HRESULT AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix) override;
HRESULT GetPosition(int index, D3DVECTOR* position) override;
HRESULT GetPosition(IDirect3DRMFrame* reference, D3DVECTOR* position) override;
HRESULT AddVisual(IDirect3DRMVisual* visual) override;
HRESULT DeleteVisual(IDirect3DRMVisual* visual) override;
HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) override;
@ -25,11 +29,24 @@ struct Direct3DRMFrameImpl : public Direct3DRMObjectBase<IDirect3DRMFrame2> {
HRESULT SetMaterialMode(D3DRMMATERIALMODE mode) override;
HRESULT GetChildren(IDirect3DRMFrameArray** children) override;
D3DCOLOR m_backgroundColor = 0xFF000000;
private:
IDirect3DRMFrameArray* m_children;
IDirect3DRMLightArray* m_lights;
IDirect3DRMVisualArray* m_visuals;
IDirect3DRMTexture* m_texture = nullptr;
Direct3DRMFrameImpl* m_parent{};
Direct3DRMFrameArrayImpl* m_children{};
Direct3DRMLightArrayImpl* m_lights{};
Direct3DRMVisualArrayImpl* m_visuals{};
Direct3DRMTextureImpl* m_texture{};
D3DRMMATRIX4D m_transform =
{{1.f, 0.f, 0.f, 0.f}, {0.f, 1.f, 0.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 0.f, 1.f}};
D3DCOLOR m_backgroundColor = 0xFF000000;
D3DCOLOR m_color = 0xffffff;
friend class Direct3DRMViewportImpl;
};
struct Direct3DRMFrameArrayImpl
: public Direct3DRMArrayBase<IDirect3DRMFrame, Direct3DRMFrameImpl, IDirect3DRMFrameArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
friend class Direct3DRMFrameImpl;
};

View File

@ -1,6 +1,8 @@
#pragma once
#include "miniwin_d3drm_p.h"
#include "miniwin_d3drmobject_p.h"
#include "miniwin_p.h"
struct Direct3DRMLightImpl : public Direct3DRMObjectBase<IDirect3DRMLight> {
Direct3DRMLightImpl(float r, float g, float b);
@ -9,3 +11,8 @@ struct Direct3DRMLightImpl : public Direct3DRMObjectBase<IDirect3DRMLight> {
private:
D3DCOLOR m_color = 0xFFFFFFFF;
};
struct Direct3DRMLightArrayImpl
: public Direct3DRMArrayBase<IDirect3DRMLight, Direct3DRMLightImpl, IDirect3DRMLightArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};

View File

@ -0,0 +1,8 @@
#pragma once
#include "miniwin_d3drmobject_p.h"
struct Direct3DRMTextureImpl : public Direct3DRMObjectBase<IDirect3DRMTexture2> {
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
HRESULT Changed(BOOL pixels, BOOL palette) override;
};

View File

@ -1,11 +1,13 @@
#pragma once
#include "miniwin_d3drm.h"
#include "miniwin_d3drmdevice_p.h"
#include "miniwin_d3drmobject_p.h"
#include <SDL3/SDL.h>
class Direct3DRMDeviceImpl;
class Direct3DRMFrameImpl;
struct Direct3DRMViewportImpl : public Direct3DRMObjectBase<IDirect3DRMViewport> {
Direct3DRMViewportImpl(
DWORD width,
@ -58,4 +60,12 @@ struct Direct3DRMViewportImpl : public Direct3DRMObjectBase<IDirect3DRMViewport>
SDL_GPUTransferBuffer* m_downloadTransferBuffer;
SDL_GPUBuffer* m_vertexBuffer = nullptr;
SDL_Surface* m_renderedImage = nullptr;
D3DVALUE m_front = 1.f;
D3DVALUE m_back = 10.f;
D3DVALUE m_field = 0.5f;
};
struct Direct3DRMViewportArrayImpl
: public Direct3DRMArrayBase<IDirect3DRMViewport, Direct3DRMViewportImpl, IDirect3DRMViewportArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};

View File

@ -0,0 +1,9 @@
#pragma once
#include "miniwin_d3drm.h"
#include "miniwin_d3drmobject_p.h"
struct Direct3DRMVisualArrayImpl
: public Direct3DRMArrayBase<IDirect3DRMVisual, IDirect3DRMVisual, IDirect3DRMVisualArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};

View File

@ -0,0 +1 @@
#pragma once

View File

@ -2,10 +2,12 @@
#include "ShaderIndex.h"
#include "miniwin_d3drm_p.h"
#include "miniwin_d3drmdevice_p.h"
#include "miniwin_d3drmframe_p.h"
#include "miniwin_d3drmlight_p.h"
#include "miniwin_d3drmmesh_p.h"
#include "miniwin_d3drmobject_p.h"
#include "miniwin_d3drmtexture_p.h"
#include "miniwin_d3drmviewport_p.h"
#include "miniwin_ddsurface_p.h"
#include "miniwin_p.h"
@ -75,24 +77,6 @@ struct Direct3DRMWinDeviceImpl : public IDirect3DRMWinDevice {
void HandlePaint(void* p_dc) override { MINIWIN_NOT_IMPLEMENTED(); }
};
struct Direct3DRMTextureImpl : public Direct3DRMObjectBase<IDirect3DRMTexture2> {
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override
{
if (SDL_memcmp(&riid, &IID_IDirect3DRMTexture2, sizeof(GUID)) == 0) {
this->IUnknown::AddRef();
*ppvObject = static_cast<IDirect3DRMTexture2*>(this);
return DD_OK;
}
MINIWIN_NOT_IMPLEMENTED();
return E_NOINTERFACE;
}
HRESULT Changed(BOOL pixels, BOOL palette) override
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
};
struct Direct3DRMMaterialImpl : public Direct3DRMObjectBase<IDirect3DRMMaterial> {};
SDL_GPUGraphicsPipeline* InitializeGraphicsPipeline(SDL_GPUDevice* device)
@ -241,11 +225,8 @@ struct Direct3DRMImpl : virtual public IDirect3DRM2 {
}
HRESULT CreateFrame(IDirect3DRMFrame* parent, IDirect3DRMFrame2** outFrame) override
{
auto frame = new Direct3DRMFrameImpl;
*outFrame = static_cast<IDirect3DRMFrame2*>(frame);
if (parent) {
parent->AddChild(static_cast<IDirect3DRMFrame*>(frame));
}
auto parentImpl = static_cast<Direct3DRMFrameImpl*>(parent);
*outFrame = static_cast<IDirect3DRMFrame2*>(new Direct3DRMFrameImpl{parentImpl});
return DD_OK;
}
HRESULT CreateViewport(

View File

@ -1,5 +1,6 @@
#include "miniwin_d3drm.h"
#include "miniwin_d3drm_p.h"
#include "miniwin_d3drmdevice_p.h"
#include "miniwin_d3drmobject_p.h"
#include "miniwin_d3drmviewport_p.h"
#include "miniwin_p.h"

View File

@ -1,7 +1,13 @@
#include "miniwin_d3drm_p.h"
#include "miniwin_d3drmframe_p.h"
#include "miniwin_d3drmlight_p.h"
#include "miniwin_d3drmtexture_p.h"
#include "miniwin_d3drmvisual_p.h"
#include "miniwin_p.h"
Direct3DRMFrameImpl::Direct3DRMFrameImpl()
#include <cstring>
Direct3DRMFrameImpl::Direct3DRMFrameImpl(Direct3DRMFrameImpl* parent)
{
m_children = new Direct3DRMFrameArrayImpl;
m_children->AddRef();
@ -9,6 +15,9 @@ Direct3DRMFrameImpl::Direct3DRMFrameImpl()
m_lights->AddRef();
m_visuals = new Direct3DRMVisualArrayImpl;
m_visuals->AddRef();
if (parent) {
parent->AddChild(this);
}
}
Direct3DRMFrameImpl::~Direct3DRMFrameImpl()
@ -37,12 +46,32 @@ HRESULT Direct3DRMFrameImpl::QueryInterface(const GUID& riid, void** ppvObject)
HRESULT Direct3DRMFrameImpl::AddChild(IDirect3DRMFrame* child)
{
if (!child) {
return DDERR_GENERIC;
}
Direct3DRMFrameImpl* childImpl = static_cast<Direct3DRMFrameImpl*>(child);
if (childImpl->m_parent) {
if (childImpl->m_parent == this) {
return DD_OK;
}
auto result = childImpl->m_parent->m_children->DeleteElement(childImpl);
SDL_assert(result == DD_OK);
}
childImpl->m_parent = this;
return m_children->AddElement(child);
}
HRESULT Direct3DRMFrameImpl::DeleteChild(IDirect3DRMFrame* child)
{
return m_children->DeleteElement(child);
Direct3DRMFrameImpl* childImpl = static_cast<Direct3DRMFrameImpl*>(child);
if (!childImpl) {
return DDERR_GENERIC;
}
HRESULT result = m_children->DeleteElement(childImpl);
if (result == DD_OK) {
childImpl->m_parent = nullptr;
}
return result;
}
HRESULT Direct3DRMFrameImpl::SetSceneBackgroundRGB(float r, float g, float b)
@ -66,18 +95,31 @@ HRESULT Direct3DRMFrameImpl::GetLights(IDirect3DRMLightArray** lightArray)
HRESULT Direct3DRMFrameImpl::AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
switch (combine) {
case D3DRMCOMBINETYPE::REPLACE:
std::memcpy(m_transform, matrix, sizeof(m_transform));
return DD_OK;
default:
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
}
HRESULT Direct3DRMFrameImpl::GetPosition(int index, D3DVECTOR* position)
HRESULT Direct3DRMFrameImpl::GetPosition(IDirect3DRMFrame* reference, D3DVECTOR* position)
{
MINIWIN_NOT_IMPLEMENTED();
if (reference) {
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
position->x = m_transform[3][0] / m_transform[3][3];
position->y = m_transform[3][1] / m_transform[3][3];
position->z = m_transform[3][2] / m_transform[3][3];
return DD_OK;
}
HRESULT Direct3DRMFrameImpl::AddVisual(IDirect3DRMVisual* visual)
{
SDL_assert(false); // Is this actually used?
return m_visuals->AddElement(visual);
}
@ -95,11 +137,15 @@ HRESULT Direct3DRMFrameImpl::GetVisuals(IDirect3DRMVisualArray** visuals)
HRESULT Direct3DRMFrameImpl::SetTexture(IDirect3DRMTexture* texture)
{
if (!texture) {
return DDERR_GENERIC;
}
auto textureImpl = static_cast<Direct3DRMTextureImpl*>(texture);
if (m_texture) {
m_texture->Release();
}
m_texture = texture;
m_texture = textureImpl;
m_texture->AddRef();
return DD_OK;
}
@ -111,26 +157,28 @@ HRESULT Direct3DRMFrameImpl::GetTexture(IDirect3DRMTexture** texture)
}
*texture = m_texture;
m_texture->AddRef();
if (m_texture) {
m_texture->AddRef();
}
return DD_OK;
}
HRESULT Direct3DRMFrameImpl::SetColor(float r, float g, float b, float a)
{
MINIWIN_NOT_IMPLEMENTED();
m_color = (static_cast<BYTE>(a * 255.0f) << 24) | (static_cast<BYTE>(r * 255.0f) << 16) |
(static_cast<BYTE>(g * 255.0f) << 8) | (static_cast<BYTE>(b * 255.0f));
return DD_OK;
}
HRESULT Direct3DRMFrameImpl::SetColor(D3DCOLOR)
HRESULT Direct3DRMFrameImpl::SetColor(D3DCOLOR c)
{
MINIWIN_NOT_IMPLEMENTED();
m_color = c;
return DD_OK;
}
HRESULT Direct3DRMFrameImpl::SetColorRGB(float r, float g, float b)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
return SetColor(r, g, b, 1.f);
}
HRESULT Direct3DRMFrameImpl::SetMaterialMode(D3DRMMATERIALMODE mode)

View File

@ -0,0 +1,19 @@
#include "miniwin_d3drmtexture_p.h"
#include "miniwin_p.h"
HRESULT Direct3DRMTextureImpl::QueryInterface(const GUID& riid, void** ppvObject)
{
if (SDL_memcmp(&riid, &IID_IDirect3DRMTexture2, sizeof(GUID)) == 0) {
this->IUnknown::AddRef();
*ppvObject = static_cast<IDirect3DRMTexture2*>(this);
return DD_OK;
}
MINIWIN_NOT_IMPLEMENTED();
return E_NOINTERFACE;
}
HRESULT Direct3DRMTextureImpl::Changed(BOOL pixels, BOOL palette)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}