diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 33d4d0fb2..54cf530c6 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -963,6 +963,9 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2() delete[] ref->color4fBuffer; ref->color4fBuffer = NULL; + delete[] ref->vertIndexBuffer; + ref->vertIndexBuffer = NULL; + DestroyGeometryProgram(); DestroyPostprocessingPrograms(); DestroyVAOs(); @@ -1014,19 +1017,20 @@ Render3DError OpenGLRenderer_1_2::InitExtensions() if (error == OGLERROR_NOERR) { error = this->InitGeometryProgram(vertexShaderProgram, fragmentShaderProgram); - if (error != OGLERROR_NOERR) + if (error == OGLERROR_NOERR) { - this->isShaderSupported = false; + std::string edgeMarkVtxShaderString = std::string(EdgeMarkVtxShader_100); + std::string edgeMarkFragShaderString = std::string(EdgeMarkFragShader_100); + std::string fogVtxShaderString = std::string(FogVtxShader_100); + std::string fogFragShaderString = std::string(FogFragShader_100); + error = this->InitPostprocessingPrograms(edgeMarkVtxShaderString, edgeMarkFragShaderString, fogVtxShaderString, fogFragShaderString); + if (error != OGLERROR_NOERR) + { + INFO("OpenGL: Edge mark and fog require OpenGL v2.0 or later. These features will be disabled.\n"); + } } - - std::string edgeMarkVtxShaderString = std::string(EdgeMarkVtxShader_100); - std::string edgeMarkFragShaderString = std::string(EdgeMarkFragShader_100); - std::string fogVtxShaderString = std::string(FogVtxShader_100); - std::string fogFragShaderString = std::string(FogFragShader_100); - error = this->InitPostprocessingPrograms(edgeMarkVtxShaderString, edgeMarkFragShaderString, fogVtxShaderString, fogFragShaderString); - if (error != OGLERROR_NOERR) + else { - this->DestroyGeometryProgram(); this->isShaderSupported = false; } } @@ -1046,7 +1050,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions() this->CreateVBOs(); } - this->isPBOSupported = this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_vertex_buffer_object") && + this->isPBOSupported = this->isVBOSupported && (this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_pixel_buffer_object") || this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_pixel_buffer_object")); if (this->isPBOSupported) @@ -1648,7 +1652,11 @@ Render3DError OpenGLRenderer_1_2::InitFinalRenderStates(const std::setisShaderSupported ? NULL : new GLfloat[VERTLIST_SIZE * 4]; + OGLRef.color4fBuffer = (this->isShaderSupported) ? NULL : new GLfloat[VERTLIST_SIZE * 4]; + + // If VBOs aren't supported, then we need to create the index buffer on the + // client side so that we have a buffer to update. + OGLRef.vertIndexBuffer = (this->isVBOSupported) ? NULL : new GLushort[OGLRENDER_VERT_INDEX_BUFFER_COUNT]; return OGLERROR_NOERR; } @@ -1731,34 +1739,26 @@ Render3DError OpenGLRenderer_1_2::DestroyToonTable() return OGLERROR_NOERR; } -Render3DError OpenGLRenderer_1_2::UploadToonTable(const u16 *toonTableBuffer) -{ - glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_ToonTable); - glBindTexture(GL_TEXTURE_1D, this->ref->texToonTableID); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, toonTableBuffer); - glActiveTextureARB(GL_TEXTURE0_ARB); - - return OGLERROR_NOERR; -} - Render3DError OpenGLRenderer_1_2::UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer) { OGLRenderRef &OGLRef = *this->ref; static GLuint depth[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; + static GLuint depthStencil[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; static GLuint fogAttributes[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; static GLuint polyID[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; i++) { depth[i] = depthBuffer[i] | 0xFF000000; + depthStencil[i] = depthBuffer[i] << 8; fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000; polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000; } glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor); glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depthBuffer); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depthStencil); glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer); @@ -1815,95 +1815,13 @@ Render3DError OpenGLRenderer_1_2::ExpandFreeTextures() return OGLERROR_NOERR; } -Render3DError OpenGLRenderer_1_2::SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount) -{ - OGLRenderRef &OGLRef = *this->ref; - const size_t polyCount = polyList->count; - size_t vertIndexCount = 0; - - for(size_t i = 0; i < polyCount; i++) - { - const POLY *poly = &polyList->list[indexList->list[i]]; - const size_t polyType = poly->type; - - if (this->isShaderSupported) - { - for(size_t j = 0; j < polyType; j++) - { - const GLushort vertIndex = poly->vertIndexes[j]; - - // While we're looping through our vertices, add each vertex index to - // a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional - // vertices here to convert them to GL_TRIANGLES, which are much easier - // to work with and won't be deprecated in future OpenGL versions. - outIndexBuffer[vertIndexCount++] = vertIndex; - if (poly->vtxFormat == GFX3D_QUADS || poly->vtxFormat == GFX3D_QUAD_STRIP) - { - if (j == 2) - { - outIndexBuffer[vertIndexCount++] = vertIndex; - } - else if (j == 3) - { - outIndexBuffer[vertIndexCount++] = poly->vertIndexes[0]; - } - } - } - } - else - { - const GLfloat thePolyAlpha = (!poly->isWireframe() && poly->isTranslucent()) ? divide5bitBy31_LUT[poly->getAttributeAlpha()] : 1.0f; - - for(size_t j = 0; j < polyType; j++) - { - const GLushort vertIndex = poly->vertIndexes[j]; - const size_t colorIndex = vertIndex * 4; - - // Consolidate the vertex color and the poly alpha to our internal color buffer - // so that OpenGL can use it. - const VERT *vert = &vertList->list[vertIndex]; - OGLRef.color4fBuffer[colorIndex+0] = material_8bit_to_float[vert->color[0]]; - OGLRef.color4fBuffer[colorIndex+1] = material_8bit_to_float[vert->color[1]]; - OGLRef.color4fBuffer[colorIndex+2] = material_8bit_to_float[vert->color[2]]; - OGLRef.color4fBuffer[colorIndex+3] = thePolyAlpha; - - // While we're looping through our vertices, add each vertex index to a - // buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional - // vertices here to convert them to GL_TRIANGLES, which are much easier - // to work with and won't be deprecated in future OpenGL versions. - outIndexBuffer[vertIndexCount++] = vertIndex; - if (poly->vtxFormat == GFX3D_QUADS || poly->vtxFormat == GFX3D_QUAD_STRIP) - { - if (j == 2) - { - outIndexBuffer[vertIndexCount++] = vertIndex; - } - else if (j == 3) - { - outIndexBuffer[vertIndexCount++] = poly->vertIndexes[0]; - } - } - } - } - } - - *outIndexCount = vertIndexCount; - - return OGLERROR_NOERR; -} - -Render3DError OpenGLRenderer_1_2::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount) +Render3DError OpenGLRenderer_1_2::EnableVertexAttributes() { OGLRenderRef &OGLRef = *this->ref; if (this->isVAOSupported) { glBindVertexArray(OGLRef.vaoGeometryStatesID); - glBindBuffer(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID); - - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * vertList->count, vertList); - glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, vertIndexCount * sizeof(GLushort), indexBuffer); } else { @@ -1912,24 +1830,9 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes(const VERTLIST *vertLis glEnableVertexAttribArray(OGLVertexAttributeID_Position); glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0); glEnableVertexAttribArray(OGLVertexAttributeID_Color); - - if (this->isVBOSupported) - { - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID); - glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, vertIndexCount * sizeof(GLushort), OGLRef.vertIndexBuffer); - - glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID); - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * vertList->count, vertList); - glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); - glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); - glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color)); - } - else - { - glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), &vertList->list[0].coord); - glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), &vertList->list[0].texcoord); - glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), &vertList->list[0].color); - } + glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition); + glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrTexCoord); + glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), OGLRef.vtxPtrColor); } else { @@ -1939,23 +1842,17 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes(const VERTLIST *vertLis if (this->isVBOSupported) { - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID); - glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, vertIndexCount * sizeof(GLushort), OGLRef.vertIndexBuffer); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer); - + glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor); glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID); - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * vertList->count, vertList); - glVertexPointer(4, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); - glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); } else { - glVertexPointer(4, GL_FLOAT, sizeof(VERT), &vertList->list[0].coord); - glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), &vertList->list[0].texcoord); - glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer); + glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor); } + + glVertexPointer(4, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrPosition); + glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrTexCoord); } } @@ -1982,25 +1879,6 @@ Render3DError OpenGLRenderer_1_2::DisableVertexAttributes() glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } - - if (this->isVBOSupported) - { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - } - } - - return OGLERROR_NOERR; -} - -Render3DError OpenGLRenderer_1_2::SelectRenderingFramebuffer() -{ - OGLRenderRef &OGLRef = *this->ref; - - if (this->isMultisampledFBOSupported) - { - OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO); } return OGLERROR_NOERR; @@ -2076,8 +1954,6 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) OGLRenderRef &OGLRef = *this->ref; this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01; - this->SelectRenderingFramebuffer(); - if (this->isShaderSupported) { glUseProgram(OGLRef.programGeometryID); @@ -2087,9 +1963,6 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (engine.renderState.enableEdgeMarking) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE); glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_STENCIL_TEST); } else { @@ -2106,16 +1979,96 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) glLoadIdentity(); } - if(engine.renderState.enableAlphaBlending) + GLushort *indexPtr = NULL; + + if (this->isVBOSupported) { - glEnable(GL_BLEND); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID); + indexPtr = (GLushort *)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); } else { - glDisable(GL_BLEND); + // If VBOs aren't supported, we need to use the client-side buffers here. + OGLRef.vtxPtrPosition = &engine.vertlist->list[0].coord; + OGLRef.vtxPtrTexCoord = &engine.vertlist->list[0].texcoord; + OGLRef.vtxPtrColor = (this->isShaderSupported) ? (GLvoid *)&engine.vertlist->list[0].color : OGLRef.color4fBuffer; + indexPtr = OGLRef.vertIndexBuffer; } - glDepthMask(GL_TRUE); + size_t vertIndexCount = 0; + + for (size_t i = 0; i < engine.polylist->count; i++) + { + const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]]; + const size_t polyType = thePoly->type; + + if (this->isShaderSupported) + { + for (size_t j = 0; j < polyType; j++) + { + const GLushort vertIndex = thePoly->vertIndexes[j]; + + // While we're looping through our vertices, add each vertex index to + // a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional + // vertices here to convert them to GL_TRIANGLES, which are much easier + // to work with and won't be deprecated in future OpenGL versions. + indexPtr[vertIndexCount++] = vertIndex; + if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP) + { + if (j == 2) + { + indexPtr[vertIndexCount++] = vertIndex; + } + else if (j == 3) + { + indexPtr[vertIndexCount++] = thePoly->vertIndexes[0]; + } + } + } + } + else + { + const GLfloat thePolyAlpha = (!thePoly->isWireframe() && thePoly->isTranslucent()) ? divide5bitBy31_LUT[thePoly->getAttributeAlpha()] : 1.0f; + + for (size_t j = 0; j < polyType; j++) + { + const GLushort vertIndex = thePoly->vertIndexes[j]; + const size_t colorIndex = vertIndex * 4; + + // Consolidate the vertex color and the poly alpha to our internal color buffer + // so that OpenGL can use it. + const VERT *vert = &engine.vertlist->list[vertIndex]; + OGLRef.color4fBuffer[colorIndex+0] = material_8bit_to_float[vert->color[0]]; + OGLRef.color4fBuffer[colorIndex+1] = material_8bit_to_float[vert->color[1]]; + OGLRef.color4fBuffer[colorIndex+2] = material_8bit_to_float[vert->color[2]]; + OGLRef.color4fBuffer[colorIndex+3] = thePolyAlpha; + + // While we're looping through our vertices, add each vertex index to a + // buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional + // vertices here to convert them to GL_TRIANGLES, which are much easier + // to work with and won't be deprecated in future OpenGL versions. + indexPtr[vertIndexCount++] = vertIndex; + if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP) + { + if (j == 2) + { + indexPtr[vertIndexCount++] = vertIndex; + } + else if (j == 3) + { + indexPtr[vertIndexCount++] = thePoly->vertIndexes[0]; + } + } + } + } + } + + if (this->isVBOSupported) + { + glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * engine.vertlist->count, engine.vertlist); + } return OGLERROR_NOERR; } @@ -2138,9 +2091,19 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState, if (polyCount > 0) { - size_t vertIndexBufferCount = 0; - this->SetupVertices(vertList, polyList, indexList, OGLRef.vertIndexBuffer, &vertIndexBufferCount); - this->EnableVertexAttributes(vertList, OGLRef.vertIndexBuffer, vertIndexBufferCount); + glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); + + if(renderState.enableAlphaBlending) + { + glEnable(GL_BLEND); + } + else + { + glDisable(GL_BLEND); + } + + this->EnableVertexAttributes(); const POLY &firstPoly = polyList->list[indexList->list[0]]; u32 lastPolyAttr = firstPoly.polyAttr; @@ -2153,7 +2116,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState, this->SetupViewport(lastViewport); GLsizei vertIndexCount = 0; - GLushort *indexBufferPtr = (this->isVBOSupported) ? 0 : OGLRef.vertIndexBuffer; + GLushort *indexBufferPtr = OGLRef.vertIndexBuffer; // Enumerate through all polygons and render for (size_t i = 0; i < polyCount; i++) @@ -2240,7 +2203,10 @@ Render3DError OpenGLRenderer_1_2::EndRender(const u64 frameCount) Render3DError OpenGLRenderer_1_2::UpdateToonTable(const u16 *toonTableBuffer) { - this->UploadToonTable(toonTableBuffer); + glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_ToonTable); + glBindTexture(GL_TEXTURE_1D, this->ref->texToonTableID); + glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, toonTableBuffer); + glActiveTextureARB(GL_TEXTURE0_ARB); return OGLERROR_NOERR; } @@ -2256,44 +2222,46 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer); - if (this->isMultisampledFBOSupported && OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID) + if (this->isMultisampledFBOSupported) { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboRenderID); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID); + OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; + if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID) + { + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboRenderID); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID); + + // It might seem wasteful to be doing a separate glClear(GL_STENCIL_BUFFER_BIT) instead + // of simply blitting the stencil buffer with everything else. + // + // We do this because glBlitFramebufferEXT() for GL_STENCIL_BUFFER_BIT has been tested + // to be unsupported on ATI/AMD GPUs running in compatibility mode. So we do the separate + // glClear() for GL_STENCIL_BUFFER_BIT to keep these GPUs working. + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + + // Blit the working depth buffer + glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); + glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); + glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + // Blit the polygon ID buffer + glReadBuffer(GL_COLOR_ATTACHMENT2_EXT); + glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT); + glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + // Blit the fog buffer + glReadBuffer(GL_COLOR_ATTACHMENT3_EXT); + glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT); + glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + // Blit the color buffer. Do this last so that color attachment 0 is set to the read FBO. + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } - // Blit the color buffer - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); - - // It might seem wasteful to be doing a separate glClear(GL_STENCIL_BUFFER_BIT) instead - // of simply blitting the stencil buffer with everything else. - // - // We do this because glBlitFramebufferEXT() for GL_STENCIL_BUFFER_BIT has been tested - // to be unsupported on ATI/AMD GPUs running in compatibility mode. So we do the separate - // glClear() for GL_STENCIL_BUFFER_BIT to keep these GPUs working. - glClearStencil(0); - glClear(GL_STENCIL_BUFFER_BIT); - - // Blit the working depth buffer - glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); - glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); - glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); - - // Blit the polygon ID buffer - glReadBuffer(GL_COLOR_ATTACHMENT2_EXT); - glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT); - glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); - - // Blit the fog buffer - glReadBuffer(GL_COLOR_ATTACHMENT3_EXT); - glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT); - glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); - - // Reset framebuffer targets - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO); glDrawBuffers(4, RenderDrawList); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID); } return OGLERROR_NOERR; @@ -2301,6 +2269,16 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf Render3DError OpenGLRenderer_1_2::ClearUsingValues(const FragmentColor &clearColor, const FragmentAttributes &clearAttributes) const { + OGLRenderRef &OGLRef = *this->ref; + + if (this->isMultisampledFBOSupported) + { + OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO); + } + + glDepthMask(GL_TRUE); + if (this->isShaderSupported && this->isFBOSupported) { glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // texGColorID @@ -2344,21 +2322,6 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly) OGLRenderRef &OGLRef = *this->ref; const PolygonAttributes attr = thePoly.getAttributes(); - // Set up polygon attributes - if (this->isShaderSupported) - { - glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode); - glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE); - glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f); - glUniform1i(OGLRef.uniformPolyID, attr.polygonID); - } - else - { - // Set the texture blending mode - static const GLint oglTexBlendMode[4] = {GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE}; - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, oglTexBlendMode[attr.polygonMode]); - } - // Set up depth test mode static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL}; glDepthFunc(oglDepthFunc[attr.enableDepthTest]); @@ -2430,11 +2393,22 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly) glDepthMask(enableDepthWrite); + // Set up polygon attributes if (this->isShaderSupported) { + glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode); + glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE); + glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f); + glUniform1i(OGLRef.uniformPolyID, attr.polygonID); glUniform1i(OGLRef.uniformPolyEnableDepthWrite, enableDepthWrite); glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE); } + else + { + // Set the texture blending mode + static const GLint oglTexBlendMode[4] = {GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE}; + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, oglTexBlendMode[attr.polygonMode]); + } return OGLERROR_NOERR; } @@ -2542,7 +2516,7 @@ Render3DError OpenGLRenderer_1_2::Reset() memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i])); } - if(!this->isShaderSupported) + if (!this->isShaderSupported) { glEnable(GL_NORMALIZE); glEnable(GL_TEXTURE_1D); @@ -2550,15 +2524,26 @@ Render3DError OpenGLRenderer_1_2::Reset() glAlphaFunc(GL_GREATER, 0); glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); - + } + + if (OGLRef.color4fBuffer != NULL) + { memset(OGLRef.color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat)); } - memset(OGLRef.vertIndexBuffer, 0, OGLRENDER_VERT_INDEX_BUFFER_COUNT * sizeof(GLushort)); + if (OGLRef.vertIndexBuffer != NULL) + { + memset(OGLRef.vertIndexBuffer, 0, OGLRENDER_VERT_INDEX_BUFFER_COUNT * sizeof(GLushort)); + } + this->currTexture = NULL; this->doubleBufferIndex = 0; this->_currentPolyIndex = 0; + OGLRef.vtxPtrPosition = (GLvoid *)offsetof(VERT, coord); + OGLRef.vtxPtrTexCoord = (GLvoid *)offsetof(VERT, texcoord); + OGLRef.vtxPtrColor = (this->isShaderSupported) ? (GLvoid *)offsetof(VERT, color) : OGLRef.color4fBuffer; + return OGLERROR_NOERR; } @@ -2598,7 +2583,7 @@ Render3DError OpenGLRenderer_1_2::RenderFinish() return OGLERROR_NOERR; } -Render3DError OpenGLRenderer_1_3::UploadToonTable(const u16 *toonTableBuffer) +Render3DError OpenGLRenderer_1_3::UpdateToonTable(const u16 *toonTableBuffer) { glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_ToonTable); glBindTexture(GL_TEXTURE_1D, this->ref->texToonTableID); @@ -2613,19 +2598,21 @@ Render3DError OpenGLRenderer_1_3::UploadClearImage(const u16 *__restrict colorBu OGLRenderRef &OGLRef = *this->ref; static GLuint depth[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; + static GLuint depthStencil[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; static GLuint fogAttributes[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; static GLuint polyID[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; i++) { depth[i] = depthBuffer[i] | 0xFF000000; + depthStencil[i] = depthBuffer[i] << 8; fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000; polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000; } glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor); glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depthBuffer); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depthStencil); glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer); @@ -2672,7 +2659,11 @@ Render3DError OpenGLRenderer_1_4::InitFinalRenderStates(const std::setisShaderSupported ? NULL : new GLfloat[VERTLIST_SIZE * 4]; + OGLRef.color4fBuffer = (this->isShaderSupported) ? NULL : new GLfloat[VERTLIST_SIZE * 4]; + + // If VBOs aren't supported, then we need to create the index buffer on the + // client side so that we have a buffer to update. + OGLRef.vertIndexBuffer = (this->isVBOSupported) ? NULL : new GLushort[OGLRENDER_VERT_INDEX_BUFFER_COUNT]; return OGLERROR_NOERR; } @@ -2794,36 +2785,24 @@ Render3DError OpenGLRenderer_1_5::CreateVAOs() return OGLERROR_NOERR; } -Render3DError OpenGLRenderer_1_5::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount) +Render3DError OpenGLRenderer_1_5::EnableVertexAttributes() { OGLRenderRef &OGLRef = *this->ref; if (this->isVAOSupported) { glBindVertexArray(OGLRef.vaoGeometryStatesID); - glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); - - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer); } else { if (this->isShaderSupported) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer); - - glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList); - glEnableVertexAttribArray(OGLVertexAttributeID_Position); glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0); glEnableVertexAttribArray(OGLVertexAttributeID_Color); - - glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); - glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); - glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color)); + glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition); + glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrTexCoord); + glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), OGLRef.vtxPtrColor); } else { @@ -2831,16 +2810,12 @@ Render3DError OpenGLRenderer_1_5::EnableVertexAttributes(const VERTLIST *vertLis glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer); + glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor); glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList); - glVertexPointer(4, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); - glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); + glVertexPointer(4, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrPosition); + glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrTexCoord); } } @@ -2867,14 +2842,81 @@ Render3DError OpenGLRenderer_1_5::DisableVertexAttributes() glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } return OGLERROR_NOERR; } +Render3DError OpenGLRenderer_1_5::BeginRender(const GFX3D &engine) +{ + OGLRenderRef &OGLRef = *this->ref; + this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01; + + if (this->isShaderSupported) + { + glUseProgram(OGLRef.programGeometryID); + glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading); + glUniform1i(OGLRef.uniformStateEnableAlphaTest, (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE); + glUniform1i(OGLRef.uniformStateEnableAntialiasing, (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE); + glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (engine.renderState.enableEdgeMarking) ? GL_TRUE : GL_FALSE); + glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE); + glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]); + } + else + { + if(engine.renderState.enableAlphaTest && (engine.renderState.alphaTestRef > 0)) + { + glAlphaFunc(GL_GEQUAL, divide5bitBy31_LUT[engine.renderState.alphaTestRef]); + } + else + { + glAlphaFunc(GL_GREATER, 0); + } + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + } + + glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); + + size_t vertIndexCount = 0; + GLushort *indexPtr = (GLushort *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + + for (size_t i = 0; i < engine.polylist->count; i++) + { + const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]]; + const size_t polyType = thePoly->type; + + for (size_t j = 0; j < polyType; j++) + { + const GLushort vertIndex = thePoly->vertIndexes[j]; + + // While we're looping through our vertices, add each vertex index to + // a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional + // vertices here to convert them to GL_TRIANGLES, which are much easier + // to work with and won't be deprecated in future OpenGL versions. + indexPtr[vertIndexCount++] = vertIndex; + if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP) + { + if (j == 2) + { + indexPtr[vertIndexCount++] = vertIndex; + } + else if (j == 3) + { + indexPtr[vertIndexCount++] = thePoly->vertIndexes[0]; + } + } + } + } + + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * engine.vertlist->count, engine.vertlist); + + return OGLERROR_NOERR; +} + Render3DError OpenGLRenderer_1_5::ReadBackPixels() { const size_t i = this->doubleBufferIndex; @@ -3044,6 +3086,9 @@ Render3DError OpenGLRenderer_2_0::InitFinalRenderStates(const std::setcount; - size_t vertIndexCount = 0; - - for(size_t i = 0; i < polyCount; i++) - { - const POLY *poly = &polyList->list[indexList->list[i]]; - const size_t polyType = poly->type; - - for(size_t j = 0; j < polyType; j++) - { - const GLushort vertIndex = poly->vertIndexes[j]; - - // While we're looping through our vertices, add each vertex index to - // a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional - // vertices here to convert them to GL_TRIANGLES, which are much easier - // to work with and won't be deprecated in future OpenGL versions. - outIndexBuffer[vertIndexCount++] = vertIndex; - if (poly->vtxFormat == GFX3D_QUADS || poly->vtxFormat == GFX3D_QUAD_STRIP) - { - if (j == 2) - { - outIndexBuffer[vertIndexCount++] = vertIndex; - } - else if (j == 3) - { - outIndexBuffer[vertIndexCount++] = poly->vertIndexes[0]; - } - } - } - } - - *outIndexCount = vertIndexCount; - - return OGLERROR_NOERR; -} - -Render3DError OpenGLRenderer_2_0::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount) +Render3DError OpenGLRenderer_2_0::EnableVertexAttributes() { OGLRenderRef &OGLRef = *this->ref; if (this->isVAOSupported) { glBindVertexArray(OGLRef.vaoGeometryStatesID); - glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); - - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer); } else { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer); - - glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList); - glEnableVertexAttribArray(OGLVertexAttributeID_Position); glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0); glEnableVertexAttribArray(OGLVertexAttributeID_Color); - - glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); - glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); - glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color)); + glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition); + glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrTexCoord); + glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), OGLRef.vtxPtrColor); } return OGLERROR_NOERR; @@ -3370,9 +3365,6 @@ Render3DError OpenGLRenderer_2_0::DisableVertexAttributes() glDisableVertexAttribArray(OGLVertexAttributeID_Position); glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0); glDisableVertexAttribArray(OGLVertexAttributeID_Color); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } return OGLERROR_NOERR; @@ -3383,8 +3375,7 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine) OGLRenderRef &OGLRef = *this->ref; this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01; - this->SelectRenderingFramebuffer(); - + // Setup render states glUseProgram(OGLRef.programGeometryID); glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading); glUniform1i(OGLRef.uniformStateEnableAlphaTest, (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE); @@ -3393,19 +3384,42 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine) glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE); glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]); - glEnable(GL_DEPTH_TEST); - glEnable(GL_STENCIL_TEST); + glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); - if(engine.renderState.enableAlphaBlending) + size_t vertIndexCount = 0; + GLushort *indexPtr = (GLushort *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + + for (size_t i = 0; i < engine.polylist->count; i++) { - glEnable(GL_BLEND); - } - else - { - glDisable(GL_BLEND); + const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]]; + const size_t polyType = thePoly->type; + + for (size_t j = 0; j < polyType; j++) + { + const GLushort vertIndex = thePoly->vertIndexes[j]; + + // While we're looping through our vertices, add each vertex index to + // a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional + // vertices here to convert them to GL_TRIANGLES, which are much easier + // to work with and won't be deprecated in future OpenGL versions. + indexPtr[vertIndexCount++] = vertIndex; + if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP) + { + if (j == 2) + { + indexPtr[vertIndexCount++] = vertIndex; + } + else if (j == 3) + { + indexPtr[vertIndexCount++] = thePoly->vertIndexes[0]; + } + } + } } - glDepthMask(GL_TRUE); + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * engine.vertlist->count, engine.vertlist); return OGLERROR_NOERR; } @@ -3574,12 +3588,6 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly) OGLRenderRef &OGLRef = *this->ref; const PolygonAttributes attr = thePoly.getAttributes(); - // Set up polygon attributes - glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode); - glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE); - glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f); - glUniform1i(OGLRef.uniformPolyID, attr.polygonID); - // Set up depth test mode static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL}; glDepthFunc(oglDepthFunc[attr.enableDepthTest]); @@ -3650,6 +3658,12 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly) } glDepthMask(enableDepthWrite); + + // Set up polygon attributes + glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode); + glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE); + glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f); + glUniform1i(OGLRef.uniformPolyID, attr.polygonID); glUniform1i(OGLRef.uniformPolyEnableDepthWrite, enableDepthWrite); glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE); diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 92be910fe..ac63e2270 100644 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -280,7 +280,7 @@ EXTERNOGLEXT(PFNGLTEXBUFFERPROC, glTexBuffer) // Core in v3.1 #define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION 0 #define OGLRENDER_MAX_MULTISAMPLES 16 -#define OGLRENDER_VERT_INDEX_BUFFER_COUNT 131072 +#define OGLRENDER_VERT_INDEX_BUFFER_COUNT (POLYLIST_SIZE * 6) enum OGLVertexAttributeID { @@ -477,7 +477,12 @@ struct OGLRenderRef // Client-side Buffers GLfloat *color4fBuffer; - CACHE_ALIGN GLushort vertIndexBuffer[OGLRENDER_VERT_INDEX_BUFFER_COUNT]; + GLushort *vertIndexBuffer; + + // Vertex Attributes Pointers + GLvoid *vtxPtrPosition; + GLvoid *vtxPtrTexCoord; + GLvoid *vtxPtrColor; }; struct GFX3D_State; @@ -580,15 +585,12 @@ protected: virtual Render3DError InitGeometryProgramShaderLocations() = 0; virtual Render3DError CreateToonTable() = 0; virtual Render3DError DestroyToonTable() = 0; - virtual Render3DError UploadToonTable(const u16 *toonTableBuffer) = 0; virtual Render3DError UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer) = 0; virtual void GetExtensionSet(std::set *oglExtensionSet) = 0; virtual Render3DError ExpandFreeTextures() = 0; - virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount) = 0; - virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount) = 0; + virtual Render3DError EnableVertexAttributes() = 0; virtual Render3DError DisableVertexAttributes() = 0; - virtual Render3DError SelectRenderingFramebuffer() = 0; virtual Render3DError DownsampleFBO() = 0; virtual Render3DError ReadBackPixels() = 0; @@ -641,15 +643,12 @@ protected: virtual Render3DError CreateToonTable(); virtual Render3DError DestroyToonTable(); - virtual Render3DError UploadToonTable(const u16 *toonTableBuffer); virtual Render3DError UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer); virtual void GetExtensionSet(std::set *oglExtensionSet); virtual Render3DError ExpandFreeTextures(); - virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount); - virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount); + virtual Render3DError EnableVertexAttributes(); virtual Render3DError DisableVertexAttributes(); - virtual Render3DError SelectRenderingFramebuffer(); virtual Render3DError DownsampleFBO(); virtual Render3DError ReadBackPixels(); @@ -681,8 +680,10 @@ public: class OpenGLRenderer_1_3 : public OpenGLRenderer_1_2 { protected: - virtual Render3DError UploadToonTable(const u16 *toonTableBuffer); virtual Render3DError UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer); + +public: + virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer); }; class OpenGLRenderer_1_4 : public OpenGLRenderer_1_3 @@ -700,8 +701,9 @@ protected: virtual void DestroyPBOs(); virtual Render3DError CreateVAOs(); - virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount); + virtual Render3DError EnableVertexAttributes(); virtual Render3DError DisableVertexAttributes(); + virtual Render3DError BeginRender(const GFX3D &engine); virtual Render3DError ReadBackPixels(); public: @@ -722,8 +724,7 @@ protected: virtual Render3DError InitFogProgramShaderLocations(); virtual Render3DError DestroyPostprocessingPrograms(); - virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount); - virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount); + virtual Render3DError EnableVertexAttributes(); virtual Render3DError DisableVertexAttributes(); virtual Render3DError BeginRender(const GFX3D &engine); diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 5235fe721..13e26d3d0 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -990,17 +990,9 @@ void OpenGLRenderer_3_2::GetExtensionSet(std::set *oglExtensionSet) } } -Render3DError OpenGLRenderer_3_2::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount) +Render3DError OpenGLRenderer_3_2::EnableVertexAttributes() { - OGLRenderRef &OGLRef = *this->ref; - - glBindVertexArray(OGLRef.vaoGeometryStatesID); - glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); - - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer); - + glBindVertexArray(this->ref->vaoGeometryStatesID); return OGLERROR_NOERR; } @@ -1010,17 +1002,6 @@ Render3DError OpenGLRenderer_3_2::DisableVertexAttributes() return OGLERROR_NOERR; } -Render3DError OpenGLRenderer_3_2::SelectRenderingFramebuffer() -{ - OGLRenderRef &OGLRef = *this->ref; - - OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; - glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO); - glDrawBuffers(4, RenderDrawList); - - return OGLERROR_NOERR; -} - Render3DError OpenGLRenderer_3_2::DownsampleFBO() { OGLRenderRef &OGLRef = *this->ref; @@ -1141,13 +1122,19 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine) // Do per-poly setup glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_PolyStates); glBindTexture(GL_TEXTURE_BUFFER, OGLRef.texPolyStatesID); + + glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); glBindBuffer(GL_TEXTURE_BUFFER, OGLRef.tboPolyStatesID); + size_t vertIndexCount = 0; + GLushort *indexPtr = (GLushort *)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, engine.polylist->count * 6 * sizeof(GLushort), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); OGLPolyStates *polyStates = (OGLPolyStates *)glMapBufferRange(GL_TEXTURE_BUFFER, 0, engine.polylist->count * sizeof(OGLPolyStates), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); for (size_t i = 0; i < engine.polylist->count; i++) { const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]]; + const size_t polyType = thePoly->type; PolygonAttributes polyAttr = thePoly->getAttributes(); PolygonTexParams texParams = thePoly->getTexParams(); @@ -1155,34 +1142,41 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine) polyStates[i].enableFog = (polyAttr.enableRenderFog) ? GL_TRUE : GL_FALSE; polyStates[i].enableDepthWrite = ((!polyAttr.isTranslucent || polyAttr.enableAlphaDepthWrite) && !(polyAttr.polygonMode == 3 && polyAttr.polygonID == 0)) ? GL_TRUE : GL_FALSE; polyStates[i].setNewDepthForTranslucent = (polyAttr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE; - polyStates[i].polyAlpha = (!polyAttr.isWireframe && polyAttr.isTranslucent) ? polyAttr.alpha : 0x1F; polyStates[i].polyMode = polyAttr.polygonMode; polyStates[i].polyID = polyAttr.polygonID; polyStates[i].texSizeS = texParams.sizeS; polyStates[i].texSizeT = texParams.sizeT; + + for (size_t j = 0; j < polyType; j++) + { + const GLushort vertIndex = thePoly->vertIndexes[j]; + + // While we're looping through our vertices, add each vertex index to + // a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional + // vertices here to convert them to GL_TRIANGLES, which are much easier + // to work with and won't be deprecated in future OpenGL versions. + indexPtr[vertIndexCount++] = vertIndex; + if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP) + { + if (j == 2) + { + indexPtr[vertIndexCount++] = vertIndex; + } + else if (j == 3) + { + indexPtr[vertIndexCount++] = thePoly->vertIndexes[0]; + } + } + } } + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); glUnmapBuffer(GL_TEXTURE_BUFFER); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * engine.vertlist->count, engine.vertlist); - // Set up remaining framebuffer states - this->SelectRenderingFramebuffer(); glUseProgram(OGLRef.programGeometryID); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_STENCIL_TEST); - - if(engine.renderState.enableAlphaBlending) - { - glEnable(GL_BLEND); - } - else - { - glDisable(GL_BLEND); - } - - glDepthMask(GL_TRUE); - + return OGLERROR_NOERR; } @@ -1253,16 +1247,12 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer); + OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID) { glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID); - // Blit the color buffer - glReadBuffer(GL_COLOR_ATTACHMENT0); - glDrawBuffer(GL_COLOR_ATTACHMENT0); - glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - // Blit the working depth buffer glReadBuffer(GL_COLOR_ATTACHMENT1); glDrawBuffer(GL_COLOR_ATTACHMENT1); @@ -1278,17 +1268,26 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf glDrawBuffer(GL_COLOR_ATTACHMENT3); glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); - // Reset framebuffer targets + // Blit the color buffer. Do this last so that color attachment 0 is set to the read FBO. glReadBuffer(GL_COLOR_ATTACHMENT0); - glDrawBuffers(4, RenderDrawList); - glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); } + glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO); + glDrawBuffers(4, RenderDrawList); + return OGLERROR_NOERR; } Render3DError OpenGLRenderer_3_2::ClearUsingValues(const FragmentColor &clearColor, const FragmentAttributes &clearAttributes) const { + OGLRenderRef &OGLRef = *this->ref; + OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; + glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO); + glDrawBuffers(4, RenderDrawList); + glDepthMask(GL_TRUE); + const GLfloat oglColor[4] = {divide5bitBy31_LUT[clearColor.r], divide5bitBy31_LUT[clearColor.g], divide5bitBy31_LUT[clearColor.b], divide5bitBy31_LUT[clearColor.a]}; const GLfloat oglDepth[4] = {(GLfloat)(clearAttributes.depth & 0x000000FF)/255.0f, (GLfloat)((clearAttributes.depth >> 8) & 0x000000FF)/255.0f, (GLfloat)((clearAttributes.depth >> 16) & 0x000000FF)/255.0f, 1.0}; const GLfloat oglPolyID[4] = {(GLfloat)clearAttributes.opaquePolyID/63.0f, 0.0, 0.0, 1.0}; @@ -1309,10 +1308,8 @@ void OpenGLRenderer_3_2::SetPolygonIndex(const size_t index) glUniform1i(this->ref->uniformPolyStateIndex, index); } - Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly) { - //OGLRenderRef &OGLRef = *this->ref; const PolygonAttributes attr = thePoly.getAttributes(); // Set up depth test mode diff --git a/desmume/src/OGLRender_3_2.h b/desmume/src/OGLRender_3_2.h index e4ac9f8aa..45370e23e 100644 --- a/desmume/src/OGLRender_3_2.h +++ b/desmume/src/OGLRender_3_2.h @@ -78,9 +78,8 @@ protected: virtual void DestroyGeometryProgram(); virtual void GetExtensionSet(std::set *oglExtensionSet); - virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount); + virtual Render3DError EnableVertexAttributes(); virtual Render3DError DisableVertexAttributes(); - virtual Render3DError SelectRenderingFramebuffer(); virtual Render3DError DownsampleFBO(); virtual Render3DError BeginRender(const GFX3D &engine); virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias); diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index beefdf696..1ffdd2163 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -485,7 +485,7 @@ struct POLY { void load(EMUFILE* is); }; -#define POLYLIST_SIZE 100000 +#define POLYLIST_SIZE 20000 struct POLYLIST { POLY list[POLYLIST_SIZE]; int count; @@ -553,15 +553,15 @@ struct VERT { void load(EMUFILE* is); }; -#define VERTLIST_SIZE 400000 -//#define VERTLIST_SIZE 10000 +#define VERTLIST_SIZE (POLYLIST_SIZE * 4) struct VERTLIST { VERT list[VERTLIST_SIZE]; int count; }; +#define INDEXLIST_SIZE (POLYLIST_SIZE * 4) struct INDEXLIST { - int list[POLYLIST_SIZE]; + int list[INDEXLIST_SIZE]; }; diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index d5e5c496b..0d1117835 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -25,7 +25,7 @@ #include "MMU.h" #include "texcache.h" -static CACHE_ALIGN u32 dsDepthToD24S8_LUT[32768] = {0}; +static CACHE_ALIGN u32 dsDepthToD24_LUT[32768] = {0}; int cur3DCore = GPU3D_NULL; GPU3DInterface gpu3DNull = { @@ -107,7 +107,7 @@ Render3D::Render3D() { for (size_t i = 0; i < 32768; i++) { - dsDepthToD24S8_LUT[i] = (u32)DS_DEPTH15TO24(i) << 8; + dsDepthToD24_LUT[i] = (u32)DS_DEPTH15TO24(i); } needTableInit = false; @@ -195,7 +195,7 @@ Render3DError Render3D::ClearFramebuffer(const GFX3D_State &renderState) //this is tested quite well in the sonic chronicles main map mode //where depth values are used for trees etc you can walk behind - this->clearImageDepthBuffer[dd] = dsDepthToD24S8_LUT[clearDepthBuffer[adr] & 0x7FFF]; + this->clearImageDepthBuffer[dd] = dsDepthToD24_LUT[clearDepthBuffer[adr] & 0x7FFF]; this->clearImageFogBuffer[dd] = BIT15(clearDepthBuffer[adr]); this->clearImagePolyIDBuffer[dd] = clearFragment.opaquePolyID;