From 21dbca95434d18914b62287c0bb81677c030e6a3 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Mon, 16 Nov 2020 15:57:56 +0100 Subject: use proper index buffers --- src/GPU3D_OpenGL.cpp | 66 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 26 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 658b261..8b9f06c 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -74,11 +74,11 @@ typedef struct Polygon* PolyData; u32 NumIndices; - u16* Indices; + u32 IndicesOffset; GLuint PrimType; u32 NumEdgeIndices; - u16* EdgeIndices; + u32 EdgeIndicesOffset; u32 RenderKey; @@ -107,7 +107,11 @@ u32 VertexBuffer[10240 * 7]; u32 NumVertices; GLuint VertexArrayID; +GLuint IndexBufferID; u16 IndexBuffer[2048 * 40]; +u32 NumIndices, NumEdgeIndices; + +const u32 EdgeIndicesOffset = 2048 * 30; GLuint TexMemID; GLuint TexPalMemID; @@ -320,6 +324,9 @@ bool Init() glEnableVertexAttribArray(3); // attrib glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); + glGenBuffers(1, &IndexBufferID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(IndexBuffer), NULL, GL_DYNAMIC_DRAW); glGenFramebuffers(4, &FramebufferID[0]); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -563,15 +570,15 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) u32* vptr = &VertexBuffer[0]; u32 vidx = 0; - u16* iptr = &IndexBuffer[0]; - u16* eiptr = &IndexBuffer[2048*30]; + u32 iidx = 0; + u32 eidx = EdgeIndicesOffset; for (int i = 0; i < npolys; i++) { RendererPolygon* rp = &polygons[i]; Polygon* poly = rp->PolyData; - rp->Indices = iptr; + rp->IndicesOffset = iidx; rp->NumIndices = 0; u32 vidx_first = vidx; @@ -606,7 +613,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) vptr = SetupVertex(poly, j, vtx, vtxattr, vptr); - *iptr++ = vidx; + IndexBuffer[iidx++] = vidx; rp->NumIndices++; vidx++; @@ -627,9 +634,9 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) } // build a triangle - *iptr++ = vidx_first; - *iptr++ = vidx - 2; - *iptr++ = vidx - 1; + IndexBuffer[iidx++] = vidx_first; + IndexBuffer[iidx++] = vidx - 2; + IndexBuffer[iidx++] = vidx - 1; rp->NumIndices += 3; } else // quad, pentagon, etc @@ -649,9 +656,9 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) if (j >= 2) { // build a triangle - *iptr++ = vidx_first; - *iptr++ = vidx - 1; - *iptr++ = vidx; + IndexBuffer[iidx++] = vidx_first; + IndexBuffer[iidx++] = vidx - 1; + IndexBuffer[iidx++] = vidx; rp->NumIndices += 3; } @@ -743,46 +750,48 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) if (j >= 1) { // build a triangle - *iptr++ = vidx_first; - *iptr++ = vidx - 1; - *iptr++ = vidx; + IndexBuffer[iidx++] = vidx_first; + IndexBuffer[iidx++] = vidx - 1; + IndexBuffer[iidx++] = vidx; rp->NumIndices += 3; } vidx++; } - *iptr++ = vidx_first; - *iptr++ = vidx - 1; - *iptr++ = vidx_first + 1; + IndexBuffer[iidx++] = vidx_first; + IndexBuffer[iidx++] = vidx - 1; + IndexBuffer[iidx++] = vidx_first + 1; rp->NumIndices += 3; } } - rp->EdgeIndices = eiptr; + rp->EdgeIndicesOffset = eidx; rp->NumEdgeIndices = 0; u32 vidx_cur = vidx_first; for (int j = 1; j < poly->NumVertices; j++) { - *eiptr++ = vidx_cur; - *eiptr++ = vidx_cur + 1; + IndexBuffer[eidx++] = vidx_cur; + IndexBuffer[eidx++] = vidx_cur + 1; vidx_cur++; rp->NumEdgeIndices += 2; } - *eiptr++ = vidx_cur; - *eiptr++ = vidx_first; + IndexBuffer[eidx++] = vidx_cur; + IndexBuffer[eidx++] = vidx_first; rp->NumEdgeIndices += 2; } NumVertices = vidx; + NumIndices = iidx; + NumEdgeIndices = eidx; } void RenderSinglePolygon(int i) { RendererPolygon* rp = &PolygonList[i]; - glDrawElements(rp->PrimType, rp->NumIndices, GL_UNSIGNED_SHORT, rp->Indices); + glDrawElements(rp->PrimType, rp->NumIndices, GL_UNSIGNED_SHORT, (void*)(uintptr_t)(rp->IndicesOffset * 2)); } int RenderPolygonBatch(int i) @@ -803,7 +812,7 @@ int RenderPolygonBatch(int i) numindices += cur_rp->NumIndices; } - glDrawElements(primtype, numindices, GL_UNSIGNED_SHORT, rp->Indices); + glDrawElements(primtype, numindices, GL_UNSIGNED_SHORT, (void*)(uintptr_t)(rp->IndicesOffset * 2)); return numpolys; } @@ -823,7 +832,7 @@ int RenderPolygonEdgeBatch(int i) numindices += cur_rp->NumEdgeIndices; } - glDrawElements(GL_LINES, numindices, GL_UNSIGNED_SHORT, rp->EdgeIndices); + glDrawElements(GL_LINES, numindices, GL_UNSIGNED_SHORT, (void*)(uintptr_t)(rp->EdgeIndicesOffset * 2)); return numpolys; } @@ -1320,6 +1329,11 @@ void RenderFrame() glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); + // bind to access the index buffer + glBindVertexArray(VertexArrayID); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, NumIndices * 2, IndexBuffer); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, EdgeIndicesOffset * 2, NumEdgeIndices * 2, IndexBuffer + EdgeIndicesOffset); + RenderSceneChunk(0, 192); } -- cgit v1.2.3 From 50cdfd01378e72167e5ec5a5fb8c93d894afa566 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Thu, 19 Nov 2020 17:46:21 +0100 Subject: fix edge indices count --- src/GPU3D_OpenGL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 8b9f06c..ba9548e 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -784,7 +784,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) NumVertices = vidx; NumIndices = iidx; - NumEdgeIndices = eidx; + NumEdgeIndices = eidx - EdgeIndicesOffset; } void RenderSinglePolygon(int i) -- cgit v1.2.3 From a47a3fa692d8811f7aa8a2a1d97eba146424f371 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 11 Dec 2020 03:29:37 +0100 Subject: GL: align uniform-buffer size to 16-byte boundary. atleast makes RenderDoc happy. --- src/GPU3D_OpenGL.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index ba9548e..72ce647 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -53,17 +53,18 @@ GLuint CurShaderID = -1; GLuint FinalPassEdgeShader[3]; GLuint FinalPassFogShader[3]; +// std140 compliant structure struct { - float uScreenSize[2]; - u32 uDispCnt; + float uScreenSize[2]; // vec2 0 / 2 + u32 uDispCnt; // int 2 / 1 u32 __pad0; - float uToonColors[32][4]; - float uEdgeColors[8][4]; - float uFogColor[4]; - float uFogDensity[34][4]; - u32 uFogOffset; - u32 uFogShift; + float uToonColors[32][4]; // vec4[32] 4 / 128 + float uEdgeColors[8][4]; // vec4[8] 132 / 32 + float uFogColor[4]; // vec4 164 / 4 + float uFogDensity[34][4]; // float[34] 168 / 136 + u32 uFogOffset; // int 304 / 1 + u32 uFogShift; // int 305 / 1 } ShaderConfig; @@ -284,7 +285,7 @@ bool Init() glGenBuffers(1, &ShaderConfigUBO); glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(ShaderConfig), &ShaderConfig, GL_STATIC_DRAW); + glBufferData(GL_UNIFORM_BUFFER, (sizeof(ShaderConfig) + 15) & ~15, &ShaderConfig, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 0, ShaderConfigUBO); -- cgit v1.2.3 From aac843c7deddae52ce46275f8c828bcac42b4693 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 11 Dec 2020 04:38:11 +0100 Subject: GL: don't break rendering order when translucent polygons contain opaque pixels. fixes #831 (also disable edgemarking for now. it sucked anyway) --- src/GPU3D_OpenGL.cpp | 73 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 18 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 72ce647..88ae77a 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -788,11 +788,13 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) NumEdgeIndices = eidx - EdgeIndicesOffset; } -void RenderSinglePolygon(int i) +int RenderSinglePolygon(int i) { RendererPolygon* rp = &PolygonList[i]; glDrawElements(rp->PrimType, rp->NumIndices, GL_UNSIGNED_SHORT, (void*)(uintptr_t)(rp->IndicesOffset * 2)); + + return 1; } int RenderPolygonBatch(int i) @@ -867,6 +869,7 @@ void RenderSceneChunk(int y, int h) RendererPolygon* rp = &PolygonList[i]; if (rp->PolyData->IsShadowMask) { i++; continue; } + if (rp->PolyData->Translucent) { i++; continue; } if (rp->PolyData->Attr & (1<<14)) glDepthFunc(GL_LEQUAL); @@ -884,7 +887,8 @@ void RenderSceneChunk(int y, int h) } // if edge marking is enabled, mark all opaque edges - if (RenderDispCnt & (1<<5)) + // TODO BETTER EDGE MARKING!!! THIS SUCKS + /*if (RenderDispCnt & (1<<5)) { UseRenderShader(flags | RenderFlag_Edge); glLineWidth(1.5); @@ -909,7 +913,7 @@ void RenderSceneChunk(int y, int h) } glDepthMask(GL_TRUE); - } + }*/ glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX); @@ -954,15 +958,32 @@ void RenderSceneChunk(int y, int h) } else if (rp->PolyData->Translucent) { - UseRenderShader(flags | RenderFlag_Trans); + bool needopaque = ((rp->PolyData->Attr & 0x001F0000) == 0x001F0000); - if (rp->PolyData->Attr & (1<<14)) + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; + + if (polyattr & (1<<14)) glDepthFunc(GL_LEQUAL); else glDepthFunc(GL_LESS); - u32 polyattr = rp->PolyData->Attr; - u32 polyid = (polyattr >> 24) & 0x3F; + if (needopaque) + { + UseRenderShader(flags); + + glDisable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_TRUE, GL_TRUE, fogenable, GL_FALSE); + + glStencilFunc(GL_ALWAYS, polyid, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0xFF); + + RenderSinglePolygon(i); + } + + UseRenderShader(flags | RenderFlag_Trans); GLboolean transfog; if (!(polyattr & (1<<15))) transfog = fogenable; @@ -985,7 +1006,7 @@ void RenderSceneChunk(int y, int h) if (polyattr & (1<<11)) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); - i += RenderPolygonBatch(i); + i += needopaque ? RenderSinglePolygon(i) : RenderPolygonBatch(i); } else { @@ -999,7 +1020,7 @@ void RenderSceneChunk(int y, int h) if (polyattr & (1<<11)) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); - i += RenderPolygonBatch(i); + i += needopaque ? RenderSinglePolygon(i) : RenderPolygonBatch(i); } } else @@ -1040,20 +1061,37 @@ void RenderSceneChunk(int y, int h) } else if (rp->PolyData->Translucent) { - UseRenderShader(flags | RenderFlag_Trans); + bool needopaque = ((rp->PolyData->Attr & 0x001F0000) == 0x001F0000); u32 polyattr = rp->PolyData->Attr; u32 polyid = (polyattr >> 24) & 0x3F; - GLboolean transfog; - if (!(polyattr & (1<<15))) transfog = fogenable; - else transfog = GL_FALSE; - - if (rp->PolyData->Attr & (1<<14)) + if (polyattr & (1<<14)) glDepthFunc(GL_LEQUAL); else glDepthFunc(GL_LESS); + if (needopaque) + { + UseRenderShader(flags); + + glDisable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_TRUE, GL_TRUE, fogenable, GL_FALSE); + + glStencilFunc(GL_ALWAYS, polyid, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0xFF); + + RenderSinglePolygon(i); + } + + UseRenderShader(flags | RenderFlag_Trans); + + GLboolean transfog; + if (!(polyattr & (1<<15))) transfog = fogenable; + else transfog = GL_FALSE; + if (rp->PolyData->IsShadow) { glDisable(GL_BLEND); @@ -1077,8 +1115,7 @@ void RenderSceneChunk(int y, int h) if (polyattr & (1<<11)) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); - RenderSinglePolygon(i); - i++; + i += RenderSinglePolygon(i); } else { @@ -1093,7 +1130,7 @@ void RenderSceneChunk(int y, int h) if (polyattr & (1<<11)) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); - i += RenderPolygonBatch(i); + i += needopaque ? RenderSinglePolygon(i) : RenderPolygonBatch(i); } } else -- cgit v1.2.3