GFX3D: Render states and geometry lists are now copied/swapped more consistently on flush. (Related to commit 8438a5a6.)
- Viewports are now processed on VIEWPORT register write instead of being processed at render time.
- CLEAR_DEPTH, CLRIMAGE_OFFSET, EDGE_COLOR, FOG_TABLE, and TOON_TABLE register writes are now handled more consistently.
- The fogDensityTable check for force-drawing clear images in gfx3d_VBlankEndSignal() has been removed. Changes done in commit 8438a5a6
will always causes this check to fail, and this commit will always cause this check to fail. Therefore, this check is now obsolete.
- Change a bunch of GFX3D-related structs from C++ style constructed structs into C-style POD structs.
This commit is contained in:
parent
be287de623
commit
5426509ede
|
@ -2,7 +2,7 @@
|
|||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 Theo Berkau
|
||||
Copyright (C) 2007 shash
|
||||
Copyright (C) 2009-2022 DeSmuME team
|
||||
Copyright (C) 2009-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -581,7 +581,7 @@ typedef union
|
|||
u8 PolygonShading:1; // 1: Polygon shading mode, interacts with POLYGON_ATTR (0x40004A4); 0=Toon Shading, 1=Highlight Shading
|
||||
u8 EnableAlphaTest:1; // 2: Perform alpha test, interacts with ALPHA_TEST_REF (0x4000340); 0=Disable, 1=Enable
|
||||
u8 EnableAlphaBlending:1; // 3: Perform alpha blending, interacts with POLYGON_ATTR (0x40004A4); 0=Disable, 1=Enable
|
||||
u8 EnableAntiAliasing:1; // 4: Render polygon edges with antialiasing; 0=Disable, 1=Enable
|
||||
u8 EnableAntialiasing:1; // 4: Render polygon edges with antialiasing; 0=Disable, 1=Enable
|
||||
u8 EnableEdgeMarking:1; // 5: Perform polygon edge marking, interacts with EDGE_COLOR (0x4000330); 0=Disable, 1=Enable
|
||||
u8 FogOnlyAlpha:1; // 6: Apply fog to the alpha channel only, interacts with FOG_COLOR (0x4000358) / FOG_TABLE (0x4000360); 0=Color+Alpha, 1=Alpha
|
||||
u8 EnableFog:1; // 7: Perform fog rendering, interacts with FOG_COLOR (0x4000358) / FOG_OFFSET (0x400035C) / FOG_TABLE (0x4000360);
|
||||
|
@ -600,7 +600,7 @@ typedef union
|
|||
// 0=Disable, 1=Enable
|
||||
u8 FogOnlyAlpha:1; // 6: Apply fog to the alpha channel only, interacts with FOG_COLOR (0x4000358) / FOG_TABLE (0x4000360); 0=Color+Alpha, 1=Alpha
|
||||
u8 EnableEdgeMarking:1; // 5: Perform polygon edge marking, interacts with EDGE_COLOR (0x4000330); 0=Disable, 1=Enable
|
||||
u8 EnableAntiAliasing:1; // 4: Render polygon edges with antialiasing; 0=Disable, 1=Enable
|
||||
u8 EnableAntialiasing:1; // 4: Render polygon edges with antialiasing; 0=Disable, 1=Enable
|
||||
u8 EnableAlphaBlending:1; // 3: Perform alpha blending, interacts with POLYGON_ATTR (0x40004A4); 0=Disable, 1=Enable
|
||||
u8 EnableAlphaTest:1; // 2: Perform alpha test, interacts with ALPHA_TEST_REF (0x4000340); 0=Disable, 1=Enable
|
||||
u8 PolygonShading:1; // 1: Polygon shading mode, interacts with POLYGON_ATTR (0x40004A4); 0=Toon Shading, 1=Highlight Shading
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2007 shash
|
||||
Copyright (C) 2007-2022 DeSmuME team
|
||||
Copyright (C) 2007-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1830,13 +1830,28 @@ static void writereg_POWCNT1(const int size, const u32 adr, const u32 val)
|
|||
if(wasGeomEnabled && !isGeomEnabled)
|
||||
{
|
||||
//kill the geometry data when the power goes off
|
||||
//but save these tables, first. they shouldnt be cleared.
|
||||
//so, so bad. we need to model this with hardware-like operations instead of c++ code
|
||||
GFX3D_State prior = gfx3d.state;
|
||||
reconstruct(&gfx3d.state);
|
||||
memcpy(gfx3d.state.u16ToonTable, prior.u16ToonTable, sizeof(prior.u16ToonTable));
|
||||
//dont think we should save this one: it's sent with 3d commands, not random bonus immediate register writes like the toon table
|
||||
//memcpy(gfx3d.state.shininessTable, prior.shininessTable, sizeof(prior.shininessTable));
|
||||
|
||||
// TODO: Test which geometry data should be cleared on power off.
|
||||
// The code below doesn't make any sense. You would think that only the data that
|
||||
// is derived from geometry commands (either via GXFIFO or if writing to registers
|
||||
// 0x04000440 - 0x040006A4) is what should be cleared. And that outside of geometry
|
||||
// command data, other data (even if related to the 3D engine) shouldn't be touched.
|
||||
// This will need further testing, but for now, we'll leave things as they are.
|
||||
// - 2023/01/22, rogerman
|
||||
gfx3d.pendingState.DISP3DCNT.value = 0;
|
||||
gfx3d.pendingState.DISP3DCNT.EnableTexMapping = 1;
|
||||
gfx3d.pendingState.DISP3DCNT.PolygonShading = PolygonShadingMode_Toon;
|
||||
gfx3d.pendingState.DISP3DCNT.EnableAlphaTest = 1;
|
||||
gfx3d.pendingState.DISP3DCNT.EnableAlphaBlending = 1;
|
||||
gfx3d.pendingState.SWAP_BUFFERS.value = 0;
|
||||
gfx3d.pendingState.alphaTestRef = 0;
|
||||
gfx3d.pendingState.clearDepth = DS_DEPTH15TO24(0x7FFF);
|
||||
gfx3d.pendingState.clearColor = 0;
|
||||
gfx3d.pendingState.fogColor = 0;
|
||||
gfx3d.pendingState.fogOffset = 0;
|
||||
gfx3d.pendingState.fogShift = 0;
|
||||
memset(gfx3d.pendingState.shininessTable, 0, sizeof(gfx3d.pendingState.shininessTable));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3271,6 +3286,28 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (adr >> 4)
|
||||
{
|
||||
case 0x400033: // Edge Mark Color Table
|
||||
MMU.ARM9_REG[adr & 0xFFF] = val;
|
||||
gfx3d_UpdateEdgeMarkColorTable<u8>((u8)(adr & 0x0000000F), val);
|
||||
return;
|
||||
|
||||
case 0x400036:
|
||||
case 0x400037: // Fog Table
|
||||
MMU.ARM9_REG[adr & 0xFFF] = val & 0x7F;
|
||||
gfx3d_UpdateFogTable<u8>((u8)(adr & 0x0000001F), val & 0x7F); // Drop the highest bit of each 8-bit value to limit the range to [0...127]
|
||||
return;
|
||||
|
||||
case 0x400038:
|
||||
case 0x400039:
|
||||
case 0x40003A:
|
||||
case 0x40003B: // Toon Table
|
||||
MMU.ARM9_REG[adr & 0xFFF] = val;
|
||||
gfx3d_UpdateToonTable<u8>((u8)(adr & 0x0000003F), val);
|
||||
return;
|
||||
}
|
||||
|
||||
GPUEngineA *mainEngine = GPU->GetEngineMain();
|
||||
GPUEngineB *subEngine = GPU->GetEngineSub();
|
||||
|
||||
|
@ -3615,18 +3652,6 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
|
|||
case REG_DIVCNT+3: printf("ERROR 8bit DIVCNT+3 WRITE\n"); return;
|
||||
#endif
|
||||
|
||||
//fog table: only write bottom 7 bits
|
||||
case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x01: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x03:
|
||||
case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x05: case eng_3D_FOG_TABLE+0x06: case eng_3D_FOG_TABLE+0x07:
|
||||
case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x09: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0B:
|
||||
case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0D: case eng_3D_FOG_TABLE+0x0E: case eng_3D_FOG_TABLE+0x0F:
|
||||
case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x11: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x13:
|
||||
case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x15: case eng_3D_FOG_TABLE+0x16: case eng_3D_FOG_TABLE+0x17:
|
||||
case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x19: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1B:
|
||||
case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1D: case eng_3D_FOG_TABLE+0x1E: case eng_3D_FOG_TABLE+0x1F:
|
||||
val &= 0x7F;
|
||||
break;
|
||||
|
||||
//ensata putchar port
|
||||
case 0x04FFF000:
|
||||
if(nds.ensataEmulation)
|
||||
|
@ -3663,9 +3688,29 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
|
|||
|
||||
case eng_3D_CLEAR_COLOR+0: case eng_3D_CLEAR_COLOR+1:
|
||||
case eng_3D_CLEAR_COLOR+2: case eng_3D_CLEAR_COLOR+3:
|
||||
T1WriteByte((u8*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val);
|
||||
T1WriteByte((u8*)&gfx3d.pendingState.clearColor, adr-eng_3D_CLEAR_COLOR, val);
|
||||
break;
|
||||
|
||||
case eng_3D_CLEAR_DEPTH:
|
||||
HostWriteByte(MMU.ARM9_REG, 0x0354, val);
|
||||
gfx3d_glClearDepth<u8, 0>(val);
|
||||
return;
|
||||
|
||||
case eng_3D_CLEAR_DEPTH+1:
|
||||
HostWriteByte(MMU.ARM9_REG, 0x0355, val);
|
||||
gfx3d_glClearDepth<u8, 1>(val);
|
||||
return;
|
||||
|
||||
case eng_3D_CLRIMAGE_OFFSET:
|
||||
HostWriteByte(MMU.ARM9_REG, 0x0356, val);
|
||||
gfx3d_glClearImageOffset<u8, 0>(val);
|
||||
return;
|
||||
|
||||
case eng_3D_CLRIMAGE_OFFSET+1:
|
||||
HostWriteByte(MMU.ARM9_REG, 0x0357, val);
|
||||
gfx3d_glClearImageOffset<u8, 1>(val);
|
||||
return;
|
||||
|
||||
case REG_VRAMCNTA:
|
||||
case REG_VRAMCNTB:
|
||||
case REG_VRAMCNTC:
|
||||
|
@ -3761,13 +3806,23 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
|||
|
||||
switch (adr >> 4)
|
||||
{
|
||||
//toon table
|
||||
case 0x0400038:
|
||||
case 0x0400039:
|
||||
case 0x040003A:
|
||||
case 0x040003B:
|
||||
((u16 *)(MMU.ARM9_REG))[(adr & 0xFFF)>>1] = val;
|
||||
gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val);
|
||||
case 0x400033: // Edge Mark Color Table
|
||||
((u16 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u16) >> 1)] = val;
|
||||
gfx3d_UpdateEdgeMarkColorTable<u16>((u8)(adr & 0x0000000F), val);
|
||||
return;
|
||||
|
||||
case 0x400036:
|
||||
case 0x400037: // Fog Table
|
||||
((u16 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u16) >> 1)] = val & 0x7F7F;
|
||||
gfx3d_UpdateFogTable<u16>((u8)(adr & 0x0000001F), val & 0x7F7F); // Drop the highest bit of each 8-bit value to limit the range to [0...127]
|
||||
return;
|
||||
|
||||
case 0x400038:
|
||||
case 0x400039:
|
||||
case 0x40003A:
|
||||
case 0x40003B: // Toon Table
|
||||
((u16 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u16) >> 1)] = val;
|
||||
gfx3d_UpdateToonTable<u16>((u8)(adr & 0x0000003F), val);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4262,14 +4317,6 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
|||
MMU_new.gxstat.write(16,adr,val);
|
||||
break;
|
||||
|
||||
//fog table: only write bottom 7 bits
|
||||
case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x06:
|
||||
case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0E:
|
||||
case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x16:
|
||||
case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1E:
|
||||
val &= 0x7F7F;
|
||||
break;
|
||||
|
||||
// Alpha test reference value - Parameters:1
|
||||
case eng_3D_ALPHA_TEST_REF:
|
||||
HostWriteWord(MMU.ARM9_REG, 0x0340, val);
|
||||
|
@ -4278,13 +4325,18 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
|||
|
||||
case eng_3D_CLEAR_COLOR:
|
||||
case eng_3D_CLEAR_COLOR+2:
|
||||
T1WriteWord((u8*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val);
|
||||
T1WriteWord((u8 *)&gfx3d.pendingState.clearColor, adr-eng_3D_CLEAR_COLOR, val);
|
||||
break;
|
||||
|
||||
// Clear background depth setup - Parameters:2
|
||||
case eng_3D_CLEAR_DEPTH:
|
||||
HostWriteWord(MMU.ARM9_REG, 0x0354, val);
|
||||
gfx3d_glClearDepth(val);
|
||||
gfx3d_glClearDepth<u16, 0>(val);
|
||||
return;
|
||||
|
||||
case eng_3D_CLRIMAGE_OFFSET:
|
||||
HostWriteWord(MMU.ARM9_REG, 0x0356, val);
|
||||
gfx3d_glClearImageOffset<u16, 0>(val);
|
||||
return;
|
||||
|
||||
// Fog Color - Parameters:4b
|
||||
|
@ -4477,16 +4529,23 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
// lookups by the compiler
|
||||
switch (adr >> 4)
|
||||
{
|
||||
case 0x400033: //edge color table
|
||||
((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> 2] = val;
|
||||
case 0x400033: // Edge Mark Color Table
|
||||
((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u32) >> 1)] = val;
|
||||
gfx3d_UpdateEdgeMarkColorTable<u32>((u8)(adr & 0x0000000F), val);
|
||||
return;
|
||||
|
||||
case 0x400036:
|
||||
case 0x400037: // Fog Table
|
||||
((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u32) >> 1)] = val & 0x7F7F7F7F;
|
||||
gfx3d_UpdateFogTable<u32>((u8)(adr & 0x0000001F), val & 0x7F7F7F7F); // Drop the highest bit of each 8-bit value to limit the range to [0...127]
|
||||
return;
|
||||
|
||||
case 0x400038:
|
||||
case 0x400039:
|
||||
case 0x40003A:
|
||||
case 0x40003B: //toon table
|
||||
((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> 2] = val;
|
||||
gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val);
|
||||
case 0x40003B: // Toon Table
|
||||
((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u32) >> 1)] = val;
|
||||
gfx3d_UpdateToonTable<u32>((u8)(adr & 0x0000003F), val);
|
||||
return;
|
||||
|
||||
case 0x400040:
|
||||
|
@ -4790,12 +4849,6 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
|
||||
case REG_POWCNT1: writereg_POWCNT1(32,adr,val); break;
|
||||
|
||||
//fog table: only write bottom 7 bits
|
||||
case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0C:
|
||||
case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1C:
|
||||
val &= 0x7F7F7F7F;
|
||||
break;
|
||||
|
||||
//ensata handshaking port?
|
||||
case 0x04FFF010:
|
||||
if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_ack && val == 0x13579bdf)
|
||||
|
@ -4828,13 +4881,14 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
return;
|
||||
|
||||
case eng_3D_CLEAR_COLOR:
|
||||
T1WriteLong((u8*)&gfx3d.state.clearColor,0,val);
|
||||
T1WriteLong((u8 *)&gfx3d.pendingState.clearColor, 0, val);
|
||||
break;
|
||||
|
||||
// Clear background depth setup - Parameters:2
|
||||
case eng_3D_CLEAR_DEPTH:
|
||||
HostWriteLong(MMU.ARM9_REG, 0x0354, val);
|
||||
gfx3d_glClearDepth(val);
|
||||
gfx3d_glClearDepth<u16, 0>((u16)(val & 0x0000FFFF));
|
||||
gfx3d_glClearImageOffset<u16, 0>((u16)(val >> 16));
|
||||
return;
|
||||
|
||||
// Fog Color - Parameters:4b
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2022 DeSmuME team
|
||||
Copyright (C) 2008-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1777,7 +1777,7 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const CPoly *clippedPolyList, c
|
|||
const POLY &initialPoly = *clippedPolyList[firstIndex].poly;
|
||||
TEXIMAGE_PARAM lastTexParams = initialPoly.texParam;
|
||||
u32 lastTexPalette = initialPoly.texPalette;
|
||||
u32 lastViewport = initialPoly.viewport;
|
||||
GFX3D_Viewport lastViewport = initialPoly.viewport;
|
||||
|
||||
this->SetupTexture(initialPoly, firstIndex);
|
||||
this->SetupViewport(initialPoly.viewport);
|
||||
|
@ -1806,7 +1806,7 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const CPoly *clippedPolyList, c
|
|||
}
|
||||
|
||||
// Set up the viewport if it changed
|
||||
if (lastViewport != thePoly.viewport)
|
||||
if (lastViewport.value != thePoly.viewport.value)
|
||||
{
|
||||
lastViewport = thePoly.viewport;
|
||||
this->SetupViewport(thePoly.viewport);
|
||||
|
@ -1833,7 +1833,7 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const CPoly *clippedPolyList, c
|
|||
if (lastPolyAttr.value == nextPoly.attribute.value &&
|
||||
lastTexParams.value == nextPoly.texParam.value &&
|
||||
lastTexPalette == nextPoly.texPalette &&
|
||||
lastViewport == nextPoly.viewport &&
|
||||
lastViewport.value == nextPoly.viewport.value &&
|
||||
polyPrimitive == oglPrimitiveType[nextPoly.vtxFormat] &&
|
||||
polyPrimitive != GL_LINE_LOOP &&
|
||||
polyPrimitive != GL_LINE_STRIP &&
|
||||
|
@ -3874,7 +3874,7 @@ Render3DError OpenGLRenderer_1_2::DisableVertexAttributes()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr)
|
||||
Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
|
@ -3957,7 +3957,7 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const CPoly *clippedPolyList,
|
|||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
glStencilFunc(GL_NOTEQUAL, 0x40, 0x40);
|
||||
|
||||
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(clippedPolyList, clippedPolyCount, this->_clippedPolyOpaqueCount, clippedPolyCount - 1, indexOffset, lastPolyAttr);
|
||||
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(clippedPolyList, clippedPolyCount, clippedPolyOpaqueCount, clippedPolyCount - 1, indexOffset, lastPolyAttr);
|
||||
|
||||
// Restore OpenGL states back to normal.
|
||||
this->_geometryProgramFlags = oldGProgramFlags;
|
||||
|
@ -4157,7 +4157,7 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
||||
Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
|
@ -4166,11 +4166,11 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
return OGLERROR_BEGINGL_FAILED;
|
||||
}
|
||||
|
||||
this->_clippedPolyCount = engine.clippedPolyCount;
|
||||
this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount;
|
||||
this->_clippedPolyList = engine.clippedPolyList;
|
||||
this->_clippedPolyCount = renderGList.clippedPolyCount;
|
||||
this->_clippedPolyOpaqueCount = renderGList.clippedPolyOpaqueCount;
|
||||
this->_clippedPolyList = (CPoly *)renderGList.clippedPolyList;
|
||||
|
||||
this->_enableAlphaBlending = (engine.renderState.enableAlphaBlending) ? true : false;
|
||||
this->_enableAlphaBlending = (renderState.DISP3DCNT.EnableAlphaBlending) ? true : false;
|
||||
|
||||
if (this->isVBOSupported)
|
||||
{
|
||||
|
@ -4178,14 +4178,14 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID);
|
||||
|
||||
// Only copy as much vertex data as we need to, since this can be a potentially large upload size.
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * engine.vertListCount, engine.vertList);
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * renderGList.vertListCount, renderGList.vertList);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If VBOs aren't supported, we need to use the client-side buffers here.
|
||||
OGLRef.vtxPtrPosition = &engine.vertList[0].coord;
|
||||
OGLRef.vtxPtrTexCoord = &engine.vertList[0].texcoord;
|
||||
OGLRef.vtxPtrColor = (this->isShaderSupported) ? (GLvoid *)&engine.vertList[0].color : OGLRef.color4fBuffer;
|
||||
OGLRef.vtxPtrPosition = (GLvoid *)&renderGList.vertList[0].coord;
|
||||
OGLRef.vtxPtrTexCoord = (GLvoid *)&renderGList.vertList[0].texcoord;
|
||||
OGLRef.vtxPtrColor = (this->isShaderSupported) ? (GLvoid *)&renderGList.vertList[0].color : OGLRef.color4fBuffer;
|
||||
}
|
||||
|
||||
// Generate the clipped polygon list.
|
||||
|
@ -4197,10 +4197,10 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
|
||||
const size_t polyType = thePoly.type;
|
||||
const VERT vert[4] = {
|
||||
engine.vertList[thePoly.vertIndexes[0]],
|
||||
engine.vertList[thePoly.vertIndexes[1]],
|
||||
engine.vertList[thePoly.vertIndexes[2]],
|
||||
engine.vertList[thePoly.vertIndexes[3]]
|
||||
renderGList.vertList[thePoly.vertIndexes[0]],
|
||||
renderGList.vertList[thePoly.vertIndexes[1]],
|
||||
renderGList.vertList[thePoly.vertIndexes[2]],
|
||||
renderGList.vertList[thePoly.vertIndexes[3]]
|
||||
};
|
||||
|
||||
if (this->isShaderSupported)
|
||||
|
@ -4238,7 +4238,7 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
|
||||
// Consolidate the vertex color and the poly alpha to our internal color buffer
|
||||
// so that OpenGL can use it.
|
||||
const VERT *vertForAlpha = &engine.vertList[vertIndex];
|
||||
const VERT *vertForAlpha = &renderGList.vertList[vertIndex];
|
||||
OGLRef.color4fBuffer[colorIndex+0] = divide6bitBy63_LUT[vertForAlpha->color[0]];
|
||||
OGLRef.color4fBuffer[colorIndex+1] = divide6bitBy63_LUT[vertForAlpha->color[1]];
|
||||
OGLRef.color4fBuffer[colorIndex+2] = divide6bitBy63_LUT[vertForAlpha->color[2]];
|
||||
|
@ -4289,29 +4289,29 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
}
|
||||
|
||||
// Set up rendering states that will remain constant for the entire frame.
|
||||
this->_pendingRenderStates.enableAntialiasing = (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableFogAlphaOnly = (engine.renderState.enableFogAlphaOnly) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableAntialiasing = (renderState.DISP3DCNT.EnableAntialiasing) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableFogAlphaOnly = (renderState.DISP3DCNT.FogOnlyAlpha) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.clearPolyID = this->_clearAttributes.opaquePolyID;
|
||||
this->_pendingRenderStates.clearDepth = (GLfloat)this->_clearAttributes.depth / (GLfloat)0x00FFFFFF;
|
||||
this->_pendingRenderStates.alphaTestRef = divide5bitBy31_LUT[engine.renderState.alphaTestRef];
|
||||
this->_pendingRenderStates.alphaTestRef = divide5bitBy31_LUT[renderState.alphaTestRef];
|
||||
|
||||
if (this->_enableFog && this->_deviceInfo.isFogSupported)
|
||||
{
|
||||
this->_fogProgramKey.key = 0;
|
||||
this->_fogProgramKey.offset = engine.renderState.fogOffset & 0x7FFF;
|
||||
this->_fogProgramKey.shift = engine.renderState.fogShift;
|
||||
this->_fogProgramKey.offset = renderState.fogOffset & 0x7FFF;
|
||||
this->_fogProgramKey.shift = renderState.fogShift;
|
||||
|
||||
this->_pendingRenderStates.fogColor.r = divide5bitBy31_LUT[(engine.renderState.fogColor ) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.g = divide5bitBy31_LUT[(engine.renderState.fogColor >> 5) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.b = divide5bitBy31_LUT[(engine.renderState.fogColor >> 10) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.a = divide5bitBy31_LUT[(engine.renderState.fogColor >> 16) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogOffset = (GLfloat)(engine.renderState.fogOffset & 0x7FFF) / 32767.0f;
|
||||
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> engine.renderState.fogShift) / 32767.0f;
|
||||
this->_pendingRenderStates.fogColor.r = divide5bitBy31_LUT[(renderState.fogColor ) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.g = divide5bitBy31_LUT[(renderState.fogColor >> 5) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.b = divide5bitBy31_LUT[(renderState.fogColor >> 10) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.a = divide5bitBy31_LUT[(renderState.fogColor >> 16) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogOffset = (GLfloat)(renderState.fogOffset & 0x7FFF) / 32767.0f;
|
||||
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> renderState.fogShift) / 32767.0f;
|
||||
|
||||
u8 fogDensityTable[32];
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
{
|
||||
fogDensityTable[i] = (engine.renderState.fogDensityTable[i] == 127) ? 255 : engine.renderState.fogDensityTable[i] << 1;
|
||||
fogDensityTable[i] = (renderState.fogDensityTable[i] == 127) ? 255 : renderState.fogDensityTable[i] << 1;
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
||||
|
@ -4321,12 +4321,12 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
|
||||
if (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported)
|
||||
{
|
||||
const u8 alpha8 = (engine.renderState.enableAntialiasing) ? 0x80 : 0xFF;
|
||||
const u8 alpha8 = (renderState.DISP3DCNT.EnableAntialiasing) ? 0x80 : 0xFF;
|
||||
FragmentColor edgeColor32[8];
|
||||
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
edgeColor32[i].color = COLOR555TO8888(engine.renderState.edgeMarkColorTable[i] & 0x7FFF, alpha8);
|
||||
edgeColor32[i].color = COLOR555TO8888(renderState.edgeMarkColorTable[i] & 0x7FFF, alpha8);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
||||
|
@ -4337,10 +4337,10 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
if (this->isShaderSupported)
|
||||
{
|
||||
this->_geometryProgramFlags.value = 0;
|
||||
this->_geometryProgramFlags.EnableWDepth = (engine.renderState.wbuffer) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableAlphaTest = (engine.renderState.enableAlphaTest) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableWDepth = renderState.SWAP_BUFFERS.DepthMode;
|
||||
this->_geometryProgramFlags.EnableAlphaTest = renderState.DISP3DCNT.EnableAlphaTest;
|
||||
this->_geometryProgramFlags.EnableTextureSampling = (this->_enableTextureSampling) ? 1 : 0;
|
||||
this->_geometryProgramFlags.ToonShadingMode = (engine.renderState.shading) ? 1 : 0;
|
||||
this->_geometryProgramFlags.ToonShadingMode = renderState.DISP3DCNT.PolygonShading;
|
||||
this->_geometryProgramFlags.EnableFog = (this->_enableFog && this->_deviceInfo.isFogSupported) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0;
|
||||
this->_geometryProgramFlags.OpaqueDrawMode = (this->_isDepthLEqualPolygonFacingSupported) ? 1 : 0;
|
||||
|
@ -4351,14 +4351,14 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
{
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
||||
glBindTexture(GL_TEXTURE_1D, OGLRef.texToonTableID);
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, engine.renderState.u16ToonTable);
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderState.toonTable16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (engine.renderState.enableAlphaTest && (engine.renderState.alphaTestRef > 0))
|
||||
if (renderState.DISP3DCNT.EnableAlphaTest && (renderState.alphaTestRef > 0))
|
||||
{
|
||||
glAlphaFunc(GL_GEQUAL, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
|
||||
glAlphaFunc(GL_GEQUAL, divide5bitBy31_LUT[renderState.alphaTestRef]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4426,7 +4426,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry()
|
|||
this->SetupPolygon(firstPoly, true, false);
|
||||
}
|
||||
|
||||
this->ZeroDstAlphaPass(this->_clippedPolyList, this->_clippedPolyCount, this->_enableAlphaBlending, indexOffset, lastPolyAttr);
|
||||
this->ZeroDstAlphaPass(this->_clippedPolyList, this->_clippedPolyCount, this->_clippedPolyOpaqueCount, this->_enableAlphaBlending, indexOffset, lastPolyAttr);
|
||||
|
||||
if (this->_clippedPolyOpaqueCount > 0)
|
||||
{
|
||||
|
@ -4956,23 +4956,15 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, size_t polyR
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::SetupViewport(const u32 viewportValue)
|
||||
Render3DError OpenGLRenderer_1_2::SetupViewport(const GFX3D_Viewport viewport)
|
||||
{
|
||||
const GLfloat wScalar = this->_framebufferWidth / (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH;
|
||||
const GLfloat hScalar = this->_framebufferHeight / (GLfloat)GPU_FRAMEBUFFER_NATIVE_HEIGHT;
|
||||
|
||||
VIEWPORT viewport;
|
||||
viewport.decode(viewportValue);
|
||||
|
||||
// The maximum viewport y-value is 191. Values above 191 need to wrap
|
||||
// around and go negative.
|
||||
//
|
||||
// Test case: The Homie Rollerz character select screen sets the y-value
|
||||
// to 253, which then wraps around to -2.
|
||||
glViewport( viewport.x * wScalar,
|
||||
(viewport.y > 191) ? (viewport.y - 0xFF) * hScalar : viewport.y * hScalar,
|
||||
viewport.width * wScalar,
|
||||
viewport.height * hScalar);
|
||||
glViewport(viewport.x * wScalar,
|
||||
viewport.y * hScalar,
|
||||
viewport.width * wScalar,
|
||||
viewport.height * hScalar);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
@ -5446,7 +5438,7 @@ Render3DError OpenGLRenderer_2_0::DisableVertexAttributes()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
|
||||
Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
|
@ -5455,17 +5447,17 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
|
|||
return OGLERROR_BEGINGL_FAILED;
|
||||
}
|
||||
|
||||
this->_clippedPolyCount = engine.clippedPolyCount;
|
||||
this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount;
|
||||
this->_clippedPolyList = engine.clippedPolyList;
|
||||
this->_clippedPolyCount = renderGList.clippedPolyCount;
|
||||
this->_clippedPolyOpaqueCount = renderGList.clippedPolyOpaqueCount;
|
||||
this->_clippedPolyList = (CPoly *)renderGList.clippedPolyList;
|
||||
|
||||
this->_enableAlphaBlending = (engine.renderState.enableAlphaBlending) ? true : false;
|
||||
this->_enableAlphaBlending = (renderState.DISP3DCNT.EnableAlphaBlending) ? true : false;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
|
||||
|
||||
// Only copy as much vertex data as we need to, since this can be a potentially large upload size.
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * engine.vertListCount, engine.vertList);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * renderGList.vertListCount, renderGList.vertList);
|
||||
|
||||
// Generate the clipped polygon list.
|
||||
bool renderNeedsToonTable = false;
|
||||
|
@ -5476,10 +5468,10 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
|
|||
|
||||
const size_t polyType = thePoly.type;
|
||||
const VERT vert[4] = {
|
||||
engine.vertList[thePoly.vertIndexes[0]],
|
||||
engine.vertList[thePoly.vertIndexes[1]],
|
||||
engine.vertList[thePoly.vertIndexes[2]],
|
||||
engine.vertList[thePoly.vertIndexes[3]]
|
||||
renderGList.vertList[thePoly.vertIndexes[0]],
|
||||
renderGList.vertList[thePoly.vertIndexes[1]],
|
||||
renderGList.vertList[thePoly.vertIndexes[2]],
|
||||
renderGList.vertList[thePoly.vertIndexes[3]]
|
||||
};
|
||||
|
||||
for (size_t j = 0; j < polyType; j++)
|
||||
|
@ -5527,29 +5519,29 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
|
|||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(OGLRef.vertIndexBuffer), OGLRef.vertIndexBuffer);
|
||||
|
||||
// Set up rendering states that will remain constant for the entire frame.
|
||||
this->_pendingRenderStates.enableAntialiasing = (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableFogAlphaOnly = (engine.renderState.enableFogAlphaOnly) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableAntialiasing = (renderState.DISP3DCNT.EnableAntialiasing) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableFogAlphaOnly = (renderState.DISP3DCNT.FogOnlyAlpha) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.clearPolyID = this->_clearAttributes.opaquePolyID;
|
||||
this->_pendingRenderStates.clearDepth = (GLfloat)this->_clearAttributes.depth / (GLfloat)0x00FFFFFF;
|
||||
this->_pendingRenderStates.alphaTestRef = divide5bitBy31_LUT[engine.renderState.alphaTestRef];
|
||||
this->_pendingRenderStates.alphaTestRef = divide5bitBy31_LUT[renderState.alphaTestRef];
|
||||
|
||||
if (this->_enableFog && this->_deviceInfo.isFogSupported)
|
||||
{
|
||||
this->_fogProgramKey.key = 0;
|
||||
this->_fogProgramKey.offset = engine.renderState.fogOffset & 0x7FFF;
|
||||
this->_fogProgramKey.shift = engine.renderState.fogShift;
|
||||
this->_fogProgramKey.offset = renderState.fogOffset & 0x7FFF;
|
||||
this->_fogProgramKey.shift = renderState.fogShift;
|
||||
|
||||
this->_pendingRenderStates.fogColor.r = divide5bitBy31_LUT[(engine.renderState.fogColor ) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.g = divide5bitBy31_LUT[(engine.renderState.fogColor >> 5) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.b = divide5bitBy31_LUT[(engine.renderState.fogColor >> 10) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.a = divide5bitBy31_LUT[(engine.renderState.fogColor >> 16) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogOffset = (GLfloat)(engine.renderState.fogOffset & 0x7FFF) / 32767.0f;
|
||||
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> engine.renderState.fogShift) / 32767.0f;
|
||||
this->_pendingRenderStates.fogColor.r = divide5bitBy31_LUT[(renderState.fogColor ) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.g = divide5bitBy31_LUT[(renderState.fogColor >> 5) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.b = divide5bitBy31_LUT[(renderState.fogColor >> 10) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.a = divide5bitBy31_LUT[(renderState.fogColor >> 16) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogOffset = (GLfloat)(renderState.fogOffset & 0x7FFF) / 32767.0f;
|
||||
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> renderState.fogShift) / 32767.0f;
|
||||
|
||||
u8 fogDensityTable[32];
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
{
|
||||
fogDensityTable[i] = (engine.renderState.fogDensityTable[i] == 127) ? 255 : engine.renderState.fogDensityTable[i] << 1;
|
||||
fogDensityTable[i] = (renderState.fogDensityTable[i] == 127) ? 255 : renderState.fogDensityTable[i] << 1;
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
||||
|
@ -5559,12 +5551,12 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
|
|||
|
||||
if (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported)
|
||||
{
|
||||
const u8 alpha8 = (engine.renderState.enableAntialiasing) ? 0x80 : 0xFF;
|
||||
const u8 alpha8 = (renderState.DISP3DCNT.EnableAntialiasing) ? 0x80 : 0xFF;
|
||||
FragmentColor edgeColor32[8];
|
||||
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
edgeColor32[i].color = COLOR555TO8888(engine.renderState.edgeMarkColorTable[i] & 0x7FFF, alpha8);
|
||||
edgeColor32[i].color = COLOR555TO8888(renderState.edgeMarkColorTable[i] & 0x7FFF, alpha8);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
||||
|
@ -5574,10 +5566,10 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
|
|||
|
||||
// Setup render states
|
||||
this->_geometryProgramFlags.value = 0;
|
||||
this->_geometryProgramFlags.EnableWDepth = (engine.renderState.wbuffer) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableAlphaTest = (engine.renderState.enableAlphaTest) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableWDepth = renderState.SWAP_BUFFERS.DepthMode;
|
||||
this->_geometryProgramFlags.EnableAlphaTest = renderState.DISP3DCNT.EnableAlphaTest;
|
||||
this->_geometryProgramFlags.EnableTextureSampling = (this->_enableTextureSampling) ? 1 : 0;
|
||||
this->_geometryProgramFlags.ToonShadingMode = (engine.renderState.shading) ? 1 : 0;
|
||||
this->_geometryProgramFlags.ToonShadingMode = renderState.DISP3DCNT.PolygonShading;
|
||||
this->_geometryProgramFlags.EnableFog = (this->_enableFog && this->_deviceInfo.isFogSupported) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0;
|
||||
this->_geometryProgramFlags.OpaqueDrawMode = (this->_isDepthLEqualPolygonFacingSupported) ? 1 : 0;
|
||||
|
@ -5588,7 +5580,7 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
|
|||
{
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
||||
glBindTexture(GL_TEXTURE_1D, OGLRef.texToonTableID);
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, engine.renderState.u16ToonTable);
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderState.toonTable16);
|
||||
}
|
||||
|
||||
glReadBuffer(GL_COLOROUT_ATTACHMENT_ID);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2022 DeSmuME team
|
||||
Copyright (C) 2008-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -323,7 +323,7 @@ enum OGLTextureUnitID
|
|||
OGLTextureUnitID_DepthStencil,
|
||||
OGLTextureUnitID_GPolyID,
|
||||
OGLTextureUnitID_FogAttr,
|
||||
OGLTextureUnitID_PolyStates,
|
||||
OGLTextureUnitID_PolyStates,
|
||||
OGLTextureUnitID_LookupTable,
|
||||
};
|
||||
|
||||
|
@ -604,8 +604,6 @@ struct OGLRenderRef
|
|||
};
|
||||
|
||||
struct GFX3D_State;
|
||||
struct POLYLIST;
|
||||
struct INDEXLIST;
|
||||
struct POLY;
|
||||
class OpenGLRenderer;
|
||||
|
||||
|
@ -876,13 +874,13 @@ protected:
|
|||
virtual void _SetupGeometryShaders(const OGLGeometryFlags flags);
|
||||
virtual Render3DError EnableVertexAttributes();
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
|
||||
virtual Render3DError ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
|
||||
virtual void _ResolveWorkingBackFacing();
|
||||
virtual void _ResolveGeometry();
|
||||
virtual Render3DError ReadBackPixels();
|
||||
|
||||
// Base rendering methods
|
||||
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
|
||||
virtual Render3DError RenderGeometry();
|
||||
virtual Render3DError PostprocessFramebuffer();
|
||||
virtual Render3DError EndRender();
|
||||
|
@ -893,7 +891,7 @@ protected:
|
|||
virtual void SetPolygonIndex(const size_t index);
|
||||
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer);
|
||||
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
|
||||
virtual Render3DError SetupViewport(const u32 viewportValue);
|
||||
virtual Render3DError SetupViewport(const GFX3D_Viewport viewport);
|
||||
|
||||
virtual Render3DError DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool performDepthEqualTest, const bool enableAlphaDepthWrite, const bool isTranslucent, const u8 opaquePolyID);
|
||||
|
||||
|
@ -916,7 +914,7 @@ protected:
|
|||
virtual Render3DError EnableVertexAttributes();
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
|
||||
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
|
||||
|
||||
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2022 DeSmuME team
|
||||
Copyright (C) 2008-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1758,7 +1758,7 @@ Render3DError OpenGLRenderer_3_2::DisableVertexAttributes()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr)
|
||||
Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
|
@ -1816,7 +1816,7 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const CPoly *clippedPolyList,
|
|||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
glStencilFunc(GL_NOTEQUAL, 0x40, 0x40);
|
||||
|
||||
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(clippedPolyList, clippedPolyCount, this->_clippedPolyOpaqueCount, clippedPolyCount - 1, indexOffset, lastPolyAttr);
|
||||
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(clippedPolyList, clippedPolyCount, clippedPolyOpaqueCount, clippedPolyCount - 1, indexOffset, lastPolyAttr);
|
||||
|
||||
// Restore OpenGL states back to normal.
|
||||
this->_geometryProgramFlags = oldGProgramFlags;
|
||||
|
@ -1973,7 +1973,7 @@ Render3DError OpenGLRenderer_3_2::ReadBackPixels()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
||||
Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
|
@ -1982,11 +1982,11 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
return OGLERROR_BEGINGL_FAILED;
|
||||
}
|
||||
|
||||
this->_clippedPolyCount = engine.clippedPolyCount;
|
||||
this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount;
|
||||
this->_clippedPolyList = engine.clippedPolyList;
|
||||
this->_clippedPolyCount = renderGList.clippedPolyCount;
|
||||
this->_clippedPolyOpaqueCount = renderGList.clippedPolyOpaqueCount;
|
||||
this->_clippedPolyList = (CPoly *)renderGList.clippedPolyList;
|
||||
|
||||
this->_enableAlphaBlending = (engine.renderState.enableAlphaBlending) ? true : false;
|
||||
this->_enableAlphaBlending = (renderState.DISP3DCNT.EnableAlphaBlending) ? true : false;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
|
||||
|
@ -1999,9 +1999,9 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
glDeleteSync(this->_syncBufferSetup);
|
||||
}
|
||||
|
||||
const size_t vtxBufferSize = sizeof(VERT) * engine.vertListCount;
|
||||
const size_t vtxBufferSize = sizeof(VERT) * renderGList.vertListCount;
|
||||
VERT *vtxPtr = (VERT *)glMapBufferRange(GL_ARRAY_BUFFER, 0, vtxBufferSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
memcpy(vtxPtr, engine.vertList, vtxBufferSize);
|
||||
memcpy(vtxPtr, renderGList.vertList, vtxBufferSize);
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
|
||||
this->_syncBufferSetup = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
|
@ -2025,10 +2025,10 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
|
||||
const size_t polyType = thePoly.type;
|
||||
const VERT vert[4] = {
|
||||
engine.vertList[thePoly.vertIndexes[0]],
|
||||
engine.vertList[thePoly.vertIndexes[1]],
|
||||
engine.vertList[thePoly.vertIndexes[2]],
|
||||
engine.vertList[thePoly.vertIndexes[3]]
|
||||
renderGList.vertList[thePoly.vertIndexes[0]],
|
||||
renderGList.vertList[thePoly.vertIndexes[1]],
|
||||
renderGList.vertList[thePoly.vertIndexes[2]],
|
||||
renderGList.vertList[thePoly.vertIndexes[3]]
|
||||
};
|
||||
|
||||
for (size_t j = 0; j < polyType; j++)
|
||||
|
@ -2075,19 +2075,19 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(OGLRef.vertIndexBuffer), OGLRef.vertIndexBuffer);
|
||||
|
||||
// Set up rendering states that will remain constant for the entire frame.
|
||||
this->_pendingRenderStates.enableAntialiasing = (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableFogAlphaOnly = (engine.renderState.enableFogAlphaOnly) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableAntialiasing = (renderState.DISP3DCNT.EnableAntialiasing) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.enableFogAlphaOnly = (renderState.DISP3DCNT.FogOnlyAlpha) ? GL_TRUE : GL_FALSE;
|
||||
this->_pendingRenderStates.clearPolyID = this->_clearAttributes.opaquePolyID;
|
||||
this->_pendingRenderStates.clearDepth = (GLfloat)this->_clearAttributes.depth / (GLfloat)0x00FFFFFF;
|
||||
this->_pendingRenderStates.alphaTestRef = divide5bitBy31_LUT[engine.renderState.alphaTestRef];
|
||||
this->_pendingRenderStates.alphaTestRef = divide5bitBy31_LUT[renderState.alphaTestRef];
|
||||
|
||||
if (renderNeedsToonTable)
|
||||
{
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
{
|
||||
this->_pendingRenderStates.toonColor[i].r = divide5bitBy31_LUT[(engine.renderState.u16ToonTable[i] ) & 0x001F];
|
||||
this->_pendingRenderStates.toonColor[i].g = divide5bitBy31_LUT[(engine.renderState.u16ToonTable[i] >> 5) & 0x001F];
|
||||
this->_pendingRenderStates.toonColor[i].b = divide5bitBy31_LUT[(engine.renderState.u16ToonTable[i] >> 10) & 0x001F];
|
||||
this->_pendingRenderStates.toonColor[i].r = divide5bitBy31_LUT[(renderState.toonTable16[i] ) & 0x001F];
|
||||
this->_pendingRenderStates.toonColor[i].g = divide5bitBy31_LUT[(renderState.toonTable16[i] >> 5) & 0x001F];
|
||||
this->_pendingRenderStates.toonColor[i].b = divide5bitBy31_LUT[(renderState.toonTable16[i] >> 10) & 0x001F];
|
||||
this->_pendingRenderStates.toonColor[i].a = 1.0f;
|
||||
}
|
||||
}
|
||||
|
@ -2095,20 +2095,20 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
if (this->_enableFog)
|
||||
{
|
||||
this->_fogProgramKey.key = 0;
|
||||
this->_fogProgramKey.offset = engine.renderState.fogOffset & 0x7FFF;
|
||||
this->_fogProgramKey.shift = engine.renderState.fogShift;
|
||||
this->_fogProgramKey.offset = renderState.fogOffset & 0x7FFF;
|
||||
this->_fogProgramKey.shift = renderState.fogShift;
|
||||
|
||||
this->_pendingRenderStates.fogColor.r = divide5bitBy31_LUT[(engine.renderState.fogColor ) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.g = divide5bitBy31_LUT[(engine.renderState.fogColor >> 5) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.b = divide5bitBy31_LUT[(engine.renderState.fogColor >> 10) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.a = divide5bitBy31_LUT[(engine.renderState.fogColor >> 16) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogOffset = (GLfloat)(engine.renderState.fogOffset & 0x7FFF) / 32767.0f;
|
||||
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> engine.renderState.fogShift) / 32767.0f;
|
||||
this->_pendingRenderStates.fogColor.r = divide5bitBy31_LUT[(renderState.fogColor ) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.g = divide5bitBy31_LUT[(renderState.fogColor >> 5) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.b = divide5bitBy31_LUT[(renderState.fogColor >> 10) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogColor.a = divide5bitBy31_LUT[(renderState.fogColor >> 16) & 0x0000001F];
|
||||
this->_pendingRenderStates.fogOffset = (GLfloat)(renderState.fogOffset & 0x7FFF) / 32767.0f;
|
||||
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> renderState.fogShift) / 32767.0f;
|
||||
|
||||
u8 fogDensityTable[32];
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
{
|
||||
fogDensityTable[i] = (engine.renderState.fogDensityTable[i] == 127) ? 255 : engine.renderState.fogDensityTable[i] << 1;
|
||||
fogDensityTable[i] = (renderState.fogDensityTable[i] == 127) ? 255 : renderState.fogDensityTable[i] << 1;
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
||||
|
@ -2117,12 +2117,12 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
|
||||
if (this->_enableEdgeMark)
|
||||
{
|
||||
const GLfloat edgeColorAlpha = (engine.renderState.enableAntialiasing) ? (16.0f/31.0f) : 1.0f;
|
||||
const GLfloat edgeColorAlpha = (renderState.DISP3DCNT.EnableAntialiasing) ? (16.0f/31.0f) : 1.0f;
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
this->_pendingRenderStates.edgeColor[i].r = divide5bitBy31_LUT[(engine.renderState.edgeMarkColorTable[i] ) & 0x001F];
|
||||
this->_pendingRenderStates.edgeColor[i].g = divide5bitBy31_LUT[(engine.renderState.edgeMarkColorTable[i] >> 5) & 0x001F];
|
||||
this->_pendingRenderStates.edgeColor[i].b = divide5bitBy31_LUT[(engine.renderState.edgeMarkColorTable[i] >> 10) & 0x001F];
|
||||
this->_pendingRenderStates.edgeColor[i].r = divide5bitBy31_LUT[(renderState.edgeMarkColorTable[i] ) & 0x001F];
|
||||
this->_pendingRenderStates.edgeColor[i].g = divide5bitBy31_LUT[(renderState.edgeMarkColorTable[i] >> 5) & 0x001F];
|
||||
this->_pendingRenderStates.edgeColor[i].b = divide5bitBy31_LUT[(renderState.edgeMarkColorTable[i] >> 10) & 0x001F];
|
||||
this->_pendingRenderStates.edgeColor[i].a = edgeColorAlpha;
|
||||
}
|
||||
}
|
||||
|
@ -2176,10 +2176,10 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
|
||||
// Set up the default draw call states.
|
||||
this->_geometryProgramFlags.value = 0;
|
||||
this->_geometryProgramFlags.EnableWDepth = (engine.renderState.wbuffer) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableAlphaTest = (engine.renderState.enableAlphaTest) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableWDepth = renderState.SWAP_BUFFERS.DepthMode;
|
||||
this->_geometryProgramFlags.EnableAlphaTest = renderState.DISP3DCNT.EnableAlphaTest;
|
||||
this->_geometryProgramFlags.EnableTextureSampling = (this->_enableTextureSampling) ? 1 : 0;
|
||||
this->_geometryProgramFlags.ToonShadingMode = (engine.renderState.shading) ? 1 : 0;
|
||||
this->_geometryProgramFlags.ToonShadingMode = renderState.DISP3DCNT.PolygonShading;
|
||||
this->_geometryProgramFlags.EnableFog = (this->_enableFog) ? 1 : 0;
|
||||
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark) ? 1 : 0;
|
||||
this->_geometryProgramFlags.OpaqueDrawMode = 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2019 DeSmuME team
|
||||
Copyright (C) 2008-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -98,11 +98,11 @@ protected:
|
|||
virtual void _SetupGeometryShaders(const OGLGeometryFlags flags);
|
||||
virtual Render3DError EnableVertexAttributes();
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
|
||||
virtual Render3DError ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
|
||||
virtual void _ResolveWorkingBackFacing();
|
||||
virtual void _ResolveGeometry();
|
||||
virtual Render3DError ReadBackPixels();
|
||||
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
|
||||
virtual Render3DError PostprocessFramebuffer();
|
||||
|
||||
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const u8 *__restrict fogBuffer, const u8 opaquePolyID);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2022 DeSmuME team
|
||||
Copyright (C) 2008-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -144,6 +144,57 @@ void gfx3d_init();
|
|||
void gfx3d_deinit();
|
||||
void gfx3d_reset();
|
||||
|
||||
typedef union
|
||||
{
|
||||
u16 value;
|
||||
|
||||
struct
|
||||
{
|
||||
#ifndef MSB_FIRST
|
||||
u8 XOffset;
|
||||
u8 YOffset;
|
||||
#else
|
||||
u8 YOffset;
|
||||
u8 XOffset;
|
||||
#endif
|
||||
};
|
||||
} IOREG_CLRIMAGE_OFFSET;
|
||||
|
||||
typedef union
|
||||
{
|
||||
u8 cmd[4]; // 0- 7: Unpacked command OR packed command #1
|
||||
// 8-15: Packed command #2
|
||||
// 16-23: Packed command #3
|
||||
// 24-31: Packed command #4
|
||||
|
||||
u32 command; // 8-bit unpacked command
|
||||
u32 param; // Parameter(s) for previous command(s)
|
||||
|
||||
} IOREG_GXFIFO; // 0x04000400: Geometry command/parameter sent to FIFO
|
||||
|
||||
typedef union
|
||||
{
|
||||
#ifndef MSB_FIRST
|
||||
u8 MtxMode:2; // 0- 1: Set matrix mode;
|
||||
// 0=Projection
|
||||
// 1=Position
|
||||
// 2=Position+Vector
|
||||
// 3=Texture
|
||||
u8 :6; // 2- 7: Unused bits
|
||||
|
||||
u32 :24; // 8-31: Unused bits
|
||||
#else
|
||||
u8 :6; // 2- 7: Unused bits
|
||||
u8 MtxMode:2; // 0- 1: Set matrix mode;
|
||||
// 0=Projection
|
||||
// 1=Position
|
||||
// 2=Position+Vector
|
||||
// 3=Texture
|
||||
|
||||
u32 :24; // 8-31: Unused bits
|
||||
#endif
|
||||
} IOREG_MTX_MODE; // 0x04000440: MTX_MODE command port
|
||||
|
||||
typedef union
|
||||
{
|
||||
u32 value;
|
||||
|
@ -230,7 +281,7 @@ typedef union
|
|||
u8 LightMask:4; // 0- 3: Light enable mask
|
||||
#endif
|
||||
};
|
||||
} POLYGON_ATTR;
|
||||
} POLYGON_ATTR; // 0x040004A4: POLYGON_ATTR command port
|
||||
|
||||
typedef union
|
||||
{
|
||||
|
@ -301,7 +352,173 @@ typedef union
|
|||
u16 :16;
|
||||
#endif
|
||||
};
|
||||
} TEXIMAGE_PARAM;
|
||||
} TEXIMAGE_PARAM; // 0x040004A8: TEXIMAGE_PARAM command port
|
||||
|
||||
typedef union
|
||||
{
|
||||
u32 value;
|
||||
|
||||
struct
|
||||
{
|
||||
#ifndef MSB_FIRST
|
||||
u8 YSortMode:1; // 0: Translucent polygon Y-sorting mode; 0=Auto-sort, 1=Manual-sort
|
||||
u8 DepthMode:1; // 1: Depth buffering select; 0=Z 1=W
|
||||
u8 :6; // 2- 7: Unused bits
|
||||
|
||||
u32 :24; // 8-31: Unused bits
|
||||
#else
|
||||
u8 :6; // 2- 7: Unused bits
|
||||
u8 DepthMode:1; // 1: Depth buffering select; 0=Z 1=W
|
||||
u8 YSortMode:1; // 0: Translucent polygon Y-sorting mode; 0=Auto-sort, 1=Manual-sort
|
||||
|
||||
u32 :24; // 8-31: Unused bits
|
||||
#endif
|
||||
};
|
||||
} IOREG_SWAP_BUFFERS; // 0x04000540: SWAP_BUFFERS command port
|
||||
|
||||
typedef union
|
||||
{
|
||||
u32 value;
|
||||
|
||||
struct
|
||||
{
|
||||
// Coordinate (0,0) represents the bottom-left of the screen.
|
||||
// Coordinate (255,191) represents the top-right of the screen.
|
||||
u8 X1; // 0- 7: First X-coordinate; 0...255
|
||||
u8 Y1; // 8-15: First Y-coordinate; 0...191
|
||||
u8 X2; // 16-23: Second X-coordinate; 0...255
|
||||
u8 Y2; // 24-31: Second Y-coordinate; 0...191
|
||||
};
|
||||
} IOREG_VIEWPORT; // 0x04000580: VIEWPORT command port
|
||||
|
||||
typedef union
|
||||
{
|
||||
u32 value;
|
||||
|
||||
struct
|
||||
{
|
||||
u8 TestBusy:1;
|
||||
u8 BoxTestResult:1;
|
||||
u8 :6;
|
||||
|
||||
u8 PosVecMtxStackLevel:5;
|
||||
u8 ProjMtxStackLevel:1;
|
||||
u8 MtxStackBusy:1;
|
||||
u8 AckMtxStackError:1;
|
||||
|
||||
u16 CommandListCount:9;
|
||||
u8 CommandListLessThanHalf:1;
|
||||
u8 CommandListEmpty:1;
|
||||
u8 EngineBusy:1;
|
||||
u8 :2;
|
||||
u8 CommandListIRQ:2;
|
||||
};
|
||||
|
||||
} IOREG_GXSTAT; // 0x04000600: Geometry engine status
|
||||
|
||||
typedef union
|
||||
{
|
||||
u32 value;
|
||||
|
||||
struct
|
||||
{
|
||||
u16 PolygonCount; // 0-15: Number of polygons currently stored in polygon list RAM; 0...2048
|
||||
u16 VertexCount; // 16-31: Number of vertices currently stored in vertex RAM; 0...6144
|
||||
};
|
||||
} IOREG_RAM_COUNT; // 0x04000604: Polygon list and vertex RAM count
|
||||
|
||||
struct GFX3D_IOREG
|
||||
{
|
||||
u8 RDLINES_COUNT; // 0x04000320
|
||||
u8 __unused1[15];
|
||||
u16 EDGE_COLOR[8]; // 0x04000330
|
||||
u8 ALPHA_TEST_REF; // 0x04000340
|
||||
u8 __unused2[15];
|
||||
u32 CLEAR_COLOR; // 0x04000350
|
||||
u16 CLEAR_DEPTH; // 0x04000354
|
||||
IOREG_CLRIMAGE_OFFSET CLRIMAGE_OFFSET; // 0x04000356
|
||||
u32 FOG_COLOR; // 0x04000358
|
||||
u16 FOG_OFFSET; // 0x0400035C
|
||||
u8 __unused3[2];
|
||||
u8 FOG_TABLE[32]; // 0x04000360
|
||||
u16 TOON_TABLE[32]; // 0x04000380
|
||||
u8 __unused4[64];
|
||||
|
||||
IOREG_GXFIFO GXFIFO; // 0x04000400
|
||||
u8 __unused5[60];
|
||||
|
||||
// Geometry command ports
|
||||
u32 MTX_MODE; // 0x04000440
|
||||
u32 MTX_PUSH; // 0x04000444
|
||||
u32 MTX_POP; // 0x04000448
|
||||
u32 MTX_STORE; // 0x0400044C
|
||||
u32 MTX_RESTORE; // 0x04000450
|
||||
u32 MTX_IDENTITY; // 0x04000454
|
||||
u32 MTX_LOAD_4x4; // 0x04000458
|
||||
u32 MTX_LOAD_4x3; // 0x0400045C
|
||||
u32 MTX_MULT_4x4; // 0x04000460
|
||||
u32 MTX_MULT_4x3; // 0x04000464
|
||||
u32 MTX_MULT_3x3; // 0x04000468
|
||||
u32 MTX_SCALE; // 0x0400046C
|
||||
u32 MTX_TRANS; // 0x04000470
|
||||
u8 __unused6[12];
|
||||
u32 COLOR; // 0x04000480
|
||||
u32 NORMAL; // 0x04000484
|
||||
u32 TEXCOORD; // 0x04000488
|
||||
u32 VTX_16; // 0x0400048C
|
||||
u32 VTX_10; // 0x04000490
|
||||
u32 VTX_XY; // 0x04000494
|
||||
u32 VTX_XZ; // 0x04000498
|
||||
u32 VTX_YZ; // 0x0400049C
|
||||
u32 VTX_DIFF; // 0x040004A0
|
||||
u32 POLYGON_ATTR; // 0x040004A4
|
||||
u32 TEXIMAGE_PARAM; // 0x040004A8
|
||||
u32 PLTT_BASE; // 0x040004AC
|
||||
u8 __unused7[16];
|
||||
u32 DIF_AMB; // 0x040004C0
|
||||
u32 SPE_EMI; // 0x040004C4
|
||||
u32 LIGHT_VECTOR; // 0x040004C8
|
||||
u32 LIGHT_COLOR; // 0x040004CC
|
||||
u32 SHININESS; // 0x040004D0
|
||||
u8 __unused8[44];
|
||||
u32 BEGIN_VTXS; // 0x04000500
|
||||
u32 END_VTXS; // 0x04000504
|
||||
u8 __unused9[56];
|
||||
IOREG_SWAP_BUFFERS SWAP_BUFFERS; // 0x04000540
|
||||
u8 __unused10[60];
|
||||
IOREG_VIEWPORT VIEWPORT; // 0x04000580
|
||||
u8 __unused11[60];
|
||||
u32 BOX_TEST; // 0x040005C0
|
||||
u32 POS_TEST; // 0x040005C4
|
||||
u32 VEC_TEST; // 0x040005C8
|
||||
u8 __unused12[52];
|
||||
|
||||
IOREG_GXSTAT GXSTAT; // 0x04000600
|
||||
IOREG_RAM_COUNT RAM_COUNT; // 0x04000604
|
||||
u8 __unused13[8];
|
||||
u16 DISP_1DOT_DEPTH; // 0x04000610
|
||||
u8 __unused14[14];
|
||||
u32 POS_RESULT[4]; // 0x04000620
|
||||
u16 VEC_RESULT[3]; // 0x04000630
|
||||
u8 __unused15[10];
|
||||
u8 CLIPMTX_RESULT[64]; // 0x04000640
|
||||
u8 VECMTX_RESULT[36]; // 0x04000680
|
||||
};
|
||||
typedef struct GFX3D_IOREG GFX3D_IOREG; // 0x04000320 - 0x040006A4
|
||||
|
||||
union GFX3D_Viewport
|
||||
{
|
||||
u64 value;
|
||||
|
||||
struct
|
||||
{
|
||||
s16 x;
|
||||
s16 y;
|
||||
u16 width;
|
||||
u16 height;
|
||||
};
|
||||
};
|
||||
typedef union GFX3D_Viewport GFX3D_Viewport;
|
||||
|
||||
struct POLY {
|
||||
PolygonType type; //tri or quad
|
||||
|
@ -310,7 +527,8 @@ struct POLY {
|
|||
POLYGON_ATTR attribute;
|
||||
TEXIMAGE_PARAM texParam;
|
||||
u32 texPalette; //the hardware rendering params
|
||||
u32 viewport;
|
||||
GFX3D_Viewport viewport;
|
||||
IOREG_VIEWPORT viewportLegacySave; // Exists for save state compatibility.
|
||||
float miny, maxy;
|
||||
|
||||
void setVertIndexes(int a, int b, int c, int d=-1)
|
||||
|
@ -360,12 +578,7 @@ struct POLY {
|
|||
|
||||
#define POLYLIST_SIZE 20000
|
||||
#define VERTLIST_SIZE (POLYLIST_SIZE * 4)
|
||||
|
||||
struct POLYLIST {
|
||||
POLY list[POLYLIST_SIZE];
|
||||
size_t count;
|
||||
size_t opaqueCount;
|
||||
};
|
||||
#define INDEXLIST_SIZE (POLYLIST_SIZE * 4)
|
||||
|
||||
//just a vert with a 4 float position
|
||||
struct VERT_POS4f
|
||||
|
@ -483,17 +696,6 @@ union VtxTexCoord16
|
|||
};
|
||||
typedef union VtxTexCoord16 VtxTexCoord16;
|
||||
|
||||
#define INDEXLIST_SIZE (POLYLIST_SIZE * 4)
|
||||
struct INDEXLIST {
|
||||
int list[INDEXLIST_SIZE];
|
||||
};
|
||||
|
||||
struct VIEWPORT {
|
||||
u8 x, y;
|
||||
u16 width, height;
|
||||
void decode(u32 v);
|
||||
};
|
||||
|
||||
//ok, imagine the plane that cuts diagonally across a cube such that it clips
|
||||
//out to be a hexagon. within that plane, draw a quad such that it cuts off
|
||||
//four corners of the hexagon, and you will observe a decagon
|
||||
|
@ -513,6 +715,7 @@ struct CPoly
|
|||
POLY *poly;
|
||||
VERT clipVerts[MAX_CLIPPED_VERTS];
|
||||
};
|
||||
typedef struct CPoly CPoly;
|
||||
|
||||
class GFX3D_Clipper
|
||||
{
|
||||
|
@ -536,103 +739,94 @@ public:
|
|||
//used to communicate state to the renderer
|
||||
struct GFX3D_State
|
||||
{
|
||||
GFX3D_State()
|
||||
: enableTexturing(true)
|
||||
, enableAlphaTest(true)
|
||||
, enableAlphaBlending(true)
|
||||
, enableAntialiasing(false)
|
||||
, enableEdgeMarking(false)
|
||||
, enableClearImage(false)
|
||||
, enableFog(false)
|
||||
, enableFogAlphaOnly(false)
|
||||
, shading(PolygonShadingMode_Toon)
|
||||
, alphaTestRef(0)
|
||||
, activeFlushCommand(0)
|
||||
, pendingFlushCommand(0)
|
||||
, clearDepth(DS_DEPTH15TO24(0x7FFF))
|
||||
, clearColor(0)
|
||||
, fogColor(0)
|
||||
, fogOffset(0)
|
||||
, fogShift(0)
|
||||
, invalidateToon(true)
|
||||
{
|
||||
for(u32 i=0;i<ARRAY_SIZE(shininessTable);i++)
|
||||
shininessTable[i] = 0;
|
||||
|
||||
for(u32 i=0;i<ARRAY_SIZE(u16ToonTable);i++)
|
||||
u16ToonTable[i] = 0;
|
||||
}
|
||||
|
||||
IOREG_DISP3DCNT savedDISP3DCNT;
|
||||
IOREG_DISP3DCNT DISP3DCNT;
|
||||
u8 fogShift;
|
||||
|
||||
BOOL enableTexturing, enableAlphaTest, enableAlphaBlending,
|
||||
enableAntialiasing, enableEdgeMarking, enableClearImage, enableFog, enableFogAlphaOnly;
|
||||
|
||||
u32 shading;
|
||||
|
||||
BOOL wbuffer, sortmode;
|
||||
u8 alphaTestRef;
|
||||
u32 clearColor; // Not an RGBA8888 color. This uses its own packed format.
|
||||
u32 clearDepth;
|
||||
IOREG_CLRIMAGE_OFFSET clearImageOffset;
|
||||
u32 fogColor; // Not an RGBA8888 color. This uses its own packed format.
|
||||
u16 fogOffset;
|
||||
|
||||
IOREG_SWAP_BUFFERS SWAP_BUFFERS;
|
||||
|
||||
CACHE_ALIGN u16 edgeMarkColorTable[8];
|
||||
CACHE_ALIGN u8 fogDensityTable[32];
|
||||
CACHE_ALIGN u16 toonTable16[32];
|
||||
CACHE_ALIGN u8 shininessTable[128];
|
||||
};
|
||||
typedef struct GFX3D_State GFX3D_State;
|
||||
|
||||
struct GFX3D_GeometryList
|
||||
{
|
||||
PAGE_ALIGN VERT vertList[VERTLIST_SIZE];
|
||||
PAGE_ALIGN POLY polyList[POLYLIST_SIZE];
|
||||
PAGE_ALIGN CPoly clippedPolyList[POLYLIST_SIZE];
|
||||
|
||||
size_t vertListCount;
|
||||
size_t polyCount;
|
||||
size_t polyOpaqueCount;
|
||||
size_t clippedPolyCount;
|
||||
size_t clippedPolyOpaqueCount;
|
||||
};
|
||||
typedef struct GFX3D_GeometryList GFX3D_GeometryList;
|
||||
|
||||
struct LegacyGFX3DStateSFormat
|
||||
{
|
||||
u32 enableTexturing;
|
||||
u32 enableAlphaTest;
|
||||
u32 enableAlphaBlending;
|
||||
u32 enableAntialiasing;
|
||||
u32 enableEdgeMarking;
|
||||
u32 enableClearImage;
|
||||
u32 enableFog;
|
||||
u32 enableFogAlphaOnly;
|
||||
|
||||
u32 fogShift;
|
||||
|
||||
u32 toonShadingMode;
|
||||
u32 enableWDepth;
|
||||
u32 polygonTransparentSortMode;
|
||||
u32 alphaTestRef;
|
||||
|
||||
u32 clearColor;
|
||||
u32 clearDepth;
|
||||
|
||||
u32 fogColor[4]; //for savestate compatibility as of 26-jul-09
|
||||
u32 fogOffset;
|
||||
|
||||
u16 toonTable16[32];
|
||||
u8 shininessTable[128];
|
||||
|
||||
u32 activeFlushCommand;
|
||||
u32 pendingFlushCommand;
|
||||
|
||||
u32 clearDepth;
|
||||
u32 clearColor;
|
||||
#include "PACKED.h"
|
||||
struct {
|
||||
u32 fogColor;
|
||||
u32 pad[3]; //for savestate compatibility as of 26-jul-09
|
||||
};
|
||||
#include "PACKED_END.h"
|
||||
u32 fogOffset;
|
||||
u32 fogShift;
|
||||
|
||||
bool invalidateToon;
|
||||
CACHE_ALIGN u16 u16ToonTable[32];
|
||||
u8 shininessTable[128];
|
||||
|
||||
//TODO: copy these in instead of this sloppy memory mapping
|
||||
u8 *fogDensityTable; // Alias to MMU.ARM9_REG+0x0360
|
||||
u16 *edgeMarkColorTable; // Alias to MMU.ARM9_REG+0x0330
|
||||
};
|
||||
typedef struct LegacyGFX3D_StateSFormat LegacyGFX3D_StateSFormat;
|
||||
|
||||
struct Viewer3d_State
|
||||
struct Viewer3D_State
|
||||
{
|
||||
int frameNumber;
|
||||
GFX3D_State state;
|
||||
VERT vertList[VERTLIST_SIZE];
|
||||
POLYLIST polylist;
|
||||
INDEXLIST indexlist;
|
||||
|
||||
size_t vertListCount;
|
||||
GFX3D_GeometryList gList;
|
||||
int indexList[INDEXLIST_SIZE];
|
||||
};
|
||||
typedef struct Viewer3D_State Viewer3D_State;
|
||||
|
||||
extern Viewer3d_State* viewer3d_state;
|
||||
extern Viewer3D_State viewer3D;
|
||||
|
||||
struct GFX3D
|
||||
{
|
||||
GFX3D()
|
||||
: polylist(NULL)
|
||||
, vertList(NULL)
|
||||
, render3DFrameCount(0) {
|
||||
}
|
||||
|
||||
//currently set values
|
||||
GFX3D_State state;
|
||||
|
||||
//values used for the currently-rendered frame (committed with each flush)
|
||||
GFX3D_State renderState;
|
||||
|
||||
POLYLIST *polylist;
|
||||
VERT *vertList;
|
||||
INDEXLIST indexlist;
|
||||
GFX3D_State pendingState;
|
||||
GFX3D_State appliedState;
|
||||
GFX3D_GeometryList gList[2];
|
||||
|
||||
size_t clippedPolyCount;
|
||||
size_t clippedPolyOpaqueCount;
|
||||
CPoly *clippedPolyList;
|
||||
|
||||
size_t vertListCount;
|
||||
u8 pendingListIndex;
|
||||
u8 appliedListIndex;
|
||||
u32 render3DFrameCount; // Increments when gfx3d_doFlush() is called. Resets every 60 video frames.
|
||||
};
|
||||
typedef struct GFX3D GFX3D;
|
||||
|
||||
extern GFX3D gfx3d;
|
||||
|
||||
//---------------------
|
||||
|
@ -646,12 +840,14 @@ void gfx3d_glFlush(u32 v);
|
|||
|
||||
void gfx3d_glFogColor(u32 v);
|
||||
void gfx3d_glFogOffset (u32 v);
|
||||
void gfx3d_glClearDepth(u32 v);
|
||||
template<typename T, size_t ADDROFFSET> void gfx3d_glClearDepth(const T val);
|
||||
template<typename T, size_t ADDROFFSET> void gfx3d_glClearImageOffset(const T val);
|
||||
void gfx3d_glSwapScreen(u32 screen);
|
||||
int gfx3d_GetNumPolys();
|
||||
int gfx3d_GetNumVertex();
|
||||
void gfx3d_UpdateToonTable(u8 offset, u16 val);
|
||||
void gfx3d_UpdateToonTable(u8 offset, u32 val);
|
||||
u32 gfx3d_GetNumPolys();
|
||||
u32 gfx3d_GetNumVertex();
|
||||
template<typename T> void gfx3d_UpdateEdgeMarkColorTable(const u8 offset, const T val);
|
||||
template<typename T> void gfx3d_UpdateFogTable(const u8 offset, const T val);
|
||||
template<typename T> void gfx3d_UpdateToonTable(const u8 offset, const T val);
|
||||
s32 gfx3d_GetClipMatrix (const u32 index);
|
||||
s32 gfx3d_GetDirectionalMatrix(const u32 index);
|
||||
void gfx3d_glAlphaFunc(u32 v);
|
||||
|
@ -678,6 +874,7 @@ void gfx3d_FinishLoadStateBufferRead();
|
|||
void gfx3d_ClearStack();
|
||||
|
||||
void gfx3d_parseCurrentDISP3DCNT();
|
||||
const GFX3D_IOREG& GFX3D_GetIORegisterMap();
|
||||
void ParseReg_DISP3DCNT();
|
||||
|
||||
#endif //_GFX3D_H_
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2009-2022 DeSmuME team
|
||||
Copyright (C) 2009-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -313,25 +313,25 @@ FORCEINLINE int edge_fx_fl::Step() {
|
|||
|
||||
|
||||
|
||||
static FORCEINLINE void alphaBlend(FragmentColor &dst, const FragmentColor src)
|
||||
static FORCEINLINE void alphaBlend(const bool isAlphaBlendingEnabled, const FragmentColor inSrc, FragmentColor &outDst)
|
||||
{
|
||||
if (src.a == 0)
|
||||
if (inSrc.a == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (src.a == 31 || dst.a == 0 || !gfx3d.renderState.enableAlphaBlending)
|
||||
if (inSrc.a == 31 || outDst.a == 0 || !isAlphaBlendingEnabled)
|
||||
{
|
||||
dst = src;
|
||||
outDst = inSrc;
|
||||
}
|
||||
else
|
||||
{
|
||||
const u8 alpha = src.a + 1;
|
||||
const u8 alpha = inSrc.a + 1;
|
||||
const u8 invAlpha = 32 - alpha;
|
||||
dst.r = (alpha*src.r + invAlpha*dst.r) >> 5;
|
||||
dst.g = (alpha*src.g + invAlpha*dst.g) >> 5;
|
||||
dst.b = (alpha*src.b + invAlpha*dst.b) >> 5;
|
||||
dst.a = max(src.a, dst.a);
|
||||
outDst.r = (alpha*inSrc.r + invAlpha*outDst.r) >> 5;
|
||||
outDst.g = (alpha*inSrc.g + invAlpha*outDst.g) >> 5;
|
||||
outDst.b = (alpha*inSrc.b + invAlpha*outDst.b) >> 5;
|
||||
outDst.a = max(inSrc.a, outDst.a);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -424,6 +424,8 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_shade(const PolygonMode polygonMode,
|
|||
return;
|
||||
}
|
||||
|
||||
const GFX3D_State &renderState = *this->_softRender->currentRenderState;
|
||||
|
||||
static const FragmentColor colorWhite = MakeFragmentColor(0x3F, 0x3F, 0x3F, 0x1F);
|
||||
const FragmentColor mainTexColor = (this->_currentTexture->IsSamplingEnabled()) ? this->_sample(texCoordU, texCoordV) : colorWhite;
|
||||
|
||||
|
@ -468,7 +470,7 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_shade(const PolygonMode polygonMode,
|
|||
{
|
||||
const FragmentColor toonColor = this->_softRender->toonColor32LUT[src.r >> 1];
|
||||
|
||||
if (gfx3d.renderState.shading == PolygonShadingMode_Highlight)
|
||||
if (renderState.DISP3DCNT.PolygonShading == PolygonShadingMode_Highlight)
|
||||
{
|
||||
// Tested in the "Shadows of Almia" logo in the Pokemon Ranger: Shadows of Almia title screen.
|
||||
// Also tested in Advance Wars: Dual Strike and Advance Wars: Days of Ruin when tiles highlight
|
||||
|
@ -502,6 +504,7 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_shade(const PolygonMode polygonMode,
|
|||
template<bool RENDERER> template<bool ISFRONTFACING, bool ISSHADOWPOLYGON>
|
||||
FORCEINLINE void RasterizerUnit<RENDERER>::_pixel(const POLYGON_ATTR polyAttr, const bool isTranslucent, const size_t fragmentIndex, FragmentColor &dstColor, float r, float g, float b, float invu, float invv, float z, float w)
|
||||
{
|
||||
const GFX3D_State &renderState = *this->_softRender->currentRenderState;
|
||||
FragmentColor newDstColor32;
|
||||
FragmentColor shaderOutput;
|
||||
bool isOpaquePixel;
|
||||
|
@ -522,7 +525,7 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_pixel(const POLYGON_ATTR polyAttr, c
|
|||
|
||||
// Note that an IEEE-754 single-precision float uses a 23-bit significand. Therefore, we will multiply the
|
||||
// Z-depth by a 22-bit significand for safety.
|
||||
const u32 newDepth = (gfx3d.renderState.wbuffer) ? u32floor(w * 4096.0f) : u32floor(z * 4194303.0f) << 2;
|
||||
const u32 newDepth = (renderState.SWAP_BUFFERS.DepthMode) ? u32floor(w * 4096.0f) : u32floor(z * 4194303.0f) << 2;
|
||||
|
||||
// run the depth test
|
||||
bool depthFail = false;
|
||||
|
@ -642,7 +645,7 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_pixel(const POLYGON_ATTR polyAttr, c
|
|||
dstAttributeTranslucentPolyID = polyAttr.PolygonID;
|
||||
|
||||
//alpha blending and write color
|
||||
alphaBlend(dstColor, shaderOutput);
|
||||
alphaBlend((renderState.DISP3DCNT.EnableAlphaBlending != 0), shaderOutput, dstColor);
|
||||
|
||||
dstAttributeIsFogged = (dstAttributeIsFogged && polyAttr.Fog_Enable);
|
||||
}
|
||||
|
@ -779,6 +782,7 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_drawscanline(const POLYGON_ATTR poly
|
|||
template<bool RENDERER> template<bool ISFRONTFACING, bool ISSHADOWPOLYGON>
|
||||
FORCEINLINE void RasterizerUnit<RENDERER>::_pixel_SSE2(const POLYGON_ATTR polyAttr, const bool isTranslucent, const size_t fragmentIndex, FragmentColor &dstColor, const __m128 &srcColorf, float invu, float invv, float z, float w)
|
||||
{
|
||||
const GFX3D_State &renderState = *this->_softRender->currentRenderState;
|
||||
FragmentColor newDstColor32;
|
||||
FragmentColor shaderOutput;
|
||||
bool isOpaquePixel;
|
||||
|
@ -799,7 +803,7 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_pixel_SSE2(const POLYGON_ATTR polyAt
|
|||
|
||||
// Note that an IEEE-754 single-precision float uses a 23-bit significand. Therefore, we will multiply the
|
||||
// Z-depth by a 22-bit significand for safety.
|
||||
const u32 newDepth = (gfx3d.renderState.wbuffer) ? u32floor(w * 4096.0f) : u32floor(z * 4194303.0f) << 2;
|
||||
const u32 newDepth = (renderState.SWAP_BUFFERS.DepthMode) ? u32floor(w * 4096.0f) : u32floor(z * 4194303.0f) << 2;
|
||||
|
||||
// run the depth test
|
||||
bool depthFail = false;
|
||||
|
@ -891,7 +895,7 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_pixel_SSE2(const POLYGON_ATTR polyAt
|
|||
this->_shade<ISSHADOWPOLYGON>((PolygonMode)polyAttr.Mode, newDstColor32, shaderOutput, invu * w, invv * w);
|
||||
|
||||
// handle alpha test
|
||||
if ( shaderOutput.a == 0 || (this->_softRender->currentRenderState->enableAlphaTest && shaderOutput.a < this->_softRender->currentRenderState->alphaTestRef) )
|
||||
if ( shaderOutput.a == 0 || (renderState.DISP3DCNT.EnableAlphaTest && (shaderOutput.a < renderState.alphaTestRef)) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -917,7 +921,7 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_pixel_SSE2(const POLYGON_ATTR polyAt
|
|||
dstAttributeTranslucentPolyID = polyAttr.PolygonID;
|
||||
|
||||
//alpha blending and write color
|
||||
alphaBlend(dstColor, shaderOutput);
|
||||
alphaBlend((renderState.DISP3DCNT.EnableAlphaBlending != 0), shaderOutput, dstColor);
|
||||
|
||||
dstAttributeIsFogged = (dstAttributeIsFogged && polyAttr.Fog_Enable);
|
||||
}
|
||||
|
@ -1910,21 +1914,13 @@ void SoftRasterizerRenderer::_TransformVertices()
|
|||
vert.fcolor[2] /= vertw;
|
||||
|
||||
//viewport transformation
|
||||
VIEWPORT viewport;
|
||||
viewport.decode(poly.poly->viewport);
|
||||
vert.coord[0] *= viewport.width;
|
||||
vert.coord[0] += viewport.x;
|
||||
|
||||
// The maximum viewport y-value is 191. Values above 191 need to wrap
|
||||
// around and go negative.
|
||||
//
|
||||
// Test case: The Homie Rollerz character select screen sets the y-value
|
||||
// to 253, which then wraps around to -2.
|
||||
vert.coord[1] *= viewport.height;
|
||||
vert.coord[1] += (viewport.y > 191) ? (viewport.y - 0xFF) : viewport.y;
|
||||
vert.coord[1] = 192 - vert.coord[1];
|
||||
|
||||
vert.coord[0] *= poly.poly->viewport.width;
|
||||
vert.coord[0] += poly.poly->viewport.x;
|
||||
vert.coord[0] *= wScalar;
|
||||
|
||||
vert.coord[1] *= poly.poly->viewport.height;
|
||||
vert.coord[1] += poly.poly->viewport.y;
|
||||
vert.coord[1] = 192 - vert.coord[1];
|
||||
vert.coord[1] *= hScalar;
|
||||
|
||||
//here is a hack which needs to be removed.
|
||||
|
@ -2010,7 +2006,7 @@ Render3DError SoftRasterizerRenderer::ApplyRenderingSettings(const GFX3D_State &
|
|||
return Render3D::ApplyRenderingSettings(renderState);
|
||||
}
|
||||
|
||||
Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D &engine)
|
||||
Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
|
||||
{
|
||||
// Force all threads to finish before rendering with new data
|
||||
for (size_t i = 0; i < this->_threadCount; i++)
|
||||
|
@ -2019,10 +2015,10 @@ Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D &engine)
|
|||
}
|
||||
|
||||
// Keep the current render states for later use
|
||||
this->currentRenderState = (GFX3D_State *)&engine.renderState;
|
||||
this->_clippedPolyCount = engine.clippedPolyCount;
|
||||
this->_clippedPolyOpaqueCount = engine.clippedPolyOpaqueCount;
|
||||
memcpy(this->_clippedPolyList, engine.clippedPolyList, this->_clippedPolyCount * sizeof(CPoly));
|
||||
this->currentRenderState = (GFX3D_State *)&renderState;
|
||||
this->_clippedPolyCount = renderGList.clippedPolyCount;
|
||||
this->_clippedPolyOpaqueCount = renderGList.clippedPolyOpaqueCount;
|
||||
memcpy(this->_clippedPolyList, renderGList.clippedPolyList, this->_clippedPolyCount * sizeof(CPoly));
|
||||
|
||||
const bool doMultithreadedStateSetup = (this->_threadCount >= 2);
|
||||
|
||||
|
@ -2038,16 +2034,16 @@ Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D &engine)
|
|||
}
|
||||
|
||||
// Convert the toon table colors
|
||||
ColorspaceConvertBuffer555To6665Opaque<false, false, BESwapDst>(engine.renderState.u16ToonTable, (u32 *)this->toonColor32LUT, 32);
|
||||
ColorspaceConvertBuffer555To6665Opaque<false, false, BESwapDst>(renderState.toonTable16, (u32 *)this->toonColor32LUT, 32);
|
||||
|
||||
if (this->_enableEdgeMark)
|
||||
{
|
||||
this->_UpdateEdgeMarkColorTable(this->currentRenderState->edgeMarkColorTable);
|
||||
this->_UpdateEdgeMarkColorTable(renderState.edgeMarkColorTable);
|
||||
}
|
||||
|
||||
if (this->_enableFog)
|
||||
{
|
||||
this->_UpdateFogTable(this->currentRenderState->fogDensityTable);
|
||||
this->_UpdateFogTable(renderState.fogDensityTable);
|
||||
}
|
||||
|
||||
if (doMultithreadedStateSetup)
|
||||
|
@ -2107,7 +2103,7 @@ void SoftRasterizerRenderer::_UpdateEdgeMarkColorTable(const u16 *edgeMarkColorT
|
|||
//we can do this by rendering a 3d frame and then freezing the system, but only changing the edge mark colors
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
this->_edgeMarkTable[i].color = LE_TO_LOCAL_32( COLOR555TO6665(edgeMarkColorTable[i] & 0x7FFF, (this->currentRenderState->enableAntialiasing) ? 0x10 : 0x1F) );
|
||||
this->_edgeMarkTable[i].color = LE_TO_LOCAL_32( COLOR555TO6665(edgeMarkColorTable[i] & 0x7FFF, (this->currentRenderState->DISP3DCNT.EnableAntialiasing) ? 0x10 : 0x1F) );
|
||||
|
||||
//zero 20-jun-2013 - this doesnt make any sense. at least, it should be related to the 0x8000 bit. if this is undocumented behaviour, lets write about which scenario proves it here, or which scenario is requiring this code.
|
||||
//// this seems to be the only thing that selectively disables edge marking
|
||||
|
@ -2390,7 +2386,7 @@ Render3DError SoftRasterizerRenderer::EndRender()
|
|||
this->_threadPostprocessParam[0].enableEdgeMarking = this->_enableEdgeMark;
|
||||
this->_threadPostprocessParam[0].enableFog = this->_enableFog;
|
||||
this->_threadPostprocessParam[0].fogColor = this->currentRenderState->fogColor;
|
||||
this->_threadPostprocessParam[0].fogAlphaOnly = this->currentRenderState->enableFogAlphaOnly;
|
||||
this->_threadPostprocessParam[0].fogAlphaOnly = (this->currentRenderState->DISP3DCNT.FogOnlyAlpha != 0);
|
||||
|
||||
this->RenderEdgeMarkingAndFog(this->_threadPostprocessParam[0]);
|
||||
}
|
||||
|
@ -2426,7 +2422,7 @@ Render3DError SoftRasterizerRenderer::RenderFinish()
|
|||
this->_threadPostprocessParam[i].enableEdgeMarking = this->_enableEdgeMark;
|
||||
this->_threadPostprocessParam[i].enableFog = this->_enableFog;
|
||||
this->_threadPostprocessParam[i].fogColor = this->currentRenderState->fogColor;
|
||||
this->_threadPostprocessParam[i].fogAlphaOnly = this->currentRenderState->enableFogAlphaOnly;
|
||||
this->_threadPostprocessParam[i].fogAlphaOnly = (this->currentRenderState->DISP3DCNT.FogOnlyAlpha != 0);
|
||||
|
||||
this->_task[i].execute(&SoftRasterizer_RunRenderEdgeMarkAndFog, &this->_threadPostprocessParam[i]);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2009-2022 DeSmuME team
|
||||
Copyright (C) 2009-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -176,7 +176,7 @@ protected:
|
|||
void _GetPolygonStates();
|
||||
|
||||
// Base rendering methods
|
||||
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
|
||||
virtual Render3DError RenderGeometry();
|
||||
virtual Render3DError EndRender();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2022 DeSmuME team
|
||||
Copyright (C) 2008-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -412,12 +412,12 @@ size_t Render3D::GetClippedPolyCount() const
|
|||
|
||||
Render3DError Render3D::ApplyRenderingSettings(const GFX3D_State &renderState)
|
||||
{
|
||||
this->_enableEdgeMark = (CommonSettings.GFX3D_EdgeMark) ? renderState.enableEdgeMarking : false;
|
||||
this->_enableFog = (CommonSettings.GFX3D_Fog) ? renderState.enableFog : false;
|
||||
this->_enableEdgeMark = (CommonSettings.GFX3D_EdgeMark) ? (renderState.DISP3DCNT.EnableEdgeMarking != 0) : false;
|
||||
this->_enableFog = (CommonSettings.GFX3D_Fog) ? (renderState.DISP3DCNT.EnableFog != 0) : false;
|
||||
this->_enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing;
|
||||
|
||||
this->_prevEnableTextureSampling = this->_enableTextureSampling;
|
||||
this->_enableTextureSampling = (CommonSettings.GFX3D_Texture) ? renderState.enableTexturing : false;
|
||||
this->_enableTextureSampling = (CommonSettings.GFX3D_Texture) ? (renderState.DISP3DCNT.EnableTexMapping != 0) : false;
|
||||
|
||||
this->_prevEnableTextureDeposterize = this->_enableTextureDeposterize;
|
||||
this->_enableTextureDeposterize = CommonSettings.GFX3D_Renderer_TextureDeposterize;
|
||||
|
@ -436,7 +436,7 @@ Render3DError Render3D::ApplyRenderingSettings(const GFX3D_State &renderState)
|
|||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::BeginRender(const GFX3D &engine)
|
||||
Render3DError Render3D::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
@ -579,15 +579,14 @@ Render3DError Render3D::ClearFramebuffer(const GFX3D_State &renderState)
|
|||
{
|
||||
Render3DError error = RENDER3DERROR_NOERR;
|
||||
|
||||
if (renderState.enableClearImage)
|
||||
if (renderState.DISP3DCNT.RearPlaneMode)
|
||||
{
|
||||
//the lion, the witch, and the wardrobe (thats book 1, suck it you new-school numberers)
|
||||
//uses the scroll registers in the main game engine
|
||||
const u16 *__restrict clearColorBuffer = (u16 *__restrict)MMU.texInfo.textureSlotAddr[2];
|
||||
const u16 *__restrict clearDepthBuffer = (u16 *__restrict)MMU.texInfo.textureSlotAddr[3];
|
||||
const u16 scrollBits = T1ReadWord(MMU.ARM9_REG, 0x356); //CLRIMAGE_OFFSET
|
||||
const u8 xScroll = scrollBits & 0xFF;
|
||||
const u8 yScroll = (scrollBits >> 8) & 0xFF;
|
||||
const u8 xScroll = renderState.clearImageOffset.XOffset;
|
||||
const u8 yScroll = renderState.clearImageOffset.YOffset;
|
||||
|
||||
if (xScroll == 0 && yScroll == 0)
|
||||
{
|
||||
|
@ -649,7 +648,7 @@ Render3DError Render3D::SetupTexture(const POLY &thePoly, size_t polyRenderIndex
|
|||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::SetupViewport(const u32 viewportValue)
|
||||
Render3DError Render3D::SetupViewport(const GFX3D_Viewport viewport)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
@ -688,12 +687,12 @@ Render3DError Render3D::RenderPowerOff()
|
|||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::Render(const GFX3D &engine)
|
||||
Render3DError Render3D::Render(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
|
||||
{
|
||||
Render3DError error = RENDER3DERROR_NOERR;
|
||||
this->_isPoweredOn = true;
|
||||
|
||||
const u32 clearColorSwapped = LE_TO_LOCAL_32(engine.renderState.clearColor);
|
||||
const u32 clearColorSwapped = LE_TO_LOCAL_32(renderState.clearColor);
|
||||
this->_clearColor6665.color = LE_TO_LOCAL_32( COLOR555TO6665(clearColorSwapped & 0x7FFF, (clearColorSwapped >> 16) & 0x1F) );
|
||||
|
||||
this->_clearAttributes.opaquePolyID = (clearColorSwapped >> 24) & 0x3F;
|
||||
|
@ -701,20 +700,20 @@ Render3DError Render3D::Render(const GFX3D &engine)
|
|||
//I am not sure whether it is right, though. previously this was cleared to 0, as a guess,
|
||||
//but in spiderman2 some fires with polyid 0 try to render on top of the background
|
||||
this->_clearAttributes.translucentPolyID = kUnsetTranslucentPolyID;
|
||||
this->_clearAttributes.depth = engine.renderState.clearDepth;
|
||||
this->_clearAttributes.depth = renderState.clearDepth;
|
||||
this->_clearAttributes.stencil = 0;
|
||||
this->_clearAttributes.isTranslucentPoly = 0;
|
||||
this->_clearAttributes.polyFacing = PolyFacing_Unwritten;
|
||||
this->_clearAttributes.isFogged = BIT15(clearColorSwapped);
|
||||
|
||||
error = this->BeginRender(engine);
|
||||
error = this->BeginRender(renderState, renderGList);
|
||||
if (error != RENDER3DERROR_NOERR)
|
||||
{
|
||||
this->EndRender();
|
||||
return error;
|
||||
}
|
||||
|
||||
error = this->ClearFramebuffer(engine.renderState);
|
||||
error = this->ClearFramebuffer(renderState);
|
||||
if (error != RENDER3DERROR_NOERR)
|
||||
{
|
||||
this->EndRender();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2007-2022 DeSmuME team
|
||||
Copyright (C) 2007-2023 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -198,7 +198,7 @@ protected:
|
|||
u16 *__restrict outColor16, u32 *__restrict outDepth24, u8 *__restrict outFog);
|
||||
|
||||
|
||||
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
|
||||
virtual Render3DError RenderGeometry();
|
||||
virtual Render3DError PostprocessFramebuffer();
|
||||
virtual Render3DError EndRender();
|
||||
|
@ -208,7 +208,7 @@ protected:
|
|||
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes);
|
||||
|
||||
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
|
||||
virtual Render3DError SetupViewport(const u32 viewportValue);
|
||||
virtual Render3DError SetupViewport(const GFX3D_Viewport viewport);
|
||||
|
||||
public:
|
||||
static void* operator new(size_t size);
|
||||
|
@ -232,7 +232,7 @@ public:
|
|||
|
||||
virtual Render3DError RenderPowerOff(); // Called when the renderer needs to handle a power-off condition by clearing its framebuffers.
|
||||
|
||||
virtual Render3DError Render(const GFX3D &engine); // Called when the renderer should do its job and render the current display lists.
|
||||
virtual Render3DError Render(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList); // Called whenever the 3D renderer needs to render the geometry lists.
|
||||
|
||||
virtual Render3DError RenderFinish(); // Called whenever 3D rendering needs to finish. This function should block the calling thread
|
||||
// and only release the block when 3D rendering is finished. (Before reading the 3D layer, be
|
||||
|
|
Loading…
Reference in New Issue