OpenGL Renderer: Use the fixed-point vertex list data instead of the floating-point based one, alongside other tune-ups.

- To determine polygon facing, use GFX3D's CPoly.isPolyBackFacing instead of using GLSL's gl_FrontFacing. This eases OpenGL version requirements and improves older GPU compatibility a little.
- Also fix a bug where GPUs that support FBOs, but not shaders, were unable to read out their framebuffers properly.
This commit is contained in:
rogerman 2023-02-24 13:49:07 -08:00
parent 37683a708e
commit fac70ce98b
4 changed files with 191 additions and 134 deletions

View File

@ -339,11 +339,11 @@ void main() \n\
mat2 texScaleMtx = mat2( vec2(polyTexScale.x, 0.0), \n\
vec2( 0.0, polyTexScale.y)); \n\
\n\
vtxTexCoord = texScaleMtx * inTexCoord0; \n\
vtxTexCoord = (texScaleMtx * inTexCoord0) / 16.0; \n\
vtxColor = vec4(inColor / 63.0, polyAlpha); \n\
isPolyDrawable = ((polyMode != 3) || polyDrawShadow) ? 1.0 : -1.0;\n\
\n\
gl_Position = inPosition;\n\
gl_Position = inPosition / 4096.0;\n\
} \n\
"};
@ -367,20 +367,21 @@ uniform bool polyEnableTexture;\n\
uniform bool polyEnableFog;\n\
uniform bool texDrawOpaque;\n\
uniform bool texSingleBitAlpha;\n\
uniform bool polyIsBackFacing;\n\
\n\
uniform bool drawModeDepthEqualsTest;\n\
uniform bool polyDrawShadow;\n\
uniform float polyDepthOffset;\n\
\n\
#if USE_DEPTH_LEQUAL_POLYGON_FACING && !DRAW_MODE_OPAQUE\n\
uniform sampler2D inBackFacing;\n\
uniform sampler2D inDstBackFacing;\n\
#endif\n\
\n\
void main()\n\
{\n\
#if USE_DEPTH_LEQUAL_POLYGON_FACING && !DRAW_MODE_OPAQUE\n\
bool isOpaqueDstBackFacing = bool( texture2D(inBackFacing, vec2(gl_FragCoord.x/FRAMEBUFFER_SIZE_X, gl_FragCoord.y/FRAMEBUFFER_SIZE_Y)).r );\n\
if (drawModeDepthEqualsTest && (!gl_FrontFacing || !isOpaqueDstBackFacing))\n\
bool isOpaqueDstBackFacing = bool( texture2D(inDstBackFacing, vec2(gl_FragCoord.x/FRAMEBUFFER_SIZE_X, gl_FragCoord.y/FRAMEBUFFER_SIZE_Y)).r );\n\
if (drawModeDepthEqualsTest && (polyIsBackFacing || !isOpaqueDstBackFacing))\n\
{\n\
discard;\n\
}\n\
@ -445,7 +446,7 @@ void main()\n\
gl_FragData[ATTACHMENT_FOG_ATTRIBUTES] = (isPolyDrawable > 0.0) ? vec4( float(polyEnableFog), 0.0, 0.0, float((newFragColor.a > 0.999) ? 1.0 : 0.5) ) : vec4(0.0, 0.0, 0.0, 0.0);\n\
#endif\n\
#if DRAW_MODE_OPAQUE\n\
gl_FragData[ATTACHMENT_WORKING_BUFFER] = vec4(float(!gl_FrontFacing), 0.0, 0.0, 1.0);\n\
gl_FragData[ATTACHMENT_WORKING_BUFFER] = vec4(float(polyIsBackFacing), 0.0, 0.0, 1.0);\n\
#endif\n\
\n\
#if USE_NDS_DEPTH_CALCULATION || ENABLE_FOG\n\
@ -1796,7 +1797,7 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLY *rawPolyList, const
if (lastPolyAttr.value != rawPoly.attribute.value)
{
lastPolyAttr = rawPoly.attribute;
this->SetupPolygon(rawPoly, (DRAWMODE != OGLPolyDrawMode_DrawOpaquePolys), (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass));
this->SetupPolygon(rawPoly, (DRAWMODE != OGLPolyDrawMode_DrawOpaquePolys), (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass), clippedPoly.isPolyBackFacing);
}
// Set up the texture if it changed
@ -2350,7 +2351,13 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
_pixelReadNeedsFinish = false;
delete[] ref->color4fBuffer;
free_aligned(ref->position4fBuffer);
ref->position4fBuffer = NULL;
free_aligned(ref->texCoord2fBuffer);
ref->texCoord2fBuffer = NULL;
free_aligned(ref->color4fBuffer);
ref->color4fBuffer = NULL;
if (this->isShaderSupported)
@ -2439,14 +2446,6 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
}
}
this->isVAOSupported = this->isVBOSupported &&
(this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_vertex_array_object") ||
this->IsExtensionPresent(&oglExtensionSet, "GL_APPLE_vertex_array_object"));
if (this->isVAOSupported)
{
this->CreateVAOs();
}
this->isPBOSupported = this->isVBOSupported &&
(this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_pixel_buffer_object") ||
this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_pixel_buffer_object"));
@ -2604,6 +2603,20 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
{
return error;
}
// If shaders aren't available, we need to take care of the vertex data format
// conversion on the CPU instead of on the GPU using these client-side buffers.
OGLRef.position4fBuffer = (GLfloat *)malloc_alignedPage(VERTLIST_SIZE * sizeof(GLfloat) * 4);
OGLRef.texCoord2fBuffer = (GLfloat *)malloc_alignedPage(VERTLIST_SIZE * sizeof(GLfloat) * 2);
OGLRef.color4fBuffer = (GLfloat *)malloc_alignedPage(VERTLIST_SIZE * sizeof(GLfloat) * 4);
}
this->isVAOSupported = this->isVBOSupported &&
(this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_vertex_array_object") ||
this->IsExtensionPresent(&oglExtensionSet, "GL_APPLE_vertex_array_object"));
if (this->isVAOSupported)
{
this->CreateVAOs();
}
// Set rendering support flags based on driver features.
@ -2613,8 +2626,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
this->_deviceInfo.isFogSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported;
this->_deviceInfo.isTextureSmoothingSupported = this->isShaderSupported;
// We're requiring OpenGL v2.1 for this feature because it relies on gl_FrontFacing, which may not be supported on v2.0 drivers.
this->_isDepthLEqualPolygonFacingSupported = this->IsVersionSupported(2, 1, 0) && this->isShaderSupported && this->isVBOSupported && this->isFBOSupported;
this->_isDepthLEqualPolygonFacingSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported;
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
@ -2632,7 +2644,7 @@ Render3DError OpenGLRenderer_1_2::CreateVBOs()
glGenBuffersARB(1, &OGLRef.vboPostprocessVtxID);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, VERTLIST_SIZE * sizeof(VERT), NULL, GL_STREAM_DRAW_ARB);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, VERTLIST_SIZE * sizeof(NDSVertex), NULL, GL_STREAM_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(OGLRef.vertIndexBuffer), NULL, GL_STREAM_DRAW_ARB);
@ -2703,25 +2715,48 @@ Render3DError OpenGLRenderer_1_2::CreateVAOs()
glGenVertexArrays(1, &OGLRef.vaoPostprocessStatesID);
glBindVertexArray(OGLRef.vaoGeometryStatesID);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID);
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_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
if (this->isShaderSupported)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, position));
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, texCoord));
glVertexAttribPointer(OGLVertexAttributeID_Color, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, color));
}
else
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(4, GL_FLOAT, 0, OGLRef.position4fBuffer);
glTexCoordPointer(2, GL_FLOAT, 0, OGLRef.texCoord2fBuffer);
glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer);
}
glBindVertexArray(0);
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboPostprocessVtxID);
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glVertexAttribPointer(OGLVertexAttributeID_Position, 2, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)(sizeof(GLfloat) * 8));
if (this->isShaderSupported)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboPostprocessVtxID);
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glVertexAttribPointer(OGLVertexAttributeID_Position, 2, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)(sizeof(GLfloat) * 8));
}
else
{
// Do nothing. Framebuffer post-processing requires shaders.
}
glBindVertexArray(0);
@ -2822,6 +2857,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
// Set up FBOs
glGenFramebuffersEXT(1, &OGLRef.fboClearImageID);
glGenFramebuffersEXT(1, &OGLRef.fboFramebufferFlipID);
glGenFramebuffersEXT(1, &OGLRef.fboRenderID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboClearImageID);
@ -2838,6 +2874,18 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
return OGLERROR_FBO_CREATE_ERROR;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboFramebufferFlipID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_WORKING_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{
INFO("OpenGL: Failed to create FBOs!\n");
this->DestroyFBOs();
return OGLERROR_FBO_CREATE_ERROR;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_POLYID_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGPolyID, 0);
@ -2874,6 +2922,7 @@ void OpenGLRenderer_1_2::DestroyFBOs()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
glDeleteFramebuffersEXT(1, &OGLRef.fboFramebufferFlipID);
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
@ -2884,6 +2933,7 @@ void OpenGLRenderer_1_2::DestroyFBOs()
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
OGLRef.fboClearImageID = 0;
OGLRef.fboFramebufferFlipID = 0;
OGLRef.fboRenderID = 0;
this->isFBOSupported = false;
@ -3049,7 +3099,7 @@ Render3DError OpenGLRenderer_1_2::CreateGeometryPrograms()
std::stringstream shaderFlags;
shaderFlags << "#define USE_TEXTURE_SMOOTHING " << ((this->_enableTextureSmoothing) ? 1 : 0) << "\n";
shaderFlags << "#define USE_NDS_DEPTH_CALCULATION " << ((this->_emulateNDSDepthCalculation) ? 1 : 0) << "\n";
shaderFlags << "#define USE_DEPTH_LEQUAL_POLYGON_FACING " << ((this->_emulateDepthLEqualPolygonFacing && this->IsVersionSupported(2, 1, 0) && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n";
shaderFlags << "#define USE_DEPTH_LEQUAL_POLYGON_FACING " << ((this->_emulateDepthLEqualPolygonFacing && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n";
shaderFlags << "\n";
shaderFlags << "#define ENABLE_W_DEPTH " << ((programFlags.EnableWDepth) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_ALPHA_TEST " << ((programFlags.EnableAlphaTest) ? "true\n" : "false\n");
@ -3057,7 +3107,7 @@ Render3DError OpenGLRenderer_1_2::CreateGeometryPrograms()
shaderFlags << "#define TOON_SHADING_MODE " << ((programFlags.ToonShadingMode) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_FOG " << ((programFlags.EnableFog && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_EDGE_MARK " << ((programFlags.EnableEdgeMark && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n";
shaderFlags << "#define DRAW_MODE_OPAQUE " << ((programFlags.OpaqueDrawMode && this->IsVersionSupported(2, 1, 0) && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n";
shaderFlags << "#define DRAW_MODE_OPAQUE " << ((programFlags.OpaqueDrawMode && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n";
shaderFlags << "\n";
shaderFlags << "#define ATTACHMENT_WORKING_BUFFER " << GeometryAttachmentWorkingBuffer[programFlags.DrawBuffersMode] << "\n";
shaderFlags << "#define ATTACHMENT_POLY_ID " << GeometryAttachmentPolyID[programFlags.DrawBuffersMode] << "\n";
@ -3103,7 +3153,7 @@ Render3DError OpenGLRenderer_1_2::CreateGeometryPrograms()
if (this->_emulateDepthLEqualPolygonFacing && this->_isDepthLEqualPolygonFacingSupported && !programFlags.OpaqueDrawMode)
{
const GLint uniformTexBackfacing = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "inBackFacing");
const GLint uniformTexBackfacing = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "inDstBackFacing");
glUniform1i(uniformTexBackfacing, OGLTextureUnitID_FinalColor);
}
@ -3122,6 +3172,7 @@ Render3DError OpenGLRenderer_1_2::CreateGeometryPrograms()
OGLRef.uniformTexDrawOpaque[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "texDrawOpaque");
OGLRef.uniformDrawModeDepthEqualsTest[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "drawModeDepthEqualsTest");
OGLRef.uniformPolyIsBackFacing[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyIsBackFacing");
OGLRef.uniformPolyDrawShadow[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyDrawShadow");
OGLRef.uniformPolyDepthOffset[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyDepthOffset");
}
@ -3658,12 +3709,6 @@ Render3DError OpenGLRenderer_1_2::InitFinalRenderStates(const std::set<std::stri
// Mirrored Repeat Mode Support
OGLRef.stateTexMirroredRepeat = (isTexMirroredRepeatSupported) ? GL_MIRRORED_REPEAT : GL_REPEAT;
// Map the vertex list's colors with 4 floats per color. This is being done
// because OpenGL needs 4-colors per vertex to support translucency. (The DS
// uses 3-colors per vertex, and adds alpha through the poly, so we can't
// simply reference the colors+alpha from just the vertices by themselves.)
OGLRef.color4fBuffer = (this->isShaderSupported) ? NULL : new GLfloat[VERTLIST_SIZE * 4];
return OGLERROR_NOERR;
}
@ -3828,29 +3873,18 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glEnableVertexAttribArray(OGLVertexAttributeID_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_FALSE, sizeof(VERT), OGLRef.vtxPtrColor);
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, position));
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, texCoord));
glVertexAttribPointer(OGLVertexAttributeID_Color, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, color));
}
else
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
if (this->isVBOSupported)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
}
else
{
glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor);
}
glVertexPointer(4, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrPosition);
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrTexCoord);
glVertexPointer(4, GL_FLOAT, 0, OGLRef.position4fBuffer);
glTexCoordPointer(2, GL_FLOAT, 0, OGLRef.texCoord2fBuffer);
glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer);
}
}
@ -3874,8 +3908,8 @@ Render3DError OpenGLRenderer_1_2::DisableVertexAttributes()
else
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
}
@ -4130,20 +4164,16 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
{
// Just flips the framebuffer in Y to match the coordinates of OpenGL and the NDS hardware.
// Further colorspace conversion will need to be done in a later step.
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glDrawBuffer(GL_WORKING_ATTACHMENT_ID);
glReadBuffer(GL_COLOROUT_ATTACHMENT_ID);
glBlitFramebufferEXT(0, (GLint)this->_framebufferHeight, (GLint)this->_framebufferWidth, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glReadBuffer(GL_WORKING_ATTACHMENT_ID);
}
else
{
glDrawBuffer(GL_COLOROUT_ATTACHMENT_ID);
glReadBuffer(GL_WORKING_ATTACHMENT_ID);
glBlitFramebufferEXT(0, (GLint)this->_framebufferHeight, (GLint)this->_framebufferWidth, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glReadBuffer(GL_COLOROUT_ATTACHMENT_ID);
}
const GLenum flipTarget = (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor) ? GL_WORKING_ATTACHMENT_ID : GL_COLOROUT_ATTACHMENT_ID;
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboFramebufferFlipID);
glDrawBuffer(flipTarget);
glBlitFramebufferEXT(0, (GLint)this->_framebufferHeight, (GLint)this->_framebufferWidth, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboFramebufferFlipID);
glReadBuffer(flipTarget);
}
if (this->isPBOSupported)
@ -4181,18 +4211,18 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
if (this->isVBOSupported)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
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) * renderGList.rawVertCount, renderGList.rawVertList);
}
else
{
// If VBOs aren't supported, we need to use the client-side buffers here.
OGLRef.vtxPtrPosition = (GLvoid *)&renderGList.rawVertList[0].coord;
OGLRef.vtxPtrTexCoord = (GLvoid *)&renderGList.rawVertList[0].texcoord;
OGLRef.vtxPtrColor = (this->isShaderSupported) ? (GLvoid *)&renderGList.rawVertList[0].color : OGLRef.color4fBuffer;
if (this->isShaderSupported)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(NDSVertex) * renderGList.rawVertCount, renderGList.rawVtxList);
}
else
{
// If shaders aren't supported, we need to use the client-side buffers here.
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
}
// Generate the clipped polygon list.
@ -4234,27 +4264,38 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
for (size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = rawPoly.vertIndexes[j];
const size_t colorIndex = vertIndex * 4;
const GLushort vtxIndex = rawPoly.vertIndexes[j];
const size_t positionIndex = vtxIndex * 4;
const size_t texCoordIndex = vtxIndex * 2;
const size_t colorIndex = vtxIndex * 4;
const NDSVertex &vtx = renderGList.rawVtxList[vtxIndex];
// Consolidate the vertex color and the poly alpha to our internal color buffer
// so that OpenGL can use it.
const VERT *vertForAlpha = &renderGList.rawVertList[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]];
// Since we can't use shaders, we can't perform any data format conversions
// of the vertex data on the GPU. Therefore, we need to do the conversions
// on the CPU instead.
OGLRef.position4fBuffer[positionIndex+0] = (float)vtx.position.x / 4096.0f;
OGLRef.position4fBuffer[positionIndex+1] = (float)vtx.position.y / 4096.0f;
OGLRef.position4fBuffer[positionIndex+2] = (float)vtx.position.z / 4096.0f;
OGLRef.position4fBuffer[positionIndex+3] = (float)vtx.position.w / 4096.0f;
OGLRef.texCoord2fBuffer[texCoordIndex+0] = (float)vtx.texCoord.s / 16.0f;
OGLRef.texCoord2fBuffer[texCoordIndex+1] = (float)vtx.texCoord.t / 16.0f;
OGLRef.color4fBuffer[colorIndex+0] = divide6bitBy63_LUT[vtx.color.r];
OGLRef.color4fBuffer[colorIndex+1] = divide6bitBy63_LUT[vtx.color.g];
OGLRef.color4fBuffer[colorIndex+2] = divide6bitBy63_LUT[vtx.color.b];
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.
OGLRef.vertIndexBuffer[vertIndexCount++] = vertIndex;
OGLRef.vertIndexBuffer[vertIndexCount++] = vtxIndex;
if (!GFX3D_IsPolyWireframe(rawPoly) && (rawPoly.vtxFormat == GFX3D_QUADS || rawPoly.vtxFormat == GFX3D_QUAD_STRIP))
{
if (j == 2)
{
OGLRef.vertIndexBuffer[vertIndexCount++] = vertIndex;
OGLRef.vertIndexBuffer[vertIndexCount++] = vtxIndex;
}
else if (j == 3)
{
@ -4396,13 +4437,14 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry()
size_t indexOffset = 0;
const CPoly &firstCPoly = this->_clippedPolyList[0];
const POLY *rawPolyList = this->_rawPolyList;
const POLY &firstPoly = rawPolyList[this->_clippedPolyList[0].index];
const POLY &firstPoly = rawPolyList[firstCPoly.index];
POLYGON_ATTR lastPolyAttr = firstPoly.attribute;
if (this->_clippedPolyOpaqueCount > 0)
{
this->SetupPolygon(firstPoly, false, true);
this->SetupPolygon(firstPoly, false, true, firstCPoly.isPolyBackFacing);
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawOpaquePolys>(rawPolyList, this->_clippedPolyList, this->_clippedPolyCount, 0, this->_clippedPolyOpaqueCount - 1, indexOffset, lastPolyAttr);
}
@ -4414,16 +4456,17 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry()
{
if (this->_clippedPolyOpaqueCount == 0)
{
this->SetupPolygon(firstPoly, true, false);
this->SetupPolygon(firstPoly, true, false, firstCPoly.isPolyBackFacing);
}
this->ZeroDstAlphaPass(rawPolyList, this->_clippedPolyList, this->_clippedPolyCount, this->_clippedPolyOpaqueCount, this->_enableAlphaBlending, indexOffset, lastPolyAttr);
if (this->_clippedPolyOpaqueCount > 0)
{
const POLY &lastOpaquePoly = rawPolyList[this->_clippedPolyList[this->_clippedPolyOpaqueCount - 1].index];
const CPoly &lastOpaqueCPoly = this->_clippedPolyList[this->_clippedPolyOpaqueCount - 1];
const POLY &lastOpaquePoly = rawPolyList[lastOpaqueCPoly.index];
lastPolyAttr = lastOpaquePoly.attribute;
this->SetupPolygon(lastOpaquePoly, false, true);
this->SetupPolygon(lastOpaquePoly, false, true, lastOpaqueCPoly.isPolyBackFacing);
}
}
else
@ -4440,7 +4483,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry()
if (this->_clippedPolyOpaqueCount == 0)
{
this->SetupPolygon(firstPoly, true, true);
this->SetupPolygon(firstPoly, true, true, firstCPoly.isPolyBackFacing);
}
else
{
@ -4781,7 +4824,7 @@ void OpenGLRenderer_1_2::SetPolygonIndex(const size_t index)
this->_currentPolyIndex = index;
}
Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer)
Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing)
{
// Set up depth test mode
glDepthFunc((thePoly.attribute.DepthEqualTest_Enable) ? GL_EQUAL : GL_LESS);
@ -4860,6 +4903,7 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAs
glUniform1i(OGLRef.uniformPolyIsWireframe[this->_geometryProgramFlags.value], (GFX3D_IsPolyWireframe(thePoly)) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent[this->_geometryProgramFlags.value], (thePoly.attribute.TranslucentDepthWrite_Enable) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformPolyDepthOffset[this->_geometryProgramFlags.value], 0.0f);
glUniform1i(OGLRef.uniformPolyIsBackFacing[this->_geometryProgramFlags.value], (isBackFacing) ? GL_TRUE : GL_FALSE);
}
else
{
@ -5119,6 +5163,16 @@ Render3DError OpenGLRenderer_1_2::Reset()
this->_pixelReadNeedsFinish = false;
if (OGLRef.position4fBuffer != NULL)
{
memset(OGLRef.position4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
}
if (OGLRef.texCoord2fBuffer != NULL)
{
memset(OGLRef.texCoord2fBuffer, 0, VERTLIST_SIZE * 2 * sizeof(GLfloat));
}
if (OGLRef.color4fBuffer != NULL)
{
memset(OGLRef.color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
@ -5126,10 +5180,6 @@ Render3DError OpenGLRenderer_1_2::Reset()
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;
memset(&this->_pendingRenderStates, 0, sizeof(this->_pendingRenderStates));
texCache.Reset();
@ -5371,6 +5421,8 @@ Render3DError OpenGLRenderer_2_0::InitFinalRenderStates(const std::set<std::stri
OGLRef.stateTexMirroredRepeat = GL_MIRRORED_REPEAT;
// Ignore our color buffer since we'll transfer the polygon alpha through a uniform.
OGLRef.position4fBuffer = NULL;
OGLRef.texCoord2fBuffer = NULL;
OGLRef.color4fBuffer = NULL;
return OGLERROR_NOERR;
@ -5389,9 +5441,9 @@ Render3DError OpenGLRenderer_2_0::EnableVertexAttributes()
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glEnableVertexAttribArray(OGLVertexAttributeID_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_FALSE, sizeof(VERT), OGLRef.vtxPtrColor);
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, position));
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, texCoord));
glVertexAttribPointer(OGLVertexAttributeID_Color, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, color));
}
return OGLERROR_NOERR;
@ -5433,7 +5485,7 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, co
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) * renderGList.rawVertCount, renderGList.rawVertList);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(NDSVertex) * renderGList.rawVertCount, renderGList.rawVtxList);
// Generate the clipped polygon list.
bool renderNeedsToonTable = false;

