mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-02 12:00:01 -06:00
Make the initial 3D renderer configurable via NDSArgs
(#1913)
* Allow 3D renderers to be created without passing `GPU` to the constructor * Make the initial 3D renderer configurable via `NDSArgs` * Fix a compiler error
This commit is contained in:
@ -97,9 +97,8 @@ void SetupDefaultTexParams(GLuint tex)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
GLRenderer::GLRenderer(GLCompositor&& compositor, melonDS::GPU& gpu) noexcept :
|
||||
GLRenderer::GLRenderer(GLCompositor&& compositor) noexcept :
|
||||
Renderer3D(true),
|
||||
GPU(gpu),
|
||||
CurGLCompositor(std::move(compositor))
|
||||
{
|
||||
// GLRenderer::New() will be used to actually initialize the renderer;
|
||||
@ -107,7 +106,7 @@ GLRenderer::GLRenderer(GLCompositor&& compositor, melonDS::GPU& gpu) noexcept :
|
||||
// so we can just let the destructor clean up a half-initialized renderer.
|
||||
}
|
||||
|
||||
std::unique_ptr<GLRenderer> GLRenderer::New(melonDS::GPU& gpu) noexcept
|
||||
std::unique_ptr<GLRenderer> GLRenderer::New() noexcept
|
||||
{
|
||||
assert(glEnable != nullptr);
|
||||
|
||||
@ -117,7 +116,7 @@ std::unique_ptr<GLRenderer> GLRenderer::New(melonDS::GPU& gpu) noexcept
|
||||
|
||||
// Will be returned if the initialization succeeds,
|
||||
// or cleaned up via RAII if it fails.
|
||||
std::unique_ptr<GLRenderer> result = std::unique_ptr<GLRenderer>(new GLRenderer(std::move(*compositor), gpu));
|
||||
std::unique_ptr<GLRenderer> result = std::unique_ptr<GLRenderer>(new GLRenderer(std::move(*compositor)));
|
||||
compositor = std::nullopt;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@ -333,7 +332,7 @@ GLRenderer::~GLRenderer()
|
||||
}
|
||||
}
|
||||
|
||||
void GLRenderer::Reset()
|
||||
void GLRenderer::Reset(GPU& gpu)
|
||||
{
|
||||
// This is where the compositor's Reset() method would be called,
|
||||
// except there's no such method right now.
|
||||
@ -786,14 +785,14 @@ int GLRenderer::RenderPolygonEdgeBatch(int i) const
|
||||
return numpolys;
|
||||
}
|
||||
|
||||
void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
void GLRenderer::RenderSceneChunk(const GPU3D& gpu3d, int y, int h)
|
||||
{
|
||||
u32 flags = 0;
|
||||
if (GPU.GPU3D.RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer;
|
||||
if (gpu3d.RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer;
|
||||
|
||||
if (h != 192) glScissor(0, y<<ScaleFactor, 256<<ScaleFactor, h<<ScaleFactor);
|
||||
|
||||
GLboolean fogenable = (GPU.GPU3D.RenderDispCnt & (1<<7)) ? GL_TRUE : GL_FALSE;
|
||||
GLboolean fogenable = (gpu3d.RenderDispCnt & (1<<7)) ? GL_TRUE : GL_FALSE;
|
||||
|
||||
// TODO: proper 'equal' depth test!
|
||||
// (has margin of +-0x200 in Z-buffer mode, +-0xFF in W-buffer mode)
|
||||
@ -865,7 +864,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<3))
|
||||
if (gpu3d.RenderDispCnt & (1<<3))
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
|
||||
else
|
||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE);
|
||||
@ -877,7 +876,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
// pass 2: if needed, render translucent pixels that are against background pixels
|
||||
// when background alpha is zero, those need to be rendered with blending disabled
|
||||
|
||||
if ((GPU.GPU3D.RenderClearAttr1 & 0x001F0000) == 0)
|
||||
if ((gpu3d.RenderClearAttr1 & 0x001F0000) == 0)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
@ -941,7 +940,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
if (rp->PolyData->IsShadow)
|
||||
{
|
||||
// shadow against clear-plane will only pass if its polyID matches that of the clear plane
|
||||
u32 clrpolyid = (GPU.GPU3D.RenderClearAttr1 >> 24) & 0x3F;
|
||||
u32 clrpolyid = (gpu3d.RenderClearAttr1 >> 24) & 0x3F;
|
||||
if (polyid != clrpolyid) { i++; continue; }
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
@ -1089,7 +1088,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
}
|
||||
}
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & 0x00A0) // fog/edge enabled
|
||||
if (gpu3d.RenderDispCnt & 0x00A0) // fog/edge enabled
|
||||
{
|
||||
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
@ -1111,7 +1110,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID);
|
||||
glBindVertexArray(ClearVertexArrayID);
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<5))
|
||||
if (gpu3d.RenderDispCnt & (1<<5))
|
||||
{
|
||||
// edge marking
|
||||
// TODO: depth/polyid values at screen edges
|
||||
@ -1123,19 +1122,19 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
glDrawArrays(GL_TRIANGLES, 0, 2*3);
|
||||
}
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<7))
|
||||
if (gpu3d.RenderDispCnt & (1<<7))
|
||||
{
|
||||
// fog
|
||||
|
||||
glUseProgram(FinalPassFogShader[2]);
|
||||
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<6))
|
||||
if (gpu3d.RenderDispCnt & (1<<6))
|
||||
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
||||
else
|
||||
glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
{
|
||||
u32 c = GPU.GPU3D.RenderFogColor;
|
||||
u32 c = gpu3d.RenderFogColor;
|
||||
u32 r = c & 0x1F;
|
||||
u32 g = (c >> 5) & 0x1F;
|
||||
u32 b = (c >> 10) & 0x1F;
|
||||
@ -1150,7 +1149,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
}
|
||||
|
||||
|
||||
void GLRenderer::RenderFrame()
|
||||
void GLRenderer::RenderFrame(GPU& gpu)
|
||||
{
|
||||
CurShaderID = -1;
|
||||
|
||||
@ -1159,11 +1158,11 @@ void GLRenderer::RenderFrame()
|
||||
|
||||
ShaderConfig.uScreenSize[0] = ScreenW;
|
||||
ShaderConfig.uScreenSize[1] = ScreenH;
|
||||
ShaderConfig.uDispCnt = GPU.GPU3D.RenderDispCnt;
|
||||
ShaderConfig.uDispCnt = gpu.GPU3D.RenderDispCnt;
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
u16 c = GPU.GPU3D.RenderToonTable[i];
|
||||
u16 c = gpu.GPU3D.RenderToonTable[i];
|
||||
u32 r = c & 0x1F;
|
||||
u32 g = (c >> 5) & 0x1F;
|
||||
u32 b = (c >> 10) & 0x1F;
|
||||
@ -1175,7 +1174,7 @@ void GLRenderer::RenderFrame()
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
u16 c = GPU.GPU3D.RenderEdgeTable[i];
|
||||
u16 c = gpu.GPU3D.RenderEdgeTable[i];
|
||||
u32 r = c & 0x1F;
|
||||
u32 g = (c >> 5) & 0x1F;
|
||||
u32 b = (c >> 10) & 0x1F;
|
||||
@ -1186,7 +1185,7 @@ void GLRenderer::RenderFrame()
|
||||
}
|
||||
|
||||
{
|
||||
u32 c = GPU.GPU3D.RenderFogColor;
|
||||
u32 c = gpu.GPU3D.RenderFogColor;
|
||||
u32 r = c & 0x1F;
|
||||
u32 g = (c >> 5) & 0x1F;
|
||||
u32 b = (c >> 10) & 0x1F;
|
||||
@ -1200,12 +1199,12 @@ void GLRenderer::RenderFrame()
|
||||
|
||||
for (int i = 0; i < 34; i++)
|
||||
{
|
||||
u8 d = GPU.GPU3D.RenderFogDensityTable[i];
|
||||
u8 d = gpu.GPU3D.RenderFogDensityTable[i];
|
||||
ShaderConfig.uFogDensity[i][0] = (float)d / 127.0;
|
||||
}
|
||||
|
||||
ShaderConfig.uFogOffset = GPU.GPU3D.RenderFogOffset;
|
||||
ShaderConfig.uFogShift = GPU.GPU3D.RenderFogShift;
|
||||
ShaderConfig.uFogOffset = gpu.GPU3D.RenderFogOffset;
|
||||
ShaderConfig.uFogShift = gpu.GPU3D.RenderFogShift;
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO);
|
||||
void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
|
||||
@ -1218,13 +1217,13 @@ void GLRenderer::RenderFrame()
|
||||
glBindTexture(GL_TEXTURE_2D, TexMemID);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
u32 mask = GPU.VRAMMap_Texture[i];
|
||||
u32 mask = gpu.VRAMMap_Texture[i];
|
||||
u8* vram;
|
||||
if (!mask) continue;
|
||||
else if (mask & (1<<0)) vram = GPU.VRAM_A;
|
||||
else if (mask & (1<<1)) vram = GPU.VRAM_B;
|
||||
else if (mask & (1<<2)) vram = GPU.VRAM_C;
|
||||
else if (mask & (1<<3)) vram = GPU.VRAM_D;
|
||||
else if (mask & (1<<0)) vram = gpu.VRAM_A;
|
||||
else if (mask & (1<<1)) vram = gpu.VRAM_B;
|
||||
else if (mask & (1<<2)) vram = gpu.VRAM_C;
|
||||
else if (mask & (1<<3)) vram = gpu.VRAM_D;
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*128, 1024, 128, GL_RED_INTEGER, GL_UNSIGNED_BYTE, vram);
|
||||
}
|
||||
@ -1234,12 +1233,12 @@ void GLRenderer::RenderFrame()
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
// 6 x 16K chunks
|
||||
u32 mask = GPU.VRAMMap_TexPal[i];
|
||||
u32 mask = gpu.VRAMMap_TexPal[i];
|
||||
u8* vram;
|
||||
if (!mask) continue;
|
||||
else if (mask & (1<<4)) vram = &GPU.VRAM_E[(i&3)*0x4000];
|
||||
else if (mask & (1<<5)) vram = GPU.VRAM_F;
|
||||
else if (mask & (1<<6)) vram = GPU.VRAM_G;
|
||||
else if (mask & (1<<4)) vram = &gpu.VRAM_E[(i&3)*0x4000];
|
||||
else if (mask & (1<<5)) vram = gpu.VRAM_F;
|
||||
else if (mask & (1<<6)) vram = gpu.VRAM_G;
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*8, 1024, 8, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, vram);
|
||||
}
|
||||
@ -1264,13 +1263,13 @@ void GLRenderer::RenderFrame()
|
||||
glUseProgram(ClearShaderPlain[2]);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
|
||||
u32 r = GPU.GPU3D.RenderClearAttr1 & 0x1F;
|
||||
u32 g = (GPU.GPU3D.RenderClearAttr1 >> 5) & 0x1F;
|
||||
u32 b = (GPU.GPU3D.RenderClearAttr1 >> 10) & 0x1F;
|
||||
u32 fog = (GPU.GPU3D.RenderClearAttr1 >> 15) & 0x1;
|
||||
u32 a = (GPU.GPU3D.RenderClearAttr1 >> 16) & 0x1F;
|
||||
u32 polyid = (GPU.GPU3D.RenderClearAttr1 >> 24) & 0x3F;
|
||||
u32 z = ((GPU.GPU3D.RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF;
|
||||
u32 r = gpu.GPU3D.RenderClearAttr1 & 0x1F;
|
||||
u32 g = (gpu.GPU3D.RenderClearAttr1 >> 5) & 0x1F;
|
||||
u32 b = (gpu.GPU3D.RenderClearAttr1 >> 10) & 0x1F;
|
||||
u32 fog = (gpu.GPU3D.RenderClearAttr1 >> 15) & 0x1;
|
||||
u32 a = (gpu.GPU3D.RenderClearAttr1 >> 16) & 0x1F;
|
||||
u32 polyid = (gpu.GPU3D.RenderClearAttr1 >> 24) & 0x3F;
|
||||
u32 z = ((gpu.GPU3D.RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF;
|
||||
|
||||
glStencilFunc(GL_ALWAYS, 0xFF, 0xFF);
|
||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
@ -1289,20 +1288,20 @@ void GLRenderer::RenderFrame()
|
||||
glDrawArrays(GL_TRIANGLES, 0, 2*3);
|
||||
}
|
||||
|
||||
if (GPU.GPU3D.RenderNumPolygons)
|
||||
if (gpu.GPU3D.RenderNumPolygons)
|
||||
{
|
||||
// render shit here
|
||||
u32 flags = 0;
|
||||
if (GPU.GPU3D.RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer;
|
||||
if (gpu.GPU3D.RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer;
|
||||
|
||||
int npolys = 0;
|
||||
int firsttrans = -1;
|
||||
for (u32 i = 0; i < GPU.GPU3D.RenderNumPolygons; i++)
|
||||
for (u32 i = 0; i < gpu.GPU3D.RenderNumPolygons; i++)
|
||||
{
|
||||
if (GPU.GPU3D.RenderPolygonRAM[i]->Degenerate) continue;
|
||||
if (gpu.GPU3D.RenderPolygonRAM[i]->Degenerate) continue;
|
||||
|
||||
SetupPolygon(&PolygonList[npolys], GPU.GPU3D.RenderPolygonRAM[i]);
|
||||
if (firsttrans < 0 && GPU.GPU3D.RenderPolygonRAM[i]->Translucent)
|
||||
SetupPolygon(&PolygonList[npolys], gpu.GPU3D.RenderPolygonRAM[i]);
|
||||
if (firsttrans < 0 && gpu.GPU3D.RenderPolygonRAM[i]->Translucent)
|
||||
firsttrans = npolys;
|
||||
|
||||
npolys++;
|
||||
@ -1319,15 +1318,15 @@ void GLRenderer::RenderFrame()
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, NumIndices * 2, IndexBuffer);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, EdgeIndicesOffset * 2, NumEdgeIndices * 2, IndexBuffer + EdgeIndicesOffset);
|
||||
|
||||
RenderSceneChunk(0, 192);
|
||||
RenderSceneChunk(gpu.GPU3D, 0, 192);
|
||||
}
|
||||
|
||||
FrontBuffer = FrontBuffer ? 0 : 1;
|
||||
}
|
||||
|
||||
void GLRenderer::Stop()
|
||||
void GLRenderer::Stop(const GPU& gpu)
|
||||
{
|
||||
CurGLCompositor.Stop(GPU);
|
||||
CurGLCompositor.Stop(gpu);
|
||||
}
|
||||
|
||||
void GLRenderer::PrepareCaptureFrame()
|
||||
@ -1345,9 +1344,9 @@ void GLRenderer::PrepareCaptureFrame()
|
||||
glReadPixels(0, 0, 256, 192, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
|
||||
void GLRenderer::Blit()
|
||||
void GLRenderer::Blit(const GPU& gpu)
|
||||
{
|
||||
CurGLCompositor.RenderFrame(GPU, *this);
|
||||
CurGLCompositor.RenderFrame(gpu, *this);
|
||||
}
|
||||
|
||||
u32* GLRenderer::GetLine(int line)
|
||||
|
Reference in New Issue
Block a user