mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 06:10:03 -06:00
Refactor the GPU to be object-oriented (#1873)
* Refactor GPU3D to be an object - Who has two thumbs and is the sworn enemy of global state? This guy! * Refactor GPU itself to be an object - Wow, it's used in a lot of places - Also introduce a new `Melon` namespace for a few classes - I expect other classes will be moved into `Melon` over time * Change signature of Renderer3D::SetRenderSettings - Make it noexcept, and its argument const * Remove some stray whitespace
This commit is contained in:

committed by
GitHub

parent
88072a02c5
commit
4558be0d8e
@ -97,20 +97,20 @@ void SetupDefaultTexParams(GLuint tex)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
GLRenderer::GLRenderer() noexcept : Renderer3D(true)
|
||||
GLRenderer::GLRenderer(Melon::GPU& gpu) noexcept : Renderer3D(true), GPU(gpu)
|
||||
{
|
||||
// GLRenderer::New() will be used to actually initialize the renderer;
|
||||
// The various glDelete* functions silently ignore invalid IDs,
|
||||
// so we can just let the destructor clean up a half-initialized renderer.
|
||||
}
|
||||
|
||||
std::unique_ptr<GLRenderer> GLRenderer::New() noexcept
|
||||
std::unique_ptr<GLRenderer> GLRenderer::New(Melon::GPU& gpu) noexcept
|
||||
{
|
||||
assert(glEnable != nullptr);
|
||||
|
||||
// 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::unique_ptr<GLRenderer> result = std::unique_ptr<GLRenderer>(new GLRenderer(gpu));
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
@ -329,7 +329,7 @@ void GLRenderer::Reset()
|
||||
{
|
||||
}
|
||||
|
||||
void GLRenderer::SetRenderSettings(GPU::RenderSettings& settings)
|
||||
void GLRenderer::SetRenderSettings(const Melon::RenderSettings& settings) noexcept
|
||||
{
|
||||
int scale = settings.GL_ScaleFactor;
|
||||
|
||||
@ -766,11 +766,11 @@ int GLRenderer::RenderPolygonEdgeBatch(int i)
|
||||
void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
{
|
||||
u32 flags = 0;
|
||||
if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer;
|
||||
if (GPU.GPU3D.RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer;
|
||||
|
||||
if (h != 192) glScissor(0, y<<ScaleFactor, 256<<ScaleFactor, h<<ScaleFactor);
|
||||
|
||||
GLboolean fogenable = (RenderDispCnt & (1<<7)) ? GL_TRUE : GL_FALSE;
|
||||
GLboolean fogenable = (GPU.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)
|
||||
@ -842,7 +842,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
||||
|
||||
if (RenderDispCnt & (1<<3))
|
||||
if (GPU.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);
|
||||
@ -854,7 +854,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 ((RenderClearAttr1 & 0x001F0000) == 0)
|
||||
if ((GPU.GPU3D.RenderClearAttr1 & 0x001F0000) == 0)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
@ -918,7 +918,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 = (RenderClearAttr1 >> 24) & 0x3F;
|
||||
u32 clrpolyid = (GPU.GPU3D.RenderClearAttr1 >> 24) & 0x3F;
|
||||
if (polyid != clrpolyid) { i++; continue; }
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
@ -1066,7 +1066,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
}
|
||||
}
|
||||
|
||||
if (RenderDispCnt & 0x00A0) // fog/edge enabled
|
||||
if (GPU.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);
|
||||
@ -1088,7 +1088,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID);
|
||||
glBindVertexArray(ClearVertexArrayID);
|
||||
|
||||
if (RenderDispCnt & (1<<5))
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<5))
|
||||
{
|
||||
// edge marking
|
||||
// TODO: depth/polyid values at screen edges
|
||||
@ -1100,19 +1100,19 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
||||
glDrawArrays(GL_TRIANGLES, 0, 2*3);
|
||||
}
|
||||
|
||||
if (RenderDispCnt & (1<<7))
|
||||
if (GPU.GPU3D.RenderDispCnt & (1<<7))
|
||||
{
|
||||
// fog
|
||||
|
||||
glUseProgram(FinalPassFogShader[2]);
|
||||
|
||||
if (RenderDispCnt & (1<<6))
|
||||
if (GPU.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 = RenderFogColor;
|
||||
u32 c = GPU.GPU3D.RenderFogColor;
|
||||
u32 r = c & 0x1F;
|
||||
u32 g = (c >> 5) & 0x1F;
|
||||
u32 b = (c >> 10) & 0x1F;
|
||||
@ -1136,11 +1136,11 @@ void GLRenderer::RenderFrame()
|
||||
|
||||
ShaderConfig.uScreenSize[0] = ScreenW;
|
||||
ShaderConfig.uScreenSize[1] = ScreenH;
|
||||
ShaderConfig.uDispCnt = RenderDispCnt;
|
||||
ShaderConfig.uDispCnt = GPU.GPU3D.RenderDispCnt;
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
u16 c = RenderToonTable[i];
|
||||
u16 c = GPU.GPU3D.RenderToonTable[i];
|
||||
u32 r = c & 0x1F;
|
||||
u32 g = (c >> 5) & 0x1F;
|
||||
u32 b = (c >> 10) & 0x1F;
|
||||
@ -1152,7 +1152,7 @@ void GLRenderer::RenderFrame()
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
u16 c = RenderEdgeTable[i];
|
||||
u16 c = GPU.GPU3D.RenderEdgeTable[i];
|
||||
u32 r = c & 0x1F;
|
||||
u32 g = (c >> 5) & 0x1F;
|
||||
u32 b = (c >> 10) & 0x1F;
|
||||
@ -1163,7 +1163,7 @@ void GLRenderer::RenderFrame()
|
||||
}
|
||||
|
||||
{
|
||||
u32 c = RenderFogColor;
|
||||
u32 c = GPU.GPU3D.RenderFogColor;
|
||||
u32 r = c & 0x1F;
|
||||
u32 g = (c >> 5) & 0x1F;
|
||||
u32 b = (c >> 10) & 0x1F;
|
||||
@ -1177,12 +1177,12 @@ void GLRenderer::RenderFrame()
|
||||
|
||||
for (int i = 0; i < 34; i++)
|
||||
{
|
||||
u8 d = RenderFogDensityTable[i];
|
||||
u8 d = GPU.GPU3D.RenderFogDensityTable[i];
|
||||
ShaderConfig.uFogDensity[i][0] = (float)d / 127.0;
|
||||
}
|
||||
|
||||
ShaderConfig.uFogOffset = RenderFogOffset;
|
||||
ShaderConfig.uFogShift = 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);
|
||||
@ -1195,13 +1195,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);
|
||||
}
|
||||
@ -1211,12 +1211,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);
|
||||
}
|
||||
@ -1241,13 +1241,13 @@ void GLRenderer::RenderFrame()
|
||||
glUseProgram(ClearShaderPlain[2]);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
|
||||
u32 r = RenderClearAttr1 & 0x1F;
|
||||
u32 g = (RenderClearAttr1 >> 5) & 0x1F;
|
||||
u32 b = (RenderClearAttr1 >> 10) & 0x1F;
|
||||
u32 fog = (RenderClearAttr1 >> 15) & 0x1;
|
||||
u32 a = (RenderClearAttr1 >> 16) & 0x1F;
|
||||
u32 polyid = (RenderClearAttr1 >> 24) & 0x3F;
|
||||
u32 z = ((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);
|
||||
@ -1266,20 +1266,20 @@ void GLRenderer::RenderFrame()
|
||||
glDrawArrays(GL_TRIANGLES, 0, 2*3);
|
||||
}
|
||||
|
||||
if (RenderNumPolygons)
|
||||
if (GPU.GPU3D.RenderNumPolygons)
|
||||
{
|
||||
// render shit here
|
||||
u32 flags = 0;
|
||||
if (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 < RenderNumPolygons; i++)
|
||||
for (u32 i = 0; i < GPU.GPU3D.RenderNumPolygons; i++)
|
||||
{
|
||||
if (RenderPolygonRAM[i]->Degenerate) continue;
|
||||
if (GPU.GPU3D.RenderPolygonRAM[i]->Degenerate) continue;
|
||||
|
||||
SetupPolygon(&PolygonList[npolys], RenderPolygonRAM[i]);
|
||||
if (firsttrans < 0 && RenderPolygonRAM[i]->Translucent)
|
||||
SetupPolygon(&PolygonList[npolys], GPU.GPU3D.RenderPolygonRAM[i]);
|
||||
if (firsttrans < 0 && GPU.GPU3D.RenderPolygonRAM[i]->Translucent)
|
||||
firsttrans = npolys;
|
||||
|
||||
npolys++;
|
||||
|
Reference in New Issue
Block a user