View File

@ -425,7 +425,8 @@ union OGLPolyStates
u8 TexSizeShiftS:3;
u8 TexSizeShiftT:3;
u8 :8;
u8 IsBackFacing:1;
u8 :7;
};
};
@ -536,6 +537,7 @@ struct OGLRenderRef
GLuint fboClearImageID;
GLuint fboRenderID;
GLuint fboFramebufferFlipID;
GLuint fboMSIntermediateRenderID;
GLuint selectedRenderingFBO;
@ -581,6 +583,7 @@ struct OGLRenderRef
GLint uniformTexSingleBitAlpha[256];
GLint uniformTexDrawOpaque[256];
GLint uniformDrawModeDepthEqualsTest[256];
GLint uniformPolyIsBackFacing[256];
GLint uniformPolyStateIndex[256];
GLfloat uniformPolyDepthOffset[256];
@ -591,16 +594,13 @@ struct OGLRenderRef
GLuint vaoPostprocessStatesID;
// Client-side Buffers
GLfloat *position4fBuffer;
GLfloat *texCoord2fBuffer;
GLfloat *color4fBuffer;
CACHE_ALIGN GLushort vertIndexBuffer[OGLRENDER_VERT_INDEX_BUFFER_COUNT];
CACHE_ALIGN GLushort workingCIColorBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT];
CACHE_ALIGN GLuint workingCIDepthStencilBuffer[2][GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT];
CACHE_ALIGN GLuint workingCIFogAttributesBuffer[2][GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT];
// Vertex Attributes Pointers
GLvoid *vtxPtrPosition;
GLvoid *vtxPtrTexCoord;
GLvoid *vtxPtrColor;
};
struct GFX3D_State;
@ -804,7 +804,7 @@ protected:
virtual Render3DError DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool performDepthEqualTest, const bool enableAlphaDepthWrite, const bool isTranslucent, const u8 opaquePolyID) = 0;
virtual void SetPolygonIndex(const size_t index) = 0;
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer) = 0;
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing) = 0;
public:
OpenGLRenderer();
@ -888,7 +888,7 @@ protected:
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes);
virtual void SetPolygonIndex(const size_t index);
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer);
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing);
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
virtual Render3DError SetupViewport(const GFX3D_Viewport viewport);

