OpenGL Renderer: Do some more code cleanup and tune-ups.

- In the 3.2 Core Profile and ES renderers, synchronization of vertex info uploads now occurs at a more reasonable time.
- Geometry rendering is now Y-flipped by default, eliminating the need to Y-flip the final output framebuffer under all conditions.
- Legacy OpenGL no longer needs to perform any color conversion of the final output framebuffer if FBOs are supported.
- Rename some functions and variables to better describe what things are doing now.
This commit is contained in:
rogerman 2024-08-12 11:23:23 -07:00
parent 9bbfca527a
commit 3db6d5676c
5 changed files with 265 additions and 290 deletions

View File

@ -310,7 +310,7 @@ void main() \n\
vtxColor = vec4(inColor / 63.0, polyAlpha); \n\ vtxColor = vec4(inColor / 63.0, polyAlpha); \n\
isPolyDrawable = ((polyMode != 3) || polyDrawShadow) ? 1.0 : -1.0;\n\ isPolyDrawable = ((polyMode != 3) || polyDrawShadow) ? 1.0 : -1.0;\n\
\n\ \n\
gl_Position = inPosition / 4096.0;\n\ gl_Position = vec4(inPosition.x, -inPosition.y, inPosition.z, inPosition.w) / 4096.0;\n\
} \n\ } \n\
"}; "};
@ -600,7 +600,7 @@ varying vec2 texCoord;\n\
\n\ \n\
void main()\n\ void main()\n\
{\n\ {\n\
texCoord = vec2(inTexCoord0.x, 1.0 - inTexCoord0.y);\n\ texCoord = inTexCoord0;\n\
gl_Position = vec4(inPosition, 0.0, 1.0);\n\ gl_Position = vec4(inPosition, 0.0, 1.0);\n\
}\n\ }\n\
"}; "};
@ -1277,7 +1277,7 @@ OpenGLRenderer::OpenGLRenderer()
_isSampleShadingSupported = false; _isSampleShadingSupported = false;
isVAOSupported = false; isVAOSupported = false;
_isDepthLEqualPolygonFacingSupported = false; _isDepthLEqualPolygonFacingSupported = false;
willFlipAndConvertFramebufferOnGPU = false; _willConvertFramebufferOnGPU = false;
_willUseMultisampleShaders = false; _willUseMultisampleShaders = false;
_emulateShadowPolygon = true; _emulateShadowPolygon = true;
@ -1578,7 +1578,7 @@ Render3DError OpenGLRenderer::FlushFramebuffer(const Color4u8 *__restrict srcFra
{ {
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
if (this->willFlipAndConvertFramebufferOnGPU && this->isPBOSupported) if (this->_willConvertFramebufferOnGPU && this->isPBOSupported)
{ {
this->_renderNeedsFlushMain = false; this->_renderNeedsFlushMain = false;
return Render3D::FlushFramebuffer(srcFramebuffer, NULL, dstFramebuffer16); return Render3D::FlushFramebuffer(srcFramebuffer, NULL, dstFramebuffer16);
@ -1589,13 +1589,13 @@ Render3DError OpenGLRenderer::FlushFramebuffer(const Color4u8 *__restrict srcFra
{ {
return this->_FlushFramebufferConvertOnCPU<true>(srcFramebuffer, return this->_FlushFramebufferConvertOnCPU<true>(srcFramebuffer,
dstFramebufferMain, dstFramebuffer16, dstFramebufferMain, dstFramebuffer16,
!this->willFlipAndConvertFramebufferOnGPU); !this->_willConvertFramebufferOnGPU);
} }
else else
{ {
return this->_FlushFramebufferConvertOnCPU<false>(srcFramebuffer, return this->_FlushFramebufferConvertOnCPU<false>(srcFramebuffer,
dstFramebufferMain, dstFramebuffer16, dstFramebufferMain, dstFramebuffer16,
!this->willFlipAndConvertFramebufferOnGPU); !this->_willConvertFramebufferOnGPU);
} }
} }
@ -1604,7 +1604,7 @@ Render3DError OpenGLRenderer::FlushFramebuffer(const Color4u8 *__restrict srcFra
Color4u8* OpenGLRenderer::GetFramebuffer() Color4u8* OpenGLRenderer::GetFramebuffer()
{ {
return (this->willFlipAndConvertFramebufferOnGPU && this->isPBOSupported) ? this->_mappedFramebuffer : GPU->GetEngineMain()->Get3DFramebufferMain(); return (this->_willConvertFramebufferOnGPU && this->isPBOSupported) ? this->_mappedFramebuffer : GPU->GetEngineMain()->Get3DFramebufferMain();
} }
GLsizei OpenGLRenderer::GetLimitedMultisampleSize() const GLsizei OpenGLRenderer::GetLimitedMultisampleSize() const
@ -2367,7 +2367,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
std::set<std::string> oglExtensionSet; std::set<std::string> oglExtensionSet;
this->GetExtensionSet(&oglExtensionSet); this->GetExtensionSet(&oglExtensionSet);
#if !defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_1_2)
if (!this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_multitexture")) if (!this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_multitexture"))
{ {
return OGLERROR_DRIVER_VERSION_TOO_OLD; return OGLERROR_DRIVER_VERSION_TOO_OLD;
@ -2607,7 +2607,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
} }
// Set rendering support flags based on driver features. // Set rendering support flags based on driver features.
this->willFlipAndConvertFramebufferOnGPU = this->isShaderSupported && this->isVBOSupported; this->_willConvertFramebufferOnGPU = this->isShaderSupported && this->isVBOSupported;
this->_deviceInfo.isEdgeMarkSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported; this->_deviceInfo.isEdgeMarkSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported;
this->_deviceInfo.isFogSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported; this->_deviceInfo.isFogSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported;
this->_deviceInfo.isTextureSmoothingSupported = this->isShaderSupported; this->_deviceInfo.isTextureSmoothingSupported = this->isShaderSupported;
@ -2714,7 +2714,7 @@ Render3DError OpenGLRenderer_1_2::CreateVAOs()
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, texCoord)); 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)); glVertexAttribPointer(OGLVertexAttributeID_Color, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, color));
} }
#if !defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_1_2)
else else
{ {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
@ -3847,7 +3847,7 @@ void OpenGLRenderer_1_2::_SetupGeometryShaders(const OGLGeometryFlags flags)
glUniform1i(OGLRef.uniformPolyDrawShadow[flags.value], GL_FALSE); glUniform1i(OGLRef.uniformPolyDrawShadow[flags.value], GL_FALSE);
} }
Render3DError OpenGLRenderer_1_2::EnableVertexAttributes() void OpenGLRenderer_1_2::_RenderGeometryVertexAttribEnable()
{ {
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
@ -3855,9 +3855,7 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
{ {
glBindVertexArray(OGLRef.vaoGeometryStatesID); glBindVertexArray(OGLRef.vaoGeometryStatesID);
} }
else else if (this->isShaderSupported)
{
if (this->isShaderSupported)
{ {
glEnableVertexAttribArray(OGLVertexAttributeID_Position); glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0); glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
@ -3866,7 +3864,7 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_INT, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, texCoord)); 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)); glVertexAttribPointer(OGLVertexAttributeID_Color, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(NDSVertex), (const GLvoid *)offsetof(NDSVertex, color));
} }
#if !defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_1_2)
else else
{ {
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
@ -3877,26 +3875,21 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer); glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer);
} }
#endif #endif
}
return OGLERROR_NOERR;
} }
Render3DError OpenGLRenderer_1_2::DisableVertexAttributes() void OpenGLRenderer_1_2::_RenderGeometryVertexAttribDisable()
{ {
if (this->isVAOSupported) if (this->isVAOSupported)
{ {
glBindVertexArray(0); glBindVertexArray(0);
} }
else else if (this->isShaderSupported)
{
if (this->isShaderSupported)
{ {
glDisableVertexAttribArray(OGLVertexAttributeID_Position); glDisableVertexAttribArray(OGLVertexAttributeID_Position);
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0); glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glDisableVertexAttribArray(OGLVertexAttributeID_Color); glDisableVertexAttribArray(OGLVertexAttributeID_Color);
} }
#if !defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_1_2)
else else
{ {
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
@ -3904,9 +3897,6 @@ Render3DError OpenGLRenderer_1_2::DisableVertexAttributes()
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
} }
#endif #endif
}
return OGLERROR_NOERR;
} }
Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr) Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr)
@ -3922,8 +3912,6 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
// Fully transparent pixels (alpha == 0) -- Set stencil buffer to 0 // Fully transparent pixels (alpha == 0) -- Set stencil buffer to 0
// All other pixels (alpha != 0) -- Set stencil buffer to 1 // All other pixels (alpha != 0) -- Set stencil buffer to 1
this->DisableVertexAttributes();
const bool isRunningMSAA = this->isMultisampledFBOSupported && (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID); const bool isRunningMSAA = this->isMultisampledFBOSupported && (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID);
if (isRunningMSAA) if (isRunningMSAA)
@ -3950,31 +3938,9 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
glDrawBuffer(GL_NONE); glDrawBuffer(GL_NONE);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID); glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
this->_FramebufferProcessVertexAttribEnable();
if (this->isVAOSupported)
{
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
}
else
{
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));
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if (this->isVAOSupported)
{
glBindVertexArray(0);
}
else
{
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
}
// Setup for multiple pass alpha poly drawing // Setup for multiple pass alpha poly drawing
OGLGeometryFlags oldGProgramFlags = this->_geometryProgramFlags; OGLGeometryFlags oldGProgramFlags = this->_geometryProgramFlags;
this->_geometryProgramFlags.EnableEdgeMark = 0; this->_geometryProgramFlags.EnableEdgeMark = 0;
@ -3985,7 +3951,7 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
this->EnableVertexAttributes(); this->_RenderGeometryVertexAttribEnable();
// Draw the alpha polys, touching fully transparent pixels only once. // Draw the alpha polys, touching fully transparent pixels only once.
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
@ -4095,13 +4061,56 @@ void OpenGLRenderer_1_2::_ResolveFinalFramebuffer()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
} }
Render3DError OpenGLRenderer_1_2::ReadBackPixels() void OpenGLRenderer_1_2::_FramebufferProcessVertexAttribEnable()
{
if (!this->isShaderSupported)
{
// Framebuffer processing requires shaders, so there is no legacy code path
// for this method.
return;
}
if (this->isVAOSupported)
{
glBindVertexArray(this->ref->vaoPostprocessStatesID);
}
else
{
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glDisableVertexAttribArray(OGLVertexAttributeID_Color); // Framebuffer processing doesn't use vertex colors.
glVertexAttribPointer(OGLVertexAttributeID_Position, 2, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)(sizeof(GLfloat) * 8));
}
}
void OpenGLRenderer_1_2::_FramebufferProcessVertexAttribDisable()
{
if (!this->isShaderSupported)
{
// Framebuffer processing requires shaders, so there is no legacy code path
// for this method.
return;
}
if (this->isVAOSupported)
{
glBindVertexArray(0);
}
else
{
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glDisableVertexAttribArray(OGLVertexAttributeID_Color);
}
}
Render3DError OpenGLRenderer_1_2::_FramebufferConvertColorFormat()
{ {
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
// Both flips and converts the framebuffer on the GPU. No additional postprocessing if ( this->_willConvertFramebufferOnGPU &&
// should be necessary at this point. ((this->_outputFormat == NDSColorFormat_BGR666_Rev) || (OGLRef.readPixelsBestFormat == GL_BGRA)) )
if (this->willFlipAndConvertFramebufferOnGPU)
{ {
const GLuint convertProgramID = (this->_outputFormat == NDSColorFormat_BGR666_Rev) ? OGLRef.programFramebufferRGBA6665OutputID : OGLRef.programFramebufferRGBA8888OutputID; const GLuint convertProgramID = (this->_outputFormat == NDSColorFormat_BGR666_Rev) ? OGLRef.programFramebufferRGBA6665OutputID : OGLRef.programFramebufferRGBA8888OutputID;
glUseProgram(convertProgramID); glUseProgram(convertProgramID);
@ -4125,46 +4134,11 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
glDisable(GL_BLEND); glDisable(GL_BLEND);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID); glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
this->_FramebufferProcessVertexAttribEnable();
if (this->isVAOSupported)
{
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
}
else
{
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));
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
this->_FramebufferProcessVertexAttribDisable();
if (this->isVAOSupported)
{
glBindVertexArray(0);
}
else
{
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
}
} }
if (this->isPBOSupported)
{
// Read back the pixels in BGRA format, since legacy OpenGL devices may experience a performance
// penalty if the readback is in any other format.
if (this->_mappedFramebuffer != NULL)
{
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
this->_mappedFramebuffer = NULL;
}
glReadPixels(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight, OGLRef.readPixelsBestFormat, OGLRef.readPixelsBestDataType, 0);
}
this->_pixelReadNeedsFinish = true;
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
@ -4370,7 +4344,7 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
} }
} }
} }
#if !defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_1_2)
else else
{ {
if (renderState.DISP3DCNT.EnableAlphaTest && (renderState.alphaTestRef > 0)) if (renderState.DISP3DCNT.EnableAlphaTest && (renderState.alphaTestRef > 0))
@ -4381,10 +4355,6 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
{ {
glAlphaFunc(GL_GREATER, 0); glAlphaFunc(GL_GREATER, 0);
} }
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, -1.0f, 1.0f);
} }
#endif #endif
} }
@ -4398,6 +4368,42 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
this->_geometryProgramFlags.OpaqueDrawMode = 1; this->_geometryProgramFlags.OpaqueDrawMode = 1;
} }
this->_needsZeroDstAlphaPass = true;
return OGLERROR_NOERR;
}
void OpenGLRenderer_1_2::_RenderGeometryLoopBegin()
{
OGLRenderRef &OGLRef = *this->ref;
glDisable(GL_CULL_FACE); // Polygons should already be culled before we get here.
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
if (this->_enableAlphaBlending)
{
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
#if defined(GL_VERSION_1_2)
if (!this->isShaderSupported)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, -1.0f, 1.0f);
}
#endif
glActiveTexture(GL_TEXTURE0);
if (this->isFBOSupported) if (this->isFBOSupported)
{ {
if (this->_enableMultisampledRendering) if (this->_enableMultisampledRendering)
@ -4423,34 +4429,31 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
} }
this->_RenderGeometryVertexAttribEnable();
}
void OpenGLRenderer_1_2::_RenderGeometryLoopEnd()
{
this->_RenderGeometryVertexAttribDisable();
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
this->_needsZeroDstAlphaPass = true; #if defined(GL_VERSION_1_2)
if (!this->isShaderSupported)
return OGLERROR_NOERR; {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, 1.0f, 1.0f);
}
#endif
} }
Render3DError OpenGLRenderer_1_2::RenderGeometry() Render3DError OpenGLRenderer_1_2::RenderGeometry()
{ {
if (this->_clippedPolyCount > 0) if (this->_clippedPolyCount > 0)
{ {
glDisable(GL_CULL_FACE); // Polygons should already be culled before we get here. this->_RenderGeometryLoopBegin();
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
if (this->_enableAlphaBlending)
{
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
}
glActiveTexture(GL_TEXTURE0);
this->EnableVertexAttributes();
size_t indexOffset = 0; size_t indexOffset = 0;
@ -4517,9 +4520,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry()
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(rawPolyList, this->_clippedPolyList, this->_clippedPolyCount, this->_clippedPolyOpaqueCount, this->_clippedPolyCount - 1, indexOffset, lastPolyAttr); this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(rawPolyList, this->_clippedPolyList, this->_clippedPolyCount, this->_clippedPolyOpaqueCount, this->_clippedPolyCount - 1, indexOffset, lastPolyAttr);
} }
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); this->_RenderGeometryLoopEnd();
glDepthMask(GL_TRUE);
this->DisableVertexAttributes();
} }
if (!this->_willUseMultisampleShaders) if (!this->_willUseMultisampleShaders)
@ -4557,18 +4558,7 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID); glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
this->_FramebufferProcessVertexAttribEnable();
if (this->isVAOSupported)
{
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
}
else
{
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->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) if (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported)
{ {
@ -4656,30 +4646,40 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX); glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
} }
if (this->isVAOSupported) this->_FramebufferProcessVertexAttribDisable();
{
glBindVertexArray(0);
}
else
{
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
}
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
Render3DError OpenGLRenderer_1_2::EndRender() Render3DError OpenGLRenderer_1_2::EndRender()
{ {
//needs to happen before endgl because it could free some textureids for expired cache items OGLRenderRef &OGLRef = *this->ref;
texCache.Evict();
if (this->_willUseMultisampleShaders) if (this->_willUseMultisampleShaders)
{ {
this->_ResolveFinalFramebuffer(); this->_ResolveFinalFramebuffer();
} }
this->ReadBackPixels(); this->_FramebufferConvertColorFormat();
if (this->isPBOSupported)
{
// If PBOs are supported, then begin the asynchronous pixel read.
// The asynchronous pixel read ends when RenderFinish() is called,
// which is always called before RenderFlush().
if (this->_mappedFramebuffer != NULL)
{
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
this->_mappedFramebuffer = NULL;
}
glReadPixels(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight, OGLRef.readPixelsBestFormat, OGLRef.readPixelsBestDataType, 0);
}
this->_pixelReadNeedsFinish = true;
//needs to happen before endgl because it could free some textureids for expired cache items
texCache.Evict();
ENDGL(); ENDGL();
@ -4928,7 +4928,7 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAs
glUniform1f(OGLRef.uniformPolyDepthOffset[this->_geometryProgramFlags.value], 0.0f); glUniform1f(OGLRef.uniformPolyDepthOffset[this->_geometryProgramFlags.value], 0.0f);
glUniform1i(OGLRef.uniformPolyIsBackFacing[this->_geometryProgramFlags.value], (isBackFacing) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformPolyIsBackFacing[this->_geometryProgramFlags.value], (isBackFacing) ? GL_TRUE : GL_FALSE);
} }
#if !defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_1_2)
else else
{ {
// Set the texture blending mode // Set the texture blending mode
@ -4970,7 +4970,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, size_t polyR
glUniform1i(OGLRef.uniformTexSingleBitAlpha[this->_geometryProgramFlags.value], (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformTexSingleBitAlpha[this->_geometryProgramFlags.value], (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
glUniform2f(OGLRef.uniformPolyTexScale[this->_geometryProgramFlags.value], theTexture->GetInvWidth(), theTexture->GetInvHeight()); glUniform2f(OGLRef.uniformPolyTexScale[this->_geometryProgramFlags.value], theTexture->GetInvWidth(), theTexture->GetInvHeight());
} }
#if !defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_1_2)
else else
{ {
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
@ -5176,7 +5176,7 @@ Render3DError OpenGLRenderer_1_2::Reset()
glFinish(); glFinish();
#if !defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_1_2)
if (!this->isShaderSupported) if (!this->isShaderSupported)
{ {
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
@ -5471,43 +5471,6 @@ Render3DError OpenGLRenderer_2_0::InitFinalRenderStates(const std::set<std::stri
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
Render3DError OpenGLRenderer_2_0::EnableVertexAttributes()
{
OGLRenderRef &OGLRef = *this->ref;
if (this->isVAOSupported)
{
glBindVertexArray(OGLRef.vaoGeometryStatesID);
}
else
{
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));
}
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_2_0::DisableVertexAttributes()
{
if (this->isVAOSupported)
{
glBindVertexArray(0);
}
else
{
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glDisableVertexAttribArray(OGLVertexAttributeID_Color);
}
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList) Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
{ {
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
@ -5657,25 +5620,6 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, co
this->_geometryProgramFlags.OpaqueDrawMode = 1; this->_geometryProgramFlags.OpaqueDrawMode = 1;
} }
if (this->isFBOSupported)
{
if (this->_enableMultisampledRendering)
{
OGLRef.selectedRenderingFBO = OGLRef.fboMSIntermediateRenderID;
}
else
{
OGLRef.selectedRenderingFBO = OGLRef.fboRenderID;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, this->_geometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
this->_needsZeroDstAlphaPass = true; this->_needsZeroDstAlphaPass = true;
return OGLERROR_NOERR; return OGLERROR_NOERR;

View File

@ -871,7 +871,7 @@ protected:
bool isShaderSupported; bool isShaderSupported;
bool _isSampleShadingSupported; bool _isSampleShadingSupported;
bool isVAOSupported; bool isVAOSupported;
bool willFlipAndConvertFramebufferOnGPU; bool _willConvertFramebufferOnGPU;
bool _willUseMultisampleShaders; bool _willUseMultisampleShaders;
bool _emulateShadowPolygon; bool _emulateShadowPolygon;
@ -961,12 +961,16 @@ protected:
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet) = 0; virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet) = 0;
virtual void _SetupGeometryShaders(const OGLGeometryFlags flags) = 0; virtual void _SetupGeometryShaders(const OGLGeometryFlags flags) = 0;
virtual Render3DError EnableVertexAttributes() = 0; virtual void _RenderGeometryVertexAttribEnable() = 0;
virtual Render3DError DisableVertexAttributes() = 0; virtual void _RenderGeometryVertexAttribDisable() = 0;
virtual void _RenderGeometryLoopBegin() = 0;
virtual void _RenderGeometryLoopEnd() = 0;
virtual void _ResolveWorkingBackFacing() = 0; virtual void _ResolveWorkingBackFacing() = 0;
virtual void _ResolveGeometry() = 0; virtual void _ResolveGeometry() = 0;
virtual void _ResolveFinalFramebuffer() = 0; virtual void _ResolveFinalFramebuffer() = 0;
virtual Render3DError ReadBackPixels() = 0; virtual void _FramebufferProcessVertexAttribEnable() = 0;
virtual void _FramebufferProcessVertexAttribDisable() = 0;
virtual Render3DError _FramebufferConvertColorFormat() = 0;
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 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 void SetPolygonIndex(const size_t index) = 0;
@ -1039,13 +1043,17 @@ protected:
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet); virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
virtual void _SetupGeometryShaders(const OGLGeometryFlags flags); virtual void _SetupGeometryShaders(const OGLGeometryFlags flags);
virtual Render3DError EnableVertexAttributes(); virtual void _RenderGeometryVertexAttribEnable();
virtual Render3DError DisableVertexAttributes(); virtual void _RenderGeometryVertexAttribDisable();
virtual Render3DError ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr); virtual Render3DError ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
virtual void _RenderGeometryLoopBegin();
virtual void _RenderGeometryLoopEnd();
virtual void _ResolveWorkingBackFacing(); virtual void _ResolveWorkingBackFacing();
virtual void _ResolveGeometry(); virtual void _ResolveGeometry();
virtual void _ResolveFinalFramebuffer(); virtual void _ResolveFinalFramebuffer();
virtual Render3DError ReadBackPixels(); virtual void _FramebufferProcessVertexAttribEnable();
virtual void _FramebufferProcessVertexAttribDisable();
virtual Render3DError _FramebufferConvertColorFormat();
// Base rendering methods // Base rendering methods
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList); virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
@ -1082,10 +1090,6 @@ public:
protected: protected:
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet); virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
virtual Render3DError EnableVertexAttributes();
virtual Render3DError DisableVertexAttributes();
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList); virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
}; };

