mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-19 05:41:17 +00:00
Implement 3D geometry rendering (#162)
This commit is contained in:
parent
695b697c4b
commit
8782fdb62e
@ -101,6 +101,7 @@ typedef D3DRMPROJECTIONTYPE* LPD3DRMPROJECTIONTYPE;
|
|||||||
// --- GUIDs ---
|
// --- GUIDs ---
|
||||||
DEFINE_GUID(IID_IDirect3DRM2, 0x4516ecc8, 0x8f20, 0x11d0, 0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3);
|
DEFINE_GUID(IID_IDirect3DRM2, 0x4516ecc8, 0x8f20, 0x11d0, 0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3);
|
||||||
DEFINE_GUID(IID_IDirect3DRMWinDevice, 0xc5016cc0, 0xd273, 0x11ce, 0xac, 0x48, 0x00, 0x00, 0xc0, 0x38, 0x25, 0xa1);
|
DEFINE_GUID(IID_IDirect3DRMWinDevice, 0xc5016cc0, 0xd273, 0x11ce, 0xac, 0x48, 0x00, 0x00, 0xc0, 0x38, 0x25, 0xa1);
|
||||||
|
DEFINE_GUID(IID_IDirect3DRMFrame, 0xeb16cb03, 0xd271, 0x11ce, 0xac, 0x48, 0x0, 0x0, 0xc0, 0x38, 0x25, 0xa1);
|
||||||
DEFINE_GUID(IID_IDirect3DRMMesh, 0xa3a80d01, 0x6e12, 0x11cf, 0xac, 0x4a, 0x00, 0x00, 0xc0, 0x38, 0x25, 0xa1);
|
DEFINE_GUID(IID_IDirect3DRMMesh, 0xa3a80d01, 0x6e12, 0x11cf, 0xac, 0x4a, 0x00, 0x00, 0xc0, 0x38, 0x25, 0xa1);
|
||||||
DEFINE_GUID(IID_IDirect3DRMMeshBuilder, 0xa3a80d02, 0x6e12, 0x11cf, 0xac, 0x4a, 0x00, 0x00, 0xc0, 0x38, 0x25, 0xa1);
|
DEFINE_GUID(IID_IDirect3DRMMeshBuilder, 0xa3a80d02, 0x6e12, 0x11cf, 0xac, 0x4a, 0x00, 0x00, 0xc0, 0x38, 0x25, 0xa1);
|
||||||
DEFINE_GUID(IID_IDirect3DRMTexture2, 0x120f30c0, 0x1629, 0x11d0, 0x94, 0x1c, 0x00, 0x80, 0xc8, 0x0c, 0xfa, 0x7b);
|
DEFINE_GUID(IID_IDirect3DRMTexture2, 0x120f30c0, 0x1629, 0x11d0, 0x94, 0x1c, 0x00, 0x80, 0xc8, 0x0c, 0xfa, 0x7b);
|
||||||
@ -185,6 +186,7 @@ struct IDirect3DRMMesh : public IDirect3DRMVisual {
|
|||||||
DWORD* dataSize,
|
DWORD* dataSize,
|
||||||
DWORD* data
|
DWORD* data
|
||||||
) = 0;
|
) = 0;
|
||||||
|
virtual DWORD GetGroupCount() = 0;
|
||||||
virtual HRESULT SetGroupColor(DWORD groupIndex, D3DCOLOR color) = 0;
|
virtual HRESULT SetGroupColor(DWORD groupIndex, D3DCOLOR color) = 0;
|
||||||
virtual HRESULT SetGroupColorRGB(DWORD groupIndex, float r, float g, float b) = 0;
|
virtual HRESULT SetGroupColorRGB(DWORD groupIndex, float r, float g, float b) = 0;
|
||||||
virtual HRESULT SetGroupTexture(DWORD groupIndex, IDirect3DRMTexture* texture) = 0;
|
virtual HRESULT SetGroupTexture(DWORD groupIndex, IDirect3DRMTexture* texture) = 0;
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
struct Direct3DRMFrameImpl : public Direct3DRMObjectBase<IDirect3DRMFrame2> {
|
struct Direct3DRMFrameImpl : public Direct3DRMObjectBase<IDirect3DRMFrame2> {
|
||||||
Direct3DRMFrameImpl();
|
Direct3DRMFrameImpl();
|
||||||
~Direct3DRMFrameImpl() override;
|
~Direct3DRMFrameImpl() override;
|
||||||
|
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
|
||||||
HRESULT AddChild(IDirect3DRMFrame* child) override;
|
HRESULT AddChild(IDirect3DRMFrame* child) override;
|
||||||
HRESULT DeleteChild(IDirect3DRMFrame* child) override;
|
HRESULT DeleteChild(IDirect3DRMFrame* child) override;
|
||||||
HRESULT SetSceneBackgroundRGB(float r, float g, float b) override;
|
HRESULT SetSceneBackgroundRGB(float r, float g, float b) override;
|
||||||
|
|||||||
@ -64,6 +64,7 @@ struct MeshGroup {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Direct3DRMMeshImpl : public Direct3DRMObjectBase<IDirect3DRMMesh> {
|
struct Direct3DRMMeshImpl : public Direct3DRMObjectBase<IDirect3DRMMesh> {
|
||||||
|
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
|
||||||
HRESULT Clone(int flags, GUID iid, void** object) override;
|
HRESULT Clone(int flags, GUID iid, void** object) override;
|
||||||
HRESULT AddGroup(int vertexCount, int faceCount, int vertexPerFace, DWORD* faceBuffer, D3DRMGROUPINDEX* groupIndex)
|
HRESULT AddGroup(int vertexCount, int faceCount, int vertexPerFace, DWORD* faceBuffer, D3DRMGROUPINDEX* groupIndex)
|
||||||
override;
|
override;
|
||||||
@ -75,6 +76,7 @@ struct Direct3DRMMeshImpl : public Direct3DRMObjectBase<IDirect3DRMMesh> {
|
|||||||
DWORD* dataSize,
|
DWORD* dataSize,
|
||||||
DWORD* data
|
DWORD* data
|
||||||
) override;
|
) override;
|
||||||
|
DWORD GetGroupCount() override;
|
||||||
HRESULT SetGroupColor(DWORD groupIndex, D3DCOLOR color) override;
|
HRESULT SetGroupColor(DWORD groupIndex, D3DCOLOR color) override;
|
||||||
HRESULT SetGroupColorRGB(DWORD groupIndex, float r, float g, float b) override;
|
HRESULT SetGroupColorRGB(DWORD groupIndex, float r, float g, float b) override;
|
||||||
D3DCOLOR GetGroupColor(D3DRMGROUPINDEX index) override;
|
D3DCOLOR GetGroupColor(D3DRMGROUPINDEX index) override;
|
||||||
|
|||||||
@ -38,7 +38,7 @@ struct Direct3DRMViewportImpl : public Direct3DRMObjectBase<IDirect3DRMViewport>
|
|||||||
HRESULT InverseTransform(D3DVECTOR* world, D3DRMVECTOR4D* screen) override;
|
HRESULT InverseTransform(D3DVECTOR* world, D3DRMVECTOR4D* screen) override;
|
||||||
HRESULT Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) override;
|
HRESULT Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) override;
|
||||||
void CloseDevice();
|
void CloseDevice();
|
||||||
void CollectSceneData(IDirect3DRMFrame* group);
|
HRESULT CollectSceneData(IDirect3DRMFrame* group);
|
||||||
void PushVertices(const PositionColorVertex* vertices, size_t count);
|
void PushVertices(const PositionColorVertex* vertices, size_t count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -21,6 +21,20 @@ Direct3DRMFrameImpl::~Direct3DRMFrameImpl()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT Direct3DRMFrameImpl::QueryInterface(const GUID& riid, void** ppvObject)
|
||||||
|
{
|
||||||
|
if (SDL_memcmp(&riid, &IID_IDirect3DRMFrame, sizeof(GUID)) == 0) {
|
||||||
|
this->IUnknown::AddRef();
|
||||||
|
*ppvObject = static_cast<IDirect3DRMFrame*>(this);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
if (SDL_memcmp(&riid, &IID_IDirect3DRMMesh, sizeof(GUID)) == 0) {
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Direct3DRMFrameImpl does not implement guid");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT Direct3DRMFrameImpl::AddChild(IDirect3DRMFrame* child)
|
HRESULT Direct3DRMFrameImpl::AddChild(IDirect3DRMFrame* child)
|
||||||
{
|
{
|
||||||
return m_children->AddElement(child);
|
return m_children->AddElement(child);
|
||||||
|
|||||||
@ -3,6 +3,20 @@
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
HRESULT Direct3DRMMeshImpl::QueryInterface(const GUID& riid, void** ppvObject)
|
||||||
|
{
|
||||||
|
if (SDL_memcmp(&riid, &IID_IDirect3DRMMesh, sizeof(GUID)) == 0) {
|
||||||
|
this->IUnknown::AddRef();
|
||||||
|
*ppvObject = static_cast<IDirect3DRMMesh*>(this);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
if (SDL_memcmp(&riid, &IID_IDirect3DRMFrame, sizeof(GUID)) == 0) {
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Direct3DRMMeshImpl does not implement guid");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT Direct3DRMMeshImpl::Clone(int flags, GUID iid, void** object)
|
HRESULT Direct3DRMMeshImpl::Clone(int flags, GUID iid, void** object)
|
||||||
{
|
{
|
||||||
if (!object || SDL_memcmp(&iid, &IID_IDirect3DRMMesh, sizeof(GUID)) != 0) {
|
if (!object || SDL_memcmp(&iid, &IID_IDirect3DRMMesh, sizeof(GUID)) != 0) {
|
||||||
@ -86,6 +100,11 @@ HRESULT Direct3DRMMeshImpl::GetGroup(
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD Direct3DRMMeshImpl::GetGroupCount()
|
||||||
|
{
|
||||||
|
return m_groups.size();
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT Direct3DRMMeshImpl::SetGroupColor(DWORD groupIndex, D3DCOLOR color)
|
HRESULT Direct3DRMMeshImpl::SetGroupColor(DWORD groupIndex, D3DCOLOR color)
|
||||||
{
|
{
|
||||||
if (groupIndex >= m_groups.size()) {
|
if (groupIndex >= m_groups.size()) {
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "miniwin_p.h"
|
#include "miniwin_p.h"
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
Direct3DRMViewportImpl::Direct3DRMViewportImpl(
|
Direct3DRMViewportImpl::Direct3DRMViewportImpl(
|
||||||
DWORD width,
|
DWORD width,
|
||||||
@ -29,14 +30,73 @@ Direct3DRMViewportImpl::~Direct3DRMViewportImpl()
|
|||||||
FreeDeviceResources();
|
FreeDeviceResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Direct3DRMViewportImpl::CollectSceneData(IDirect3DRMFrame* group)
|
HRESULT Direct3DRMViewportImpl::CollectSceneData(IDirect3DRMFrame* group)
|
||||||
{
|
{
|
||||||
m_backgroundColor = static_cast<Direct3DRMFrameImpl*>(group)->m_backgroundColor;
|
MINIWIN_NOT_IMPLEMENTED(); // Lights, textures, materials
|
||||||
|
|
||||||
std::vector<PositionColorVertex> vertices =
|
std::vector<PositionColorVertex> verts;
|
||||||
{{-1, -1, 0, 0, 255, 0, 255}, {1, -1, 0, 0, 0, 255, 255}, {0, 1, 0, 255, 0, 0, 128}};
|
std::function<void(IDirect3DRMFrame*)> recurseFrame;
|
||||||
|
|
||||||
PushVertices(vertices.data(), vertices.size());
|
recurseFrame = [&](IDirect3DRMFrame* frame) {
|
||||||
|
IDirect3DRMVisualArray* va = nullptr;
|
||||||
|
if (SUCCEEDED(frame->GetVisuals(&va)) && va) {
|
||||||
|
DWORD n = va->GetSize();
|
||||||
|
for (DWORD i = 0; i < n; ++i) {
|
||||||
|
IDirect3DRMVisual* vis = nullptr;
|
||||||
|
va->GetElement(i, &vis);
|
||||||
|
if (!vis) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull geometry from meshes
|
||||||
|
IDirect3DRMMesh* mesh = nullptr;
|
||||||
|
if (SUCCEEDED(vis->QueryInterface(IID_IDirect3DRMMesh, (void**) &mesh)) && mesh) {
|
||||||
|
DWORD groupCount = mesh->GetGroupCount();
|
||||||
|
for (DWORD gi = 0; gi < groupCount; ++gi) {
|
||||||
|
DWORD vtxCount, faceCount, vpf, dataSize;
|
||||||
|
mesh->GetGroup(gi, &vtxCount, &faceCount, &vpf, &dataSize, nullptr);
|
||||||
|
std::vector<D3DRMVERTEX> d3dVerts(vtxCount);
|
||||||
|
std::vector<DWORD> faces(faceCount * vpf);
|
||||||
|
mesh->GetVertices(gi, 0, vtxCount, d3dVerts.data());
|
||||||
|
mesh->GetGroup(gi, &vtxCount, &faceCount, &vpf, nullptr, faces.data());
|
||||||
|
D3DCOLOR color = mesh->GetGroupColor(gi);
|
||||||
|
|
||||||
|
for (DWORD fi = 0; fi < faceCount; ++fi) {
|
||||||
|
for (int idx = 0; idx < vpf; ++idx) {
|
||||||
|
auto& dv = d3dVerts[faces[fi * vpf + idx]];
|
||||||
|
PositionColorVertex vtx;
|
||||||
|
vtx.x = dv.position.x;
|
||||||
|
vtx.y = dv.position.y;
|
||||||
|
vtx.z = dv.position.z;
|
||||||
|
vtx.a = (color >> 24) & 0xFF;
|
||||||
|
vtx.r = (color >> 16) & 0xFF;
|
||||||
|
vtx.g = (color >> 8) & 0xFF;
|
||||||
|
vtx.b = (color >> 0) & 0xFF;
|
||||||
|
verts.push_back(vtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mesh->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recurse over sub-frames
|
||||||
|
IDirect3DRMFrame* childFrame = nullptr;
|
||||||
|
if (SUCCEEDED(vis->QueryInterface(IID_IDirect3DRMFrame, (void**) &childFrame)) && childFrame) {
|
||||||
|
recurseFrame(childFrame);
|
||||||
|
childFrame->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
vis->Release();
|
||||||
|
}
|
||||||
|
va->Release();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
recurseFrame(group);
|
||||||
|
|
||||||
|
PushVertices(verts.data(), verts.size());
|
||||||
|
|
||||||
|
return D3DRM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Direct3DRMViewportImpl::PushVertices(const PositionColorVertex* vertices, size_t count)
|
void Direct3DRMViewportImpl::PushVertices(const PositionColorVertex* vertices, size_t count)
|
||||||
@ -53,8 +113,10 @@ void Direct3DRMViewportImpl::PushVertices(const PositionColorVertex* vertices, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_vertexCount = count;
|
m_vertexCount = count;
|
||||||
|
if (!count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MINIWIN_NOT_IMPLEMENTED();
|
|
||||||
SDL_GPUTransferBufferCreateInfo transferCreateInfo = {};
|
SDL_GPUTransferBufferCreateInfo transferCreateInfo = {};
|
||||||
transferCreateInfo.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
transferCreateInfo.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||||
transferCreateInfo.size = static_cast<Uint32>(sizeof(PositionColorVertex) * m_vertexCount);
|
transferCreateInfo.size = static_cast<Uint32>(sizeof(PositionColorVertex) * m_vertexCount);
|
||||||
@ -92,7 +154,10 @@ HRESULT Direct3DRMViewportImpl::Render(IDirect3DRMFrame* group)
|
|||||||
return DDERR_GENERIC;
|
return DDERR_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectSceneData(group);
|
HRESULT success = CollectSceneData(group);
|
||||||
|
if (success != DD_OK) {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_GPUCommandBuffer* cmdbuf = SDL_AcquireGPUCommandBuffer(m_device);
|
SDL_GPUCommandBuffer* cmdbuf = SDL_AcquireGPUCommandBuffer(m_device);
|
||||||
if (cmdbuf == NULL) {
|
if (cmdbuf == NULL) {
|
||||||
@ -107,11 +172,15 @@ HRESULT Direct3DRMViewportImpl::Render(IDirect3DRMFrame* group)
|
|||||||
colorTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR;
|
colorTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR;
|
||||||
SDL_GPURenderPass* renderPass = SDL_BeginGPURenderPass(cmdbuf, &colorTargetInfo, 1, NULL);
|
SDL_GPURenderPass* renderPass = SDL_BeginGPURenderPass(cmdbuf, &colorTargetInfo, 1, NULL);
|
||||||
SDL_BindGPUGraphicsPipeline(renderPass, m_pipeline);
|
SDL_BindGPUGraphicsPipeline(renderPass, m_pipeline);
|
||||||
SDL_GPUBufferBinding vertexBufferBinding = {};
|
|
||||||
vertexBufferBinding.buffer = m_vertexBuffer;
|
if (m_vertexCount) {
|
||||||
vertexBufferBinding.offset = 0;
|
SDL_GPUBufferBinding vertexBufferBinding = {};
|
||||||
SDL_BindGPUVertexBuffers(renderPass, 0, &vertexBufferBinding, 1);
|
vertexBufferBinding.buffer = m_vertexBuffer;
|
||||||
SDL_DrawGPUPrimitives(renderPass, m_vertexCount, 1, 0, 0);
|
vertexBufferBinding.offset = 0;
|
||||||
|
SDL_BindGPUVertexBuffers(renderPass, 0, &vertexBufferBinding, 1);
|
||||||
|
SDL_DrawGPUPrimitives(renderPass, m_vertexCount, 1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_EndGPURenderPass(renderPass);
|
SDL_EndGPURenderPass(renderPass);
|
||||||
|
|
||||||
// Download rendered image
|
// Download rendered image
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user