diff --git a/miniwin/src/d3drm/backends/opengl15/renderer.cpp b/miniwin/src/d3drm/backends/opengl15/renderer.cpp index 0470eab0..4056fda5 100644 --- a/miniwin/src/d3drm/backends/opengl15/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengl15/renderer.cpp @@ -1,5 +1,6 @@ #include "d3drmrenderer_opengl15.h" #include "ddraw_impl.h" +#include "ddsurface_impl.h" #include "mathutils.h" #include @@ -104,9 +105,86 @@ void OpenGL15Renderer::SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE f m_projection[1][1] *= -1.0f; // OpenGL is upside down } -Uint32 OpenGL15Renderer::GetTextureId(IDirect3DRMTexture* texture) +struct TextureDestroyContextGL { + OpenGL15Renderer* renderer; + Uint32 textureId; +}; + +void OpenGL15Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture) { - return NO_TEXTURE_ID; // Stub + auto* ctx = new TextureDestroyContextGL{this, id}; + texture->AddDestroyCallback( + [](IDirect3DRMObject* obj, void* arg) { + auto* ctx = static_cast(arg); + auto& cache = ctx->renderer->m_textures[ctx->textureId]; + if (cache.glTextureId != 0) { + glDeleteTextures(1, &cache.glTextureId); + cache.glTextureId = 0; + cache.texture = nullptr; + } + delete ctx; + }, + ctx + ); +} + +Uint32 OpenGL15Renderer::GetTextureId(IDirect3DRMTexture* iTexture) +{ + auto texture = static_cast(iTexture); + auto surface = static_cast(texture->m_surface); + + for (Uint32 i = 0; i < m_textures.size(); ++i) { + auto& tex = m_textures[i]; + if (tex.texture == texture) { + if (tex.version != texture->m_version) { + glDeleteTextures(1, &tex.glTextureId); + glGenTextures(1, &tex.glTextureId); + glBindTexture(GL_TEXTURE_2D, tex.glTextureId); + + SDL_Surface* surf = + SDL_ConvertSurface(surface->m_surface, SDL_PIXELFORMAT_ABGR8888); // Why are the colors backwarsd? + if (!surf) { + return NO_TEXTURE_ID; + } + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels); + SDL_DestroySurface(surf); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + tex.version = texture->m_version; + } + return i; + } + } + + GLuint texId; + glGenTextures(1, &texId); + glBindTexture(GL_TEXTURE_2D, texId); + + SDL_Surface* surf = + SDL_ConvertSurface(surface->m_surface, SDL_PIXELFORMAT_ABGR8888); // Why are the colors backwarsd? + if (!surf) { + return NO_TEXTURE_ID; + } + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels); + SDL_DestroySurface(surf); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + for (Uint32 i = 0; i < m_textures.size(); ++i) { + auto& tex = m_textures[i]; + if (tex.texture == nullptr) { + tex.texture = texture; + tex.version = texture->m_version; + tex.glTextureId = texId; + AddTextureDestroyCallback(i, texture); + return i; + } + } + + m_textures.push_back({texture, texture->m_version, texId}); + AddTextureDestroyCallback((Uint32) (m_textures.size() - 1), texture); + return (Uint32) (m_textures.size() - 1); } DWORD OpenGL15Renderer::GetWidth() @@ -238,25 +316,35 @@ void OpenGL15Renderer::SubmitDraw( glLoadMatrixf(&mvMatrix[0][0]); glEnable(GL_NORMALIZE); + // Bind texture if present + if (appearance.textureId != NO_TEXTURE_ID) { + auto& tex = m_textures[appearance.textureId]; + if (tex.glTextureId) { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex.glTextureId); + } + } + else { + glDisable(GL_TEXTURE_2D); + } + + float shininess = appearance.shininess; + glMaterialf(GL_FRONT, GL_SHININESS, shininess); + if (shininess != 0.0f) { + GLfloat whiteSpec[] = {shininess, shininess, shininess, shininess}; + glMaterialfv(GL_FRONT, GL_SPECULAR, whiteSpec); + } + else { + GLfloat noSpec[] = {0.0f, 0.0f, 0.0f, 0.0f}; + glMaterialfv(GL_FRONT, GL_SPECULAR, noSpec); + } + glBegin(GL_TRIANGLES); for (size_t i = 0; i < count; i++) { const GeometryVertex& v = vertices[i]; glColor4ub(appearance.color.r, appearance.color.g, appearance.color.b, appearance.color.a); glNormal3f(v.normals.x, v.normals.y, v.normals.z); glTexCoord2f(v.texCoord.u, v.texCoord.v); - - // Set per-vertex specular material - float shininess = appearance.shininess; - glMaterialf(GL_FRONT, GL_SHININESS, shininess); - if (shininess != 0.0f) { - GLfloat whiteSpec[] = {shininess, shininess, shininess, shininess}; - glMaterialfv(GL_FRONT, GL_SPECULAR, whiteSpec); - } - else { - GLfloat noSpec[] = {0.0f, 0.0f, 0.0f, 1.0f}; - glMaterialfv(GL_FRONT, GL_SPECULAR, noSpec); - } - glVertex3f(v.position.x, v.position.y, v.position.z); } glEnd(); diff --git a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp index 613fba2a..329f98a4 100644 --- a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp +++ b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp @@ -93,7 +93,7 @@ static SDL_GPUGraphicsPipeline* InitializeGraphicsPipeline(SDL_GPUDevice* device pipelineCreateInfo.depth_stencil_state.enable_depth_test = true; pipelineCreateInfo.depth_stencil_state.enable_depth_write = depthWrite; pipelineCreateInfo.depth_stencil_state.enable_stencil_test = false; - pipelineCreateInfo.depth_stencil_state.compare_op = SDL_GPU_COMPAREOP_GREATER; + pipelineCreateInfo.depth_stencil_state.compare_op = SDL_GPU_COMPAREOP_LESS; pipelineCreateInfo.depth_stencil_state.write_mask = 0xff; SDL_GPUGraphicsPipeline* pipeline = SDL_CreateGPUGraphicsPipeline(device, &pipelineCreateInfo); @@ -277,7 +277,7 @@ HRESULT Direct3DRMSDL3GPURenderer::BeginFrame(const D3DRMMATRIX4D& viewMatrix) SDL_GPUDepthStencilTargetInfo depthStencilTargetInfo = {}; depthStencilTargetInfo.texture = m_depthTexture; - depthStencilTargetInfo.clear_depth = 0.f; + depthStencilTargetInfo.clear_depth = 1.f; depthStencilTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR; SDL_GPUCommandBuffer* cmdbuf = SDL_AcquireGPUCommandBuffer(m_device); diff --git a/miniwin/src/internal/d3drmrenderer_opengl15.h b/miniwin/src/internal/d3drmrenderer_opengl15.h index 7762ff77..a6c69613 100644 --- a/miniwin/src/internal/d3drmrenderer_opengl15.h +++ b/miniwin/src/internal/d3drmrenderer_opengl15.h @@ -10,6 +10,12 @@ DEFINE_GUID(OPENGL15_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03); +struct GLTextureCacheEntry { + IDirect3DRMTexture* texture; + Uint32 version; + GLuint glTextureId; +}; + class OpenGL15Renderer : public Direct3DRMRenderer { public: static Direct3DRMRenderer* Create(DWORD width, DWORD height); @@ -33,6 +39,8 @@ class OpenGL15Renderer : public Direct3DRMRenderer { HRESULT FinalizeFrame() override; private: + void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture); + std::vector m_textures; D3DRMMATRIX4D m_viewMatrix; D3DRMMATRIX4D m_projection; SDL_Surface* m_renderedImage;