View File

@ -142,6 +142,7 @@ flat out int polySetNewDepthForTranslucent;\n\
flat out int polyMode;\n\
flat out int polyID;\n\
flat out int texSingleBitAlpha;\n\
flat out int polyIsBackFacing;\n\
flat out int isPolyDrawable;\n\
\n\
void main()\n\
@ -165,15 +166,16 @@ void main()\n\
polySetNewDepthForTranslucent = (polyStateBits >> 15) & 0x01;\n\
polyEnableTexture = (polyStateBits >> 16) & 0x01;\n\
texSingleBitAlpha = (polyStateBits >> 17) & 0x01;\n\
polyIsBackFacing = (polyStateBits >> 24) & 0x01;\n\
\n\
isPolyDrawable = int((polyMode != 3) || polyDrawShadow);\n\
\n\
mat2 texScaleMtx = mat2( vec2(polyTexScale.x, 0.0), \n\
vec2( 0.0, polyTexScale.y)); \n\
\n\
vtxTexCoord = texScaleMtx * inTexCoord0;\n\
vtxTexCoord = (texScaleMtx * inTexCoord0) / 16.0;\n\
vtxColor = vec4(inColor / 63.0, polyAlpha);\n\
gl_Position = inPosition;\n\
gl_Position = inPosition / 4096.0;\n\
}\n\
"};
@ -188,6 +190,7 @@ flat in int polySetNewDepthForTranslucent;\n\
flat in int polyMode;\n\
flat in int polyID;\n\
flat in int texSingleBitAlpha;\n\
flat in int polyIsBackFacing;\n\
flat in int isPolyDrawable;\n\
\n\
layout (std140) uniform RenderStates\n\
@ -212,9 +215,9 @@ uniform bool polyDrawShadow;\n\
uniform float polyDepthOffset;\n\
\n\
#if DRAW_MODE_OPAQUE\n\
out vec4 outBackFacing;\n\
out vec4 outDstBackFacing;\n\
#elif USE_DEPTH_LEQUAL_POLYGON_FACING\n\
uniform sampler2D inBackFacing;\n\
uniform sampler2D inDstBackFacing;\n\
#endif\n\
\n\
out vec4 outFragColor;\n\
@ -232,8 +235,8 @@ layout (depth_less) out float gl_FragDepth;\n\
void main()\n\
{\n\
#if USE_DEPTH_LEQUAL_POLYGON_FACING && !DRAW_MODE_OPAQUE\n\
bool isOpaqueDstBackFacing = bool( texelFetch(inBackFacing, ivec2(gl_FragCoord.xy), 0).r );\n\
if ( drawModeDepthEqualsTest && (!gl_FrontFacing || !isOpaqueDstBackFacing) )\n\
bool isOpaqueDstBackFacing = bool( texelFetch(inDstBackFacing, ivec2(gl_FragCoord.xy), 0).r );\n\
if ( drawModeDepthEqualsTest && (bool(polyIsBackFacing) || !isOpaqueDstBackFacing) )\n\
{\n\
discard;\n\
}\n\
@ -305,7 +308,7 @@ void main()\n\
outFogAttributes = (isPolyDrawable != 0) ? vec4( float(polyEnableFog), 0.0, 0.0, float((outFragColor.a > 0.999) ? 1.0 : 0.5) ) : vec4(0.0, 0.0, 0.0, 0.0);\n\
#endif\n\
#if DRAW_MODE_OPAQUE\n\
outBackFacing = vec4(float(!gl_FrontFacing), 0.0, 0.0, 1.0);\n\
outDstBackFacing = vec4(float(polyIsBackFacing), 0.0, 0.0, 1.0);\n\
#endif\n\
\n\
#if USE_NDS_DEPTH_CALCULATION || ENABLE_FOG\n\
@ -791,7 +794,7 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
INFO("OpenGL: Driver does not support at least 2x multisampled FBOs.\n");
}
this->_isDepthLEqualPolygonFacingSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported;
this->_isDepthLEqualPolygonFacingSupported = true;
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
@ -1111,9 +1114,9 @@ Render3DError OpenGLRenderer_3_2::CreateVAOs()
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_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, position));
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, texCoord));
glVertexAttribPointer(OGLVertexAttributeID_Color, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, color));
glBindVertexArray(0);
@ -1280,7 +1283,7 @@ Render3DError OpenGLRenderer_3_2::CreateGeometryPrograms()
if (programFlags.OpaqueDrawMode)
{
glBindFragDataLocation(OGLRef.programGeometryID[flagsValue], GeometryAttachmentWorkingBuffer[programFlags.DrawBuffersMode], "outBackFacing");
glBindFragDataLocation(OGLRef.programGeometryID[flagsValue], GeometryAttachmentWorkingBuffer[programFlags.DrawBuffersMode], "outDstBackFacing");
}
glLinkProgram(OGLRef.programGeometryID[flagsValue]);
@ -1319,7 +1322,7 @@ Render3DError OpenGLRenderer_3_2::CreateGeometryPrograms()
if (this->_emulateDepthLEqualPolygonFacing && !programFlags.OpaqueDrawMode)
{
const GLint uniformTexBackfacing = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "inBackFacing");
const GLint uniformTexBackfacing = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "inDstBackFacing");
glUniform1i(uniformTexBackfacing, OGLTextureUnitID_FinalColor);
}
@ -1999,9 +2002,9 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State &renderState, co
glDeleteSync(this->_syncBufferSetup);
}
const size_t vtxBufferSize = sizeof(VERT) * renderGList.rawVertCount;
VERT *vtxPtr = (VERT *)glMapBufferRange(GL_ARRAY_BUFFER, 0, vtxBufferSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
memcpy(vtxPtr, renderGList.rawVertList, vtxBufferSize);
const size_t vtxBufferSize = sizeof(NDSVertex) * renderGList.rawVertCount;
NDSVertex *vtxPtr = (NDSVertex *)glMapBufferRange(GL_ARRAY_BUFFER, 0, vtxBufferSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
memcpy(vtxPtr, renderGList.rawVtxList, vtxBufferSize);
glUnmapBuffer(GL_ARRAY_BUFFER);
this->_syncBufferSetup = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
@ -2143,6 +2146,8 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State &renderState, co
polyStates[i].TexSingleBitAlpha = (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? 1 : 0;
polyStates[i].TexSizeShiftS = rawPoly.texParam.SizeShiftS; // Note that we are using the preshifted size of S
polyStates[i].TexSizeShiftT = rawPoly.texParam.SizeShiftT; // Note that we are using the preshifted size of T
polyStates[i].IsBackFacing = (this->_clippedPolyList[i].isPolyBackFacing) ? 1 : 0;
}
if (OGLRef.uboPolyStatesID != 0)
@ -2401,7 +2406,7 @@ void OpenGLRenderer_3_2::SetPolygonIndex(const size_t index)
}
}
Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer)
Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing)
{
OGLRenderRef &OGLRef = *this->ref;

View File

@ -109,7 +109,7 @@ protected:
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes);
virtual void SetPolygonIndex(const size_t index);
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer);
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing);
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
virtual Render3DError SetFramebufferSize(size_t w, size_t h);