mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-11 10:31:16 +00:00
Add texture support for OpenGL (#239)
This commit is contained in:
parent
12d01ae311
commit
874cc526be
@ -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,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();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user