Add texture support for OpenGL (#239)

This commit is contained in:
Anders Jenbo 2025-06-05 13:26:06 +02:00 committed by GitHub
parent 12d01ae311
commit 874cc526be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 113 additions and 17 deletions

View File

@ -1,5 +1,6 @@
#include "d3drmrenderer_opengl15.h"
#include "ddraw_impl.h"
#include "ddsurface_impl.h"
#include "mathutils.h"
#include <GL/glew.h>
@ -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<TextureDestroyContextGL*>(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<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(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,14 +316,18 @@ void OpenGL15Renderer::SubmitDraw(
glLoadMatrixf(&mvMatrix[0][0]);
glEnable(GL_NORMALIZE);
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);
// 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);
}
// Set per-vertex specular material
float shininess = appearance.shininess;
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
if (shininess != 0.0f) {
@ -253,10 +335,16 @@ void OpenGL15Renderer::SubmitDraw(
glMaterialfv(GL_FRONT, GL_SPECULAR, whiteSpec);
}
else {
GLfloat noSpec[] = {0.0f, 0.0f, 0.0f, 1.0f};
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);
glVertex3f(v.position.x, v.position.y, v.position.z);
}
glEnd();

View File

@ -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);

View File

@ -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<GLTextureCacheEntry> m_textures;
D3DRMMATRIX4D m_viewMatrix;
D3DRMMATRIX4D m_projection;
SDL_Surface* m_renderedImage;