Push textures to the rendere (#209)

This commit is contained in:
Anders Jenbo 2025-05-31 23:48:20 +02:00 committed by GitHub
parent e03401c98b
commit 403ead7453
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 111 additions and 5 deletions

View File

@ -269,6 +269,11 @@ void Direct3DRMSDL3GPURenderer::SetProjection(D3DRMMATRIX4D perspective, D3DVALU
memcpy(&m_uniforms.perspective, perspective, sizeof(D3DRMMATRIX4D));
}
Uint32 Direct3DRMSDL3GPURenderer::GetTextureId(IDirect3DRMTexture* texture)
{
return NO_TEXTURE_ID;
}
DWORD Direct3DRMSDL3GPURenderer::GetWidth()
{
return m_width;

View File

@ -1,5 +1,6 @@
#include "d3drmrenderer.h"
#include "d3drmrenderer_software.h"
#include "ddsurface_impl.h"
#include "miniwin.h"
#include <SDL3/SDL.h>
@ -240,6 +241,32 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
SDL_Color c1 = ApplyLighting(v1);
SDL_Color c2 = ApplyLighting(v2);
SDL_Surface* texture = nullptr;
Uint32 texId = v0.texId;
if (texId != NO_TEXTURE_ID) {
texture = m_textures[texId];
if (texture && SDL_LockSurface(texture)) {
// Pointer to first pixel data
Uint8* pixelAddr = static_cast<Uint8*>(texture->pixels);
Uint32 pixel;
memcpy(&pixel, pixelAddr, m_bytesPerPixel);
Uint8 r, g, b, a;
SDL_GetRGBA(pixel, m_format, m_palette, &r, &g, &b, &a);
// TODO use the UV to read out and blend texels on the triangle
c0.r = r;
c0.g = g;
c0.b = b;
c0.a = a;
c1 = c0;
c2 = c0;
SDL_UnlockSurface(texture);
}
}
Uint8* pixels = (Uint8*) m_backbuffer->pixels;
int pitch = m_backbuffer->pitch;
@ -284,6 +311,55 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
}
}
struct TextureDestroyContext {
Direct3DRMSoftwareRenderer* renderer;
Uint32 textureId;
};
void Direct3DRMSoftwareRenderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture)
{
auto* ctx = new TextureDestroyContext{this, id};
texture->AddDestroyCallback(
[](IDirect3DRMObject* obj, void* arg) {
auto* ctx = static_cast<TextureDestroyContext*>(arg);
auto& sufRef = ctx->renderer->m_textures[ctx->textureId];
SDL_DestroySurface(sufRef);
sufRef = nullptr;
delete ctx;
},
ctx
);
}
Uint32 Direct3DRMSoftwareRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
{
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);
SDL_Surface* convertedRender = SDL_ConvertSurface(surface->m_surface, m_backbuffer->format);
// Check if already mapped
for (Uint32 i = 0; i < m_textures.size(); ++i) {
if (m_textures[i] == convertedRender) {
return i;
}
}
// Reuse freed slot
for (Uint32 i = 0; i < m_textures.size(); ++i) {
auto& texRef = m_textures[i];
if (texRef == nullptr) {
texRef = convertedRender;
AddTextureDestroyCallback(i, texture);
return i;
}
}
// Append new
Uint32 newId = static_cast<Uint32>(m_textures.size());
m_textures.push_back(convertedRender);
AddTextureDestroyCallback(newId, texture);
return newId;
}
DWORD Direct3DRMSoftwareRenderer::GetWidth()
{
return m_width;

View File

@ -153,8 +153,13 @@ HRESULT Direct3DRMMeshImpl::SetGroupTexture(DWORD groupIndex, IDirect3DRMTexture
return DDERR_INVALIDPARAMS;
}
auto& group = m_groups[groupIndex];
if (group.texture) {
group.texture->Release();
}
texture->AddRef();
m_groups[groupIndex].texture = texture;
group.texture = texture;
return DD_OK;
}

View File

@ -27,6 +27,6 @@ HRESULT Direct3DRMTextureImpl::Changed(BOOL pixels, BOOL palette)
if (!m_surface) {
return DDERR_GENERIC;
}
MINIWIN_NOT_IMPLEMENTED();
m_version++;
return DD_OK;
}

View File