View File

@ -201,7 +201,7 @@ void main()\n\
\n\ \n\
vtxTexCoord = (texScaleMtx * inTexCoord0) / 16.0;\n\ vtxTexCoord = (texScaleMtx * inTexCoord0) / 16.0;\n\
vtxColor = vec4(inColor / 63.0, polyAlpha);\n\ vtxColor = vec4(inColor / 63.0, polyAlpha);\n\
gl_Position = inPosition / 4096.0;\n\ gl_Position = vec4(inPosition.x, -inPosition.y, inPosition.z, inPosition.w) / 4096.0;\n\
}\n\ }\n\
"}; "};
@ -729,7 +729,7 @@ out vec2 texCoord;\n\
\n\ \n\
void main()\n\ void main()\n\
{\n\ {\n\
texCoord = vec2(inTexCoord0.x, 1.0 - inTexCoord0.y);\n\ texCoord = inTexCoord0;\n\
gl_Position = vec4(inPosition, 0.0, 1.0);\n\ gl_Position = vec4(inPosition, 0.0, 1.0);\n\
}\n\ }\n\
"}; "};
@ -779,6 +779,12 @@ OpenGLRenderer_3_2::~OpenGLRenderer_3_2()
{ {
glFinish(); glFinish();
if (this->_syncBufferSetup != NULL)
{
glDeleteSync(this->_syncBufferSetup);
this->_syncBufferSetup = NULL;
}
glUseProgram(0); glUseProgram(0);
this->DestroyMSGeometryZeroDstAlphaProgram(); this->DestroyMSGeometryZeroDstAlphaProgram();
@ -832,7 +838,7 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
// OpenGL v3.2 Core Profile should have all the necessary features to be able to flip and convert the framebuffer. // OpenGL v3.2 Core Profile should have all the necessary features to be able to flip and convert the framebuffer.
this->willFlipAndConvertFramebufferOnGPU = true; this->_willConvertFramebufferOnGPU = true;
this->_isSampleShadingSupported = this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_sample_shading"); this->_isSampleShadingSupported = this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_sample_shading");
this->_isConservativeDepthSupported = this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_conservative_depth") && IsOpenGLDriverVersionSupported(4, 0, 0); this->_isConservativeDepthSupported = this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_conservative_depth") && IsOpenGLDriverVersionSupported(4, 0, 0);
@ -2327,16 +2333,14 @@ void OpenGLRenderer_3_2::_SetupGeometryShaders(const OGLGeometryFlags flags)
glUniform1i(OGLRef.uniformPolyDrawShadow[flags.value], GL_FALSE); glUniform1i(OGLRef.uniformPolyDrawShadow[flags.value], GL_FALSE);
} }
Render3DError OpenGLRenderer_3_2::EnableVertexAttributes() void OpenGLRenderer_3_2::_RenderGeometryVertexAttribEnable()
{ {
glBindVertexArray(this->ref->vaoGeometryStatesID); glBindVertexArray(this->ref->vaoGeometryStatesID);
return OGLERROR_NOERR;
} }
Render3DError OpenGLRenderer_3_2::DisableVertexAttributes() void OpenGLRenderer_3_2::_RenderGeometryVertexAttribDisable()
{ {
glBindVertexArray(0); glBindVertexArray(0);
return OGLERROR_NOERR;
} }
Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr) Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr)
@ -2347,8 +2351,6 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
// Fully transparent pixels (alpha == 0) -- Set stencil buffer to 0 // Fully transparent pixels (alpha == 0) -- Set stencil buffer to 0
// All other pixels (alpha != 0) -- Set stencil buffer to 1 // All other pixels (alpha != 0) -- Set stencil buffer to 1
this->DisableVertexAttributes();
const bool isRunningMSAA = this->_enableMultisampledRendering && (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID); const bool isRunningMSAA = this->_enableMultisampledRendering && (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID);
const bool isRunningMSAAWithPerSampleShading = isRunningMSAA && this->_willUseMultisampleShaders; // Doing per-sample shading will be more accurate than not doing so. const bool isRunningMSAAWithPerSampleShading = isRunningMSAA && this->_willUseMultisampleShaders; // Doing per-sample shading will be more accurate than not doing so.
@ -2378,7 +2380,6 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID); glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
glBindVertexArray(OGLRef.vaoPostprocessStatesID); glBindVertexArray(OGLRef.vaoPostprocessStatesID);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
// Setup for multiple pass alpha poly drawing // Setup for multiple pass alpha poly drawing
OGLGeometryFlags oldGProgramFlags = this->_geometryProgramFlags; OGLGeometryFlags oldGProgramFlags = this->_geometryProgramFlags;
@ -2390,7 +2391,7 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID); glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
this->EnableVertexAttributes(); glBindVertexArray(OGLRef.vaoGeometryStatesID);
// Draw the alpha polys, touching fully transparent pixels only once. // Draw the alpha polys, touching fully transparent pixels only once.
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
@ -2492,14 +2493,22 @@ void OpenGLRenderer_3_2::_ResolveFinalFramebuffer()
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
} }
Render3DError OpenGLRenderer_3_2::ReadBackPixels() void OpenGLRenderer_3_2::_FramebufferProcessVertexAttribEnable()
{
glBindVertexArray(this->ref->vaoPostprocessStatesID);
}
void OpenGLRenderer_3_2::_FramebufferProcessVertexAttribDisable()
{
glBindVertexArray(0);
}
Render3DError OpenGLRenderer_3_2::_FramebufferConvertColorFormat()
{ {
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
if (this->_outputFormat == NDSColorFormat_BGR666_Rev) if (this->_outputFormat == NDSColorFormat_BGR666_Rev)
{ {
// Both flips and converts the framebuffer on the GPU. No additional postprocessing
// should be necessary at this point.
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID); glUseProgram(OGLRef.programFramebufferRGBA6665OutputID);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
glReadBuffer(OGL_WORKING_ATTACHMENT_ID); glReadBuffer(OGL_WORKING_ATTACHMENT_ID);
@ -2515,30 +2524,7 @@ Render3DError OpenGLRenderer_3_2::ReadBackPixels()
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0); glBindVertexArray(0);
} }
else
{
// Just flips the framebuffer in Y to match the coordinates of OpenGL and the NDS hardware.
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_WORKING_ATTACHMENT_ID);
glBlitFramebuffer(0, (GLint)this->_framebufferHeight, (GLint)this->_framebufferWidth, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glReadBuffer(OGL_WORKING_ATTACHMENT_ID);
}
if (this->isPBOSupported)
{
// Read back the pixels in RGBA format, since an OpenGL 3.2 device should be able to read back this
// format without a performance penalty.
if (this->_mappedFramebuffer != NULL)
{
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
this->_mappedFramebuffer = NULL;
}
glReadPixels(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight, OGLRef.readPixelsBestFormat, OGLRef.readPixelsBestDataType, 0);
}
this->_pixelReadNeedsFinish = true;
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
@ -2569,6 +2555,7 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State &renderState, co
{ {
glWaitSync(this->_syncBufferSetup, 0, GL_TIMEOUT_IGNORED); glWaitSync(this->_syncBufferSetup, 0, GL_TIMEOUT_IGNORED);
glDeleteSync(this->_syncBufferSetup); glDeleteSync(this->_syncBufferSetup);
this->_syncBufferSetup = NULL;
} }
const size_t vtxBufferSize = sizeof(NDSVertex) * renderGList.rawVertCount; const size_t vtxBufferSize = sizeof(NDSVertex) * renderGList.rawVertCount;
@ -2576,8 +2563,6 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State &renderState, co
memcpy(vtxPtr, renderGList.rawVtxList, vtxBufferSize); memcpy(vtxPtr, renderGList.rawVtxList, vtxBufferSize);
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
this->_syncBufferSetup = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
// Generate the clipped polygon list. // Generate the clipped polygon list.
if ( (OGLRef.uboPolyStatesID != 0) && (this->_clippedPolyCount > MAX_CLIPPED_POLY_COUNT_FOR_UBO) ) if ( (OGLRef.uboPolyStatesID != 0) && (this->_clippedPolyCount > MAX_CLIPPED_POLY_COUNT_FOR_UBO) )
{ {
@ -2791,6 +2776,50 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State &renderState, co
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
void OpenGLRenderer_3_2::_RenderGeometryLoopBegin()
{
OGLRenderRef &OGLRef = *this->ref;
glDisable(GL_CULL_FACE); // Polygons should already be culled before we get here.
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
if (this->_enableAlphaBlending)
{
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glActiveTexture(GL_TEXTURE0);
if (this->_enableMultisampledRendering)
{
OGLRef.selectedRenderingFBO = OGLRef.fboMSIntermediateRenderID;
}
else
{
OGLRef.selectedRenderingFBO = OGLRef.fboRenderID;
}
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, this->_geometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
glReadBuffer(GL_COLOR_ATTACHMENT0);
this->_RenderGeometryVertexAttribEnable();
}
void OpenGLRenderer_3_2::_RenderGeometryLoopEnd()
{
OpenGLRenderer_2_1::_RenderGeometryLoopEnd();
this->_syncBufferSetup = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
Render3DError OpenGLRenderer_3_2::PostprocessFramebuffer() Render3DError OpenGLRenderer_3_2::PostprocessFramebuffer()
{ {
if ( (this->_clippedPolyCount < 1) || if ( (this->_clippedPolyCount < 1) ||
@ -3042,13 +3071,6 @@ void OpenGLRenderer_3_2::SetPolygonIndex(const size_t index)
{ {
this->_currentPolyIndex = index; this->_currentPolyIndex = index;
glUniform1i(this->ref->uniformPolyStateIndex[this->_geometryProgramFlags.value], (GLint)index); glUniform1i(this->ref->uniformPolyStateIndex[this->_geometryProgramFlags.value], (GLint)index);
if (this->_syncBufferSetup != NULL)
{
glWaitSync(this->_syncBufferSetup, 0, GL_TIMEOUT_IGNORED);
glDeleteSync(this->_syncBufferSetup);
this->_syncBufferSetup = NULL;
}
} }
Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing) Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing)

View File

@ -95,13 +95,18 @@ protected:
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet); virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
virtual void _SetupGeometryShaders(const OGLGeometryFlags flags); virtual void _SetupGeometryShaders(const OGLGeometryFlags flags);
virtual Render3DError EnableVertexAttributes(); virtual void _RenderGeometryVertexAttribEnable();
virtual Render3DError DisableVertexAttributes(); virtual void _RenderGeometryVertexAttribDisable();
virtual Render3DError ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr); virtual Render3DError ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
virtual void _RenderGeometryLoopBegin();
virtual void _RenderGeometryLoopEnd();
virtual void _ResolveWorkingBackFacing(); virtual void _ResolveWorkingBackFacing();
virtual void _ResolveGeometry(); virtual void _ResolveGeometry();
virtual void _ResolveFinalFramebuffer(); virtual void _ResolveFinalFramebuffer();
virtual Render3DError ReadBackPixels(); virtual void _FramebufferProcessVertexAttribEnable();
virtual void _FramebufferProcessVertexAttribDisable();
virtual Render3DError _FramebufferConvertColorFormat();
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList); virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
virtual Render3DError PostprocessFramebuffer(); virtual Render3DError PostprocessFramebuffer();

View File

@ -346,7 +346,7 @@ Render3DError OpenGLESRenderer_3_0::InitExtensions()
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
// OpenGL ES 3.0 should have all the necessary features to be able to flip and convert the framebuffer. // OpenGL ES 3.0 should have all the necessary features to be able to flip and convert the framebuffer.
this->willFlipAndConvertFramebufferOnGPU = true; this->_willConvertFramebufferOnGPU = true;
this->_enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing; this->_enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing;
this->_emulateShadowPolygon = CommonSettings.OpenGL_Emulation_ShadowPolygon; this->_emulateShadowPolygon = CommonSettings.OpenGL_Emulation_ShadowPolygon;