@ -221,6 +221,13 @@ HRESULT Direct3DRMViewportImpl::CollectSceneData()
D3DCOLOR color = mesh->GetGroupColor(gi);
D3DRMRENDERQUALITY quality = mesh->GetGroupQuality(gi);
IDirect3DRMTexture* texture = nullptr;
mesh->GetGroupTexture(gi, &texture);
Uint32 texId = NO_TEXTURE_ID;
if (texture) {
texId = m_renderer->GetTextureId(texture);
texture->Release();
}
for (DWORD fi = 0; fi < faceCount; ++fi) {
D3DVECTOR norm;
@ -277,6 +284,7 @@ HRESULT Direct3DRMViewportImpl::CollectSceneData()
vtx.g = (color >> 8) & 0xFF;
vtx.b = (color >> 0) & 0xFF;
vtx.a = (color >> 24) & 0xFF;
vtx.texId = texId;
verts.push_back(vtx);
}
}

View File

@ -216,7 +216,7 @@ HRESULT DirectDrawSurfaceImpl::Lock(
return DDERR_GENERIC;
}
if (SDL_LockSurface(m_surface) < 0) {
if (!SDL_LockSurface(m_surface)) {
return DDERR_GENERIC;
}

View File

@ -4,10 +4,13 @@
#include <SDL3/SDL.h>
#define NO_TEXTURE_ID 0xffffffff
typedef struct PositionColorVertex {
float x, y, z;
float nx, ny, nz;
Uint8 r, g, b, a;
Uint32 texId = NO_TEXTURE_ID;
} PositionColorVertex;
struct FColor {
@ -28,6 +31,7 @@ class Direct3DRMRenderer : public IDirect3DDevice2 {
virtual void PushVertices(const PositionColorVertex* vertices, size_t count) = 0;
virtual void PushLights(const SceneLight* vertices, size_t count) = 0;
virtual void SetProjection(D3DRMMATRIX4D perspective, D3DVALUE front, D3DVALUE back) = 0;
virtual Uint32 GetTextureId(IDirect3DRMTexture* texture) = 0;
virtual DWORD GetWidth() = 0;
virtual DWORD GetHeight() = 0;
virtual void GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC* helDesc) = 0;

View File

@ -22,6 +22,7 @@ class Direct3DRMSDL3GPURenderer : public Direct3DRMRenderer {
void SetBackbuffer(SDL_Surface* backbuffer) override;
void PushVertices(const PositionColorVertex* vertices, size_t count) override;
void PushLights(const SceneLight* vertices, size_t count) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture) override;
void SetProjection(D3DRMMATRIX4D perspective, D3DVALUE front, D3DVALUE back) override;
DWORD GetWidth() override;
DWORD GetHeight() override;

View File

@ -1,6 +1,7 @@
#pragma once
#include "d3drmrenderer.h"
#include "d3drmtexture_impl.h"
#include <SDL3/SDL.h>
#include <cstddef>
@ -14,6 +15,7 @@ class Direct3DRMSoftwareRenderer : public Direct3DRMRenderer {
void SetBackbuffer(SDL_Surface* backbuffer) override;
void PushVertices(const PositionColorVertex* vertices, size_t count) override;
void PushLights(const SceneLight* vertices, size_t count) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture) override;
void SetProjection(D3DRMMATRIX4D perspective, D3DVALUE front, D3DVALUE back) override;
DWORD GetWidth() override;
DWORD GetHeight() override;
@ -32,6 +34,7 @@ class Direct3DRMSoftwareRenderer : public Direct3DRMRenderer {
void ProjectVertex(const PositionColorVertex&, float&, float&, float&) const;
void BlendPixel(Uint8* pixelAddr, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL_Color ApplyLighting(const PositionColorVertex& vertex);
void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture);
DWORD m_width;
DWORD m_height;
@ -40,6 +43,7 @@ class Direct3DRMSoftwareRenderer : public Direct3DRMRenderer {
const SDL_PixelFormatDetails* m_format;
int m_bytesPerPixel;
std::vector<SceneLight> m_lights;
std::vector<SDL_Surface*> m_textures;
D3DVALUE m_front;
D3DVALUE m_back;
std::vector<PositionColorVertex> m_vertexBuffer;

View File

@ -8,6 +8,8 @@ struct Direct3DRMTextureImpl : public Direct3DRMObjectBaseImpl<IDirect3DRMTextur
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
HRESULT Changed(BOOL pixels, BOOL palette) override;
private:
IDirectDrawSurface* m_surface = nullptr;
private:
Uint8 m_version = 0;
};

View File

@ -37,8 +37,9 @@ struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 {
void SetAutoFlip(bool enabled);
HRESULT Unlock(LPVOID lpSurfaceData) override;
SDL_Surface* m_surface = nullptr;
private:
bool m_autoFlip = false;
SDL_Surface* m_surface = nullptr;
IDirectDrawPalette* m_palette = nullptr;
};