OpenGL Renderer: More FBO rework.

This commit is contained in:
rogerman 2024-07-19 14:38:05 -07:00
parent 60385bd099
commit 8b5ac56d66
3 changed files with 248 additions and 152 deletions

View File

@ -2835,12 +2835,15 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
// Set up FBOs // Set up FBOs
glGenFramebuffersEXT(1, &OGLRef.fboClearImageID); glGenFramebuffersEXT(1, &OGLRef.fboClearImageID);
glGenFramebuffersEXT(1, &OGLRef.fboRenderID); glGenFramebuffersEXT(1, &OGLRef.fboRenderID);
glGenFramebuffersEXT(1, &OGLRef.fboRenderMutableID);
glGenFramebuffersEXT(1, &OGLRef.fboColorOutMainID); glGenFramebuffersEXT(1, &OGLRef.fboColorOutMainID);
glGenFramebuffersEXT(1, &OGLRef.fboColorOutWorkingID); glGenFramebuffersEXT(1, &OGLRef.fboColorOutWorkingID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboColorOutMainID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboColorOutMainID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texGColorID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE) if (glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE)
{ {
@ -2871,8 +2874,8 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboClearImageID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboClearImageID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIColorID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_CI_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_FOGATTRIBUTES_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIFogAttrID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_CI_FOGATTRIBUTES_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIFogAttrID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
@ -2888,6 +2891,26 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderMutableID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_POLYID_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGPolyID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_FOGATTRIBUTES_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGFogAttrID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_WORKING_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{
INFO("OpenGL: Failed to create FBOs!\n");
this->DestroyFBOs();
return OGLERROR_FBO_CREATE_ERROR;
}
// Assign the default read/draw buffers.
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_POLYID_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGPolyID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_POLYID_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGPolyID, 0);
@ -2909,6 +2932,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
OGLRef.selectedRenderingFBO = OGLRef.fboRenderID; OGLRef.selectedRenderingFBO = OGLRef.fboRenderID;
OGLRef.selectedRenderingMutableFBO = OGLRef.fboRenderMutableID;
INFO("OpenGL: Successfully created FBOs.\n"); INFO("OpenGL: Successfully created FBOs.\n");
return OGLERROR_NOERR; return OGLERROR_NOERR;
@ -2926,8 +2950,9 @@ void OpenGLRenderer_1_2::DestroyFBOs()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID); glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID); glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
glDeleteFramebuffers(1, &OGLRef.fboColorOutMainID); glDeleteFramebuffersEXT(1, &OGLRef.fboRenderMutableID);
glDeleteFramebuffers(1, &OGLRef.fboColorOutWorkingID); glDeleteFramebuffersEXT(1, &OGLRef.fboColorOutMainID);
glDeleteFramebuffersEXT(1, &OGLRef.fboColorOutWorkingID);
glDeleteTextures(1, &OGLRef.texCIColorID); glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID); glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID); glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
@ -2975,6 +3000,8 @@ Render3DError OpenGLRenderer_1_2::CreateMultisampledFBO(GLsizei numSamples)
// Set up multisampled rendering FBO // Set up multisampled rendering FBO
glGenFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderID); glGenFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderID);
glGenFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderMutableID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, OGL_POLYID_ATTACHMENT_ID, GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, OGL_POLYID_ATTACHMENT_ID, GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
@ -2994,6 +3021,25 @@ Render3DError OpenGLRenderer_1_2::CreateMultisampledFBO(GLsizei numSamples)
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderMutableID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, OGL_POLYID_ATTACHMENT_ID, GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, OGL_FOGATTRIBUTES_ATTACHMENT_ID, GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, OGL_WORKING_ATTACHMENT_ID, GL_RENDERBUFFER_EXT, OGLRef.rboMSGWorkingID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{
INFO("OpenGL: Failed to create multisampled FBO!\n");
this->DestroyMultisampledFBO();
return OGLERROR_FBO_CREATE_ERROR;
}
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
INFO("OpenGL: Successfully created multisampled FBO.\n"); INFO("OpenGL: Successfully created multisampled FBO.\n");
@ -3011,6 +3057,7 @@ void OpenGLRenderer_1_2::DestroyMultisampledFBO()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderID); glDeleteFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderID);
glDeleteFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderMutableID);
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGColorID); glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGColorID);
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGWorkingID); glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGWorkingID);
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGPolyID); glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGPolyID);
@ -3111,14 +3158,14 @@ Render3DError OpenGLRenderer_1_2::CreateGeometryPrograms()
std::stringstream shaderFlags; std::stringstream shaderFlags;
shaderFlags << "#define USE_TEXTURE_SMOOTHING " << ((this->_enableTextureSmoothing) ? 1 : 0) << "\n"; shaderFlags << "#define USE_TEXTURE_SMOOTHING " << ((this->_enableTextureSmoothing) ? 1 : 0) << "\n";
shaderFlags << "#define USE_NDS_DEPTH_CALCULATION " << ((this->_emulateNDSDepthCalculation) ? 1 : 0) << "\n"; shaderFlags << "#define USE_NDS_DEPTH_CALCULATION " << ((this->_emulateNDSDepthCalculation) ? 1 : 0) << "\n";
shaderFlags << "#define USE_DEPTH_LEQUAL_POLYGON_FACING " << ((this->_emulateDepthLEqualPolygonFacing && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n"; shaderFlags << "#define USE_DEPTH_LEQUAL_POLYGON_FACING " << ((this->_emulateDepthLEqualPolygonFacing && this->_isDepthLEqualPolygonFacingSupported) ? 1 : 0) << "\n";
shaderFlags << "\n"; shaderFlags << "\n";
shaderFlags << "#define ENABLE_W_DEPTH " << ((programFlags.EnableWDepth) ? 1 : 0) << "\n"; shaderFlags << "#define ENABLE_W_DEPTH " << ((programFlags.EnableWDepth) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_ALPHA_TEST " << ((programFlags.EnableAlphaTest) ? "true\n" : "false\n"); shaderFlags << "#define ENABLE_ALPHA_TEST " << ((programFlags.EnableAlphaTest) ? "true\n" : "false\n");
shaderFlags << "#define ENABLE_TEXTURE_SAMPLING " << ((programFlags.EnableTextureSampling) ? "true\n" : "false\n"); shaderFlags << "#define ENABLE_TEXTURE_SAMPLING " << ((programFlags.EnableTextureSampling) ? "true\n" : "false\n");
shaderFlags << "#define TOON_SHADING_MODE " << ((programFlags.ToonShadingMode) ? 1 : 0) << "\n"; 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_FOG " << ((programFlags.EnableFog && this->_deviceInfo.isFogSupported) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_EDGE_MARK " << ((programFlags.EnableEdgeMark && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n"; shaderFlags << "#define ENABLE_EDGE_MARK " << ((programFlags.EnableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0) << "\n";
shaderFlags << "#define DRAW_MODE_OPAQUE " << ((programFlags.OpaqueDrawMode && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n"; shaderFlags << "#define DRAW_MODE_OPAQUE " << ((programFlags.OpaqueDrawMode && this->isVBOSupported && this->isFBOSupported) ? 1 : 0) << "\n";
shaderFlags << "\n"; shaderFlags << "\n";
shaderFlags << "#define ATTACHMENT_WORKING_BUFFER " << GeometryAttachmentWorkingBuffer[programFlags.DrawBuffersMode] << "\n"; shaderFlags << "#define ATTACHMENT_WORKING_BUFFER " << GeometryAttachmentWorkingBuffer[programFlags.DrawBuffersMode] << "\n";
@ -3952,13 +3999,12 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
{ {
// Just downsample the color buffer now so that we have some texture data to sample from in the non-multisample shader. // Just downsample the color buffer now so that we have some texture data to sample from in the non-multisample shader.
// This is not perfectly pixel accurate, but it's better than nothing. // This is not perfectly pixel accurate, but it's better than nothing.
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboRenderID); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboColorOutMainID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
} }
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingMutableFBO);
glUseProgram(OGLRef.programGeometryZeroDstAlphaID); glUseProgram(OGLRef.programGeometryZeroDstAlphaID);
glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight); glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight);
glDisable(GL_BLEND); glDisable(GL_BLEND);
@ -4001,6 +4047,7 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
OGLGeometryFlags oldGProgramFlags = this->_geometryProgramFlags; OGLGeometryFlags oldGProgramFlags = this->_geometryProgramFlags;
this->_geometryProgramFlags.EnableEdgeMark = 0; this->_geometryProgramFlags.EnableEdgeMark = 0;
this->_geometryProgramFlags.EnableFog = 0; this->_geometryProgramFlags.EnableFog = 0;
this->_geometryProgramFlags.OpaqueDrawMode = 0;
this->_SetupGeometryShaders(this->_geometryProgramFlags); this->_SetupGeometryShaders(this->_geometryProgramFlags);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
@ -4018,7 +4065,7 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
// Restore OpenGL states back to normal. // Restore OpenGL states back to normal.
this->_geometryProgramFlags = oldGProgramFlags; this->_geometryProgramFlags = oldGProgramFlags;
this->_SetupGeometryShaders(this->_geometryProgramFlags); this->_SetupGeometryShaders(this->_geometryProgramFlags);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
glClear(GL_STENCIL_BUFFER_BIT); glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
@ -4046,15 +4093,11 @@ void OpenGLRenderer_1_2::_ResolveWorkingBackFacing()
} }
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboRenderID); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboColorOutWorkingID);
glReadBuffer(OGL_WORKING_ATTACHMENT_ID); glReadBuffer(OGL_WORKING_ATTACHMENT_ID);
glDrawBuffer(OGL_WORKING_ATTACHMENT_ID);
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Reset framebuffer targets
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
} }
@ -4069,7 +4112,7 @@ void OpenGLRenderer_1_2::_ResolveGeometry()
} }
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboRenderID); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboRenderMutableID);
if (this->isShaderSupported) if (this->isShaderSupported)
{ {
@ -4091,19 +4134,15 @@ void OpenGLRenderer_1_2::_ResolveGeometry()
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
// Reset framebuffer targets
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
} }
else else
{ {
// Blit the color buffer // Blit the color buffer
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
// Reset framebuffer targets
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
} }
// Reset framebuffer targets
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
} }
Render3DError OpenGLRenderer_1_2::ReadBackPixels() Render3DError OpenGLRenderer_1_2::ReadBackPixels()
@ -4372,7 +4411,7 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
this->_geometryProgramFlags.ToonShadingMode = renderState.DISP3DCNT.PolygonShading; this->_geometryProgramFlags.ToonShadingMode = renderState.DISP3DCNT.PolygonShading;
this->_geometryProgramFlags.EnableFog = (this->_enableFog && this->_deviceInfo.isFogSupported) ? 1 : 0; this->_geometryProgramFlags.EnableFog = (this->_enableFog && this->_deviceInfo.isFogSupported) ? 1 : 0;
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0; this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0;
this->_geometryProgramFlags.OpaqueDrawMode = (this->_isDepthLEqualPolygonFacingSupported) ? 1 : 0; this->_geometryProgramFlags.OpaqueDrawMode = 1;
this->_SetupGeometryShaders(this->_geometryProgramFlags); this->_SetupGeometryShaders(this->_geometryProgramFlags);
@ -4415,14 +4454,24 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
// Even with no polygons to draw, we always need to set these 3 flags so that // Even with no polygons to draw, we always need to set these 3 flags so that
// glDrawBuffers() can reference the correct set of FBO attachments using // glDrawBuffers() can reference the correct set of FBO attachments using
// OGLGeometryFlags.DrawBuffersMode. // OGLGeometryFlags.DrawBuffersMode.
this->_geometryProgramFlags.EnableFog = (this->_enableFog) ? 1 : 0; this->_geometryProgramFlags.EnableFog = (this->_enableFog && this->_deviceInfo.isFogSupported) ? 1 : 0;
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark) ? 1 : 0; this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0;
this->_geometryProgramFlags.OpaqueDrawMode = 1; this->_geometryProgramFlags.OpaqueDrawMode = 1;
} }
if (this->isFBOSupported) if (this->isFBOSupported)
{ {
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; if (this->_enableMultisampledRendering)
{
OGLRef.selectedRenderingFBO = OGLRef.fboMSIntermediateRenderID;
OGLRef.selectedRenderingMutableFBO = OGLRef.fboMSIntermediateRenderMutableID;
}
else
{
OGLRef.selectedRenderingFBO = OGLRef.fboRenderID;
OGLRef.selectedRenderingMutableFBO = OGLRef.fboRenderMutableID;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
if (this->isShaderSupported) if (this->isShaderSupported)
@ -4481,8 +4530,17 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry()
if (this->_clippedPolyOpaqueCount < this->_clippedPolyCount) if (this->_clippedPolyOpaqueCount < this->_clippedPolyCount)
{ {
// We are now rendering the transparent polys.
this->_geometryProgramFlags.OpaqueDrawMode = 0; this->_geometryProgramFlags.OpaqueDrawMode = 0;
// Geometry flags have changed, so we need to update shader uniforms and also
// update draw buffers based on the flags.
this->_SetupGeometryShaders(this->_geometryProgramFlags);
if (this->isFBOSupported && this->isShaderSupported)
{
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
}
if (this->_needsZeroDstAlphaPass && this->_emulateSpecialZeroAlphaBlending) if (this->_needsZeroDstAlphaPass && this->_emulateSpecialZeroAlphaBlending)
{ {
if (this->_clippedPolyOpaqueCount == 0) if (this->_clippedPolyOpaqueCount == 0)
@ -4508,12 +4566,6 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry()
glClearStencil(0); glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT); glClear(GL_STENCIL_BUFFER_BIT);
glStencilMask(0xFF); glStencilMask(0xFF);
this->_SetupGeometryShaders(this->_geometryProgramFlags);
if (this->isFBOSupported && this->isShaderSupported)
{
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
}
} }
if (this->_clippedPolyOpaqueCount == 0) if (this->_clippedPolyOpaqueCount == 0)
@ -4556,6 +4608,11 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
// Set up the postprocessing states // Set up the postprocessing states
if (this->isFBOSupported)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboColorOutMainID);
}
glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight); glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
@ -4616,7 +4673,6 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
glUseProgram(OGLRef.programEdgeMarkID); glUseProgram(OGLRef.programEdgeMarkID);
glUniform1i(OGLRef.uniformStateClearPolyID, this->_pendingRenderStates.clearPolyID); glUniform1i(OGLRef.uniformStateClearPolyID, this->_pendingRenderStates.clearPolyID);
glUniform1f(OGLRef.uniformStateClearDepth, this->_pendingRenderStates.clearDepth); glUniform1f(OGLRef.uniformStateClearDepth, this->_pendingRenderStates.clearDepth);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@ -4641,12 +4697,6 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
} }
OGLFogShaderID shaderID = this->_fogProgramMap[this->_fogProgramKey.key]; OGLFogShaderID shaderID = this->_fogProgramMap[this->_fogProgramKey.key];
if (this->isFBOSupported)
{
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
}
glUseProgram(shaderID.program); glUseProgram(shaderID.program);
glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, this->_pendingRenderStates.enableFogAlphaOnly); glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, this->_pendingRenderStates.enableFogAlphaOnly);
@ -4664,11 +4714,6 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA);
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX); glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
if (this->isFBOSupported)
{
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
}
} }
if (this->isVAOSupported) if (this->isVAOSupported)
@ -4708,7 +4753,7 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, opaquePolyID); this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, opaquePolyID);
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboClearImageID); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboClearImageID);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboRenderID); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboRenderMutableID);
// It might seem wasteful to be doing a separate glClear(GL_STENCIL_BUFFER_BIT) instead // It might seem wasteful to be doing a separate glClear(GL_STENCIL_BUFFER_BIT) instead
// of simply blitting the stencil buffer with everything else. // of simply blitting the stencil buffer with everything else.
@ -4737,77 +4782,67 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
if (this->_enableFog && this->_deviceInfo.isFogSupported) if (this->_enableFog && this->_deviceInfo.isFogSupported)
{ {
glReadBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID); glReadBuffer(OGL_CI_FOGATTRIBUTES_ATTACHMENT_ID);
glDrawBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID); glDrawBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID);
glBlitFramebufferEXT(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebufferEXT(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
} }
// Blit the color buffer. Do this last so that color attachment 0 is set to the read FBO. // Blit the color buffer. Do this last so that color attachment 0 is set to the read FBO.
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_CI_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBlitFramebufferEXT(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); glBlitFramebufferEXT(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
} }
else else
{ {
glBlitFramebufferEXT(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); glBlitFramebufferEXT(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
} }
if (this->isMultisampledFBOSupported) if (this->_enableMultisampledRendering)
{ {
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID) glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderMutableID);
// See above comment for why we need to get clear the stencil buffer separately.
glClearStencil(opaquePolyID);
glClear(GL_STENCIL_BUFFER_BIT);
if (this->isShaderSupported)
{ {
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboRenderID); if (this->_emulateDepthLEqualPolygonFacing && this->_isDepthLEqualPolygonFacingSupported)
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
// See above comment for why we need to get clear the stencil buffer separately.
glClearStencil(opaquePolyID);
glClear(GL_STENCIL_BUFFER_BIT);
if (this->isShaderSupported)
{ {
if (this->_emulateDepthLEqualPolygonFacing && this->_isDepthLEqualPolygonFacingSupported) glDrawBuffer(OGL_WORKING_ATTACHMENT_ID);
{ glClearColor(0.0, 0.0, 0.0, 0.0);
glDrawBuffer(OGL_WORKING_ATTACHMENT_ID); glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
}
if (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported)
{
glDrawBuffer(OGL_POLYID_ATTACHMENT_ID);
glClearColor((GLfloat)opaquePolyID/63.0f, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
if (this->_enableFog && this->_deviceInfo.isFogSupported)
{
glReadBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID);
glDrawBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID);
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
// Blit the color and depth buffers. Do this last so that color attachment 0 is set to the read FBO.
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
} }
else
if (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported)
{ {
// Blit the color and depth buffers. glDrawBuffer(OGL_POLYID_ATTACHMENT_ID);
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); glClearColor((GLfloat)opaquePolyID/63.0f, 0.0, 0.0, 1.0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO); glClear(GL_COLOR_BUFFER_BIT);
} }
if (this->_enableFog && this->_deviceInfo.isFogSupported)
{
glReadBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID);
glDrawBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID);
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
// Blit the color and depth buffers. Do this last so that color attachment 0 is set to the read FBO.
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
}
else
{
// Blit the color and depth buffers.
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
} }
} }
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
@ -4815,14 +4850,10 @@ Render3DError OpenGLRenderer_1_2::ClearUsingValues(const Color4u8 &clearColor666
{ {
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
if (this->isFBOSupported)
{
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
}
if (this->isShaderSupported && this->isFBOSupported) if (this->isShaderSupported && this->isFBOSupported)
{ {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingMutableFBO);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glClearColor(divide6bitBy63_LUT[clearColor6665.r], divide6bitBy63_LUT[clearColor6665.g], divide6bitBy63_LUT[clearColor6665.b], divide5bitBy31_LUT[clearColor6665.a]); glClearColor(divide6bitBy63_LUT[clearColor6665.r], divide6bitBy63_LUT[clearColor6665.g], divide6bitBy63_LUT[clearColor6665.b], divide5bitBy31_LUT[clearColor6665.a]);
glClearDepth((GLclampd)clearAttributes.depth / (GLclampd)0x00FFFFFF); glClearDepth((GLclampd)clearAttributes.depth / (GLclampd)0x00FFFFFF);
@ -4850,7 +4881,7 @@ Render3DError OpenGLRenderer_1_2::ClearUsingValues(const Color4u8 &clearColor666
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
this->_needsZeroDstAlphaPass = (clearColor6665.a == 0); this->_needsZeroDstAlphaPass = (clearColor6665.a == 0);
} }
else else
@ -5646,7 +5677,7 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, co
this->_geometryProgramFlags.ToonShadingMode = renderState.DISP3DCNT.PolygonShading; this->_geometryProgramFlags.ToonShadingMode = renderState.DISP3DCNT.PolygonShading;
this->_geometryProgramFlags.EnableFog = (this->_enableFog && this->_deviceInfo.isFogSupported) ? 1 : 0; this->_geometryProgramFlags.EnableFog = (this->_enableFog && this->_deviceInfo.isFogSupported) ? 1 : 0;
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0; this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0;
this->_geometryProgramFlags.OpaqueDrawMode = (this->_isDepthLEqualPolygonFacingSupported) ? 1 : 0; this->_geometryProgramFlags.OpaqueDrawMode = 1;
this->_SetupGeometryShaders(this->_geometryProgramFlags); this->_SetupGeometryShaders(this->_geometryProgramFlags);
@ -5671,14 +5702,24 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, co
// Even with no polygons to draw, we always need to set these 3 flags so that // Even with no polygons to draw, we always need to set these 3 flags so that
// glDrawBuffers() can reference the correct set of FBO attachments using // glDrawBuffers() can reference the correct set of FBO attachments using
// OGLGeometryFlags.DrawBuffersMode. // OGLGeometryFlags.DrawBuffersMode.
this->_geometryProgramFlags.EnableFog = (this->_enableFog) ? 1 : 0; this->_geometryProgramFlags.EnableFog = (this->_enableFog && this->_deviceInfo.isFogSupported) ? 1 : 0;
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark) ? 1 : 0; this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark && this->_deviceInfo.isEdgeMarkSupported) ? 1 : 0;
this->_geometryProgramFlags.OpaqueDrawMode = 1; this->_geometryProgramFlags.OpaqueDrawMode = 1;
} }
if (this->isFBOSupported) if (this->isFBOSupported)
{ {
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; if (this->_enableMultisampledRendering)
{
OGLRef.selectedRenderingFBO = OGLRef.fboMSIntermediateRenderID;
OGLRef.selectedRenderingMutableFBO = OGLRef.fboMSIntermediateRenderMutableID;
}
else
{
OGLRef.selectedRenderingFBO = OGLRef.fboRenderID;
OGLRef.selectedRenderingMutableFBO = OGLRef.fboRenderMutableID;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]); glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);

View File

@ -368,15 +368,21 @@ EXTERNOGLEXT(PFNGLDELETERENDERBUFFERSEXTPROC, glDeleteRenderbuffersEXT)
// Assign the FBO attachments for the main geometry render // Assign the FBO attachments for the main geometry render
#if defined(GL_VERSION_3_0) || defined(GL_ES_VERSION_3_0) #if defined(GL_VERSION_3_0) || defined(GL_ES_VERSION_3_0)
#define OGL_COLOROUT_ATTACHMENT_ID GL_COLOR_ATTACHMENT0 #define OGL_COLOROUT_ATTACHMENT_ID GL_COLOR_ATTACHMENT0
#define OGL_WORKING_ATTACHMENT_ID GL_COLOR_ATTACHMENT3 #define OGL_WORKING_ATTACHMENT_ID GL_COLOR_ATTACHMENT1
#define OGL_POLYID_ATTACHMENT_ID GL_COLOR_ATTACHMENT1 #define OGL_POLYID_ATTACHMENT_ID GL_COLOR_ATTACHMENT2
#define OGL_FOGATTRIBUTES_ATTACHMENT_ID GL_COLOR_ATTACHMENT2 #define OGL_FOGATTRIBUTES_ATTACHMENT_ID GL_COLOR_ATTACHMENT3
#define OGL_CI_COLOROUT_ATTACHMENT_ID GL_COLOR_ATTACHMENT0
#define OGL_CI_FOGATTRIBUTES_ATTACHMENT_ID GL_COLOR_ATTACHMENT1
#else #else
#define OGL_COLOROUT_ATTACHMENT_ID GL_COLOR_ATTACHMENT0_EXT #define OGL_COLOROUT_ATTACHMENT_ID GL_COLOR_ATTACHMENT0_EXT
#define OGL_WORKING_ATTACHMENT_ID GL_COLOR_ATTACHMENT3_EXT #define OGL_WORKING_ATTACHMENT_ID GL_COLOR_ATTACHMENT1_EXT
#define OGL_POLYID_ATTACHMENT_ID GL_COLOR_ATTACHMENT1_EXT #define OGL_POLYID_ATTACHMENT_ID GL_COLOR_ATTACHMENT2_EXT
#define OGL_FOGATTRIBUTES_ATTACHMENT_ID GL_COLOR_ATTACHMENT2_EXT #define OGL_FOGATTRIBUTES_ATTACHMENT_ID GL_COLOR_ATTACHMENT3_EXT
#define OGL_CI_COLOROUT_ATTACHMENT_ID GL_COLOR_ATTACHMENT0_EXT
#define OGL_CI_FOGATTRIBUTES_ATTACHMENT_ID GL_COLOR_ATTACHMENT1_EXT
#endif #endif
enum OpenGLVariantID enum OpenGLVariantID
@ -628,10 +634,13 @@ struct OGLRenderRef
GLuint fboClearImageID; GLuint fboClearImageID;
GLuint fboRenderID; GLuint fboRenderID;
GLuint fboRenderMutableID;
GLuint fboColorOutMainID; GLuint fboColorOutMainID;
GLuint fboColorOutWorkingID; GLuint fboColorOutWorkingID;
GLuint fboMSIntermediateRenderID; GLuint fboMSIntermediateRenderID;
GLuint fboMSIntermediateRenderMutableID;
GLuint selectedRenderingFBO; GLuint selectedRenderingFBO;
GLuint selectedRenderingMutableFBO;
// Shader states // Shader states
GLuint vertexGeometryShaderID; GLuint vertexGeometryShaderID;

View File

@ -924,12 +924,14 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
// Set up FBOs // Set up FBOs
glGenFramebuffers(1, &OGLRef.fboClearImageID); glGenFramebuffers(1, &OGLRef.fboClearImageID);
glGenFramebuffers(1, &OGLRef.fboRenderID); glGenFramebuffers(1, &OGLRef.fboRenderID);
glGenFramebuffers(1, &OGLRef.fboRenderMutableID);
glGenFramebuffers(1, &OGLRef.fboColorOutMainID); glGenFramebuffers(1, &OGLRef.fboColorOutMainID);
glGenFramebuffers(1, &OGLRef.fboColorOutWorkingID); glGenFramebuffers(1, &OGLRef.fboColorOutWorkingID);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboColorOutMainID); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboColorOutMainID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texGColorID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{ {
@ -960,8 +962,8 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboClearImageID); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboClearImageID);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIColorID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_CI_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_FOGATTRIBUTES_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIFogAttrID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_CI_FOGATTRIBUTES_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIFogAttrID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
@ -976,6 +978,25 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderMutableID);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_POLYID_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGPolyID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_FOGATTRIBUTES_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGFogAttrID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_WORKING_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
INFO("OpenGL: Failed to create FBOs!\n");
this->DestroyFBOs();
return OGLERROR_FBO_CREATE_ERROR;
}
// Assign the default read/draw buffers.
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_POLYID_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGPolyID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_POLYID_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGPolyID, 0);
@ -996,6 +1017,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
OGLRef.selectedRenderingFBO = OGLRef.fboRenderID; OGLRef.selectedRenderingFBO = OGLRef.fboRenderID;
OGLRef.selectedRenderingMutableFBO = OGLRef.fboRenderMutableID;
INFO("OpenGL: Successfully created FBOs.\n"); INFO("OpenGL: Successfully created FBOs.\n");
return OGLERROR_NOERR; return OGLERROR_NOERR;
@ -1013,6 +1035,7 @@ void OpenGLRenderer_3_2::DestroyFBOs()
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboClearImageID); glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
glDeleteFramebuffers(1, &OGLRef.fboRenderID); glDeleteFramebuffers(1, &OGLRef.fboRenderID);
glDeleteFramebuffers(1, &OGLRef.fboRenderMutableID);
glDeleteFramebuffers(1, &OGLRef.fboColorOutMainID); glDeleteFramebuffers(1, &OGLRef.fboColorOutMainID);
glDeleteFramebuffers(1, &OGLRef.fboColorOutWorkingID); glDeleteFramebuffers(1, &OGLRef.fboColorOutWorkingID);
glDeleteTextures(1, &OGLRef.texCIColorID); glDeleteTextures(1, &OGLRef.texCIColorID);
@ -1084,8 +1107,37 @@ Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO(GLsizei numSamples)
// Set up multisampled rendering FBO // Set up multisampled rendering FBO
glGenFramebuffers(1, &OGLRef.fboMSIntermediateRenderID); glGenFramebuffers(1, &OGLRef.fboMSIntermediateRenderID);
glGenFramebuffers(1, &OGLRef.fboMSIntermediateRenderMutableID);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
#ifdef GL_VERSION_3_2
if (this->willUsePerSampleZeroDstPass)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D_MULTISAMPLE, OGLRef.texMSGColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_WORKING_ATTACHMENT_ID, GL_TEXTURE_2D_MULTISAMPLE, OGLRef.texMSGWorkingID, 0);
}
else
#endif
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, OGL_COLOROUT_ATTACHMENT_ID, GL_RENDERBUFFER, OGLRef.rboMSGColorID);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, OGL_WORKING_ATTACHMENT_ID, GL_RENDERBUFFER, OGLRef.rboMSGWorkingID);
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, OGL_POLYID_ATTACHMENT_ID, GL_RENDERBUFFER, OGLRef.rboMSGPolyID);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, OGL_FOGATTRIBUTES_ATTACHMENT_ID, GL_RENDERBUFFER, OGLRef.rboMSGFogAttrID);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilID);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
INFO("OpenGL: Failed to create multisampled FBO. Multisample antialiasing will be disabled.\n");
this->DestroyMultisampledFBO();
return OGLERROR_FBO_CREATE_ERROR;
}
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderMutableID);
#ifdef GL_VERSION_3_2 #ifdef GL_VERSION_3_2
if (this->willUsePerSampleZeroDstPass) if (this->willUsePerSampleZeroDstPass)
{ {
@ -1128,6 +1180,7 @@ void OpenGLRenderer_3_2::DestroyMultisampledFBO()
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboMSIntermediateRenderID); glDeleteFramebuffers(1, &OGLRef.fboMSIntermediateRenderID);
glDeleteFramebuffers(1, &OGLRef.fboMSIntermediateRenderMutableID);
glDeleteTextures(1, &OGLRef.texMSGColorID); glDeleteTextures(1, &OGLRef.texMSGColorID);
glDeleteTextures(1, &OGLRef.texMSGWorkingID); glDeleteTextures(1, &OGLRef.texMSGWorkingID);
glDeleteRenderbuffers(1, &OGLRef.rboMSGColorID); glDeleteRenderbuffers(1, &OGLRef.rboMSGColorID);
@ -2061,13 +2114,12 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
{ {
// Just downsample the color buffer now so that we have some texture data to sample from in the non-multisample shader. // Just downsample the color buffer now so that we have some texture data to sample from in the non-multisample shader.
// This is not perfectly pixel accurate, but it's better than nothing. // This is not perfectly pixel accurate, but it's better than nothing.
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboColorOutMainID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBlitFramebuffer(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
} }
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingMutableFBO);
glUseProgram((isRunningMSAAWithPerSampleShading) ? OGLRef.programMSGeometryZeroDstAlphaID : OGLRef.programGeometryZeroDstAlphaID); glUseProgram((isRunningMSAAWithPerSampleShading) ? OGLRef.programMSGeometryZeroDstAlphaID : OGLRef.programGeometryZeroDstAlphaID);
glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight); glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight);
glDisable(GL_BLEND); glDisable(GL_BLEND);
@ -2089,6 +2141,7 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
OGLGeometryFlags oldGProgramFlags = this->_geometryProgramFlags; OGLGeometryFlags oldGProgramFlags = this->_geometryProgramFlags;
this->_geometryProgramFlags.EnableEdgeMark = 0; this->_geometryProgramFlags.EnableEdgeMark = 0;
this->_geometryProgramFlags.EnableFog = 0; this->_geometryProgramFlags.EnableFog = 0;
this->_geometryProgramFlags.OpaqueDrawMode = 0;
this->_SetupGeometryShaders(this->_geometryProgramFlags); this->_SetupGeometryShaders(this->_geometryProgramFlags);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
@ -2106,7 +2159,7 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
// Restore OpenGL states back to normal. // Restore OpenGL states back to normal.
this->_geometryProgramFlags = oldGProgramFlags; this->_geometryProgramFlags = oldGProgramFlags;
this->_SetupGeometryShaders(this->_geometryProgramFlags); this->_SetupGeometryShaders(this->_geometryProgramFlags);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0); glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
@ -2134,18 +2187,13 @@ void OpenGLRenderer_3_2::_ResolveWorkingBackFacing()
} }
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID); glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboColorOutWorkingID);
glReadBuffer(OGL_WORKING_ATTACHMENT_ID); glReadBuffer(OGL_WORKING_ATTACHMENT_ID);
glDrawBuffer(OGL_WORKING_ATTACHMENT_ID);
glBlitFramebuffer(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Reset framebuffer targets
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
} }
void OpenGLRenderer_3_2::_ResolveGeometry() void OpenGLRenderer_3_2::_ResolveGeometry()
@ -2158,7 +2206,7 @@ void OpenGLRenderer_3_2::_ResolveGeometry()
} }
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID); glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboRenderMutableID);
if (this->_enableEdgeMark) if (this->_enableEdgeMark)
{ {
@ -2181,7 +2229,6 @@ void OpenGLRenderer_3_2::_ResolveGeometry()
// Reset framebuffer targets // Reset framebuffer targets
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
} }
Render3DError OpenGLRenderer_3_2::ReadBackPixels() Render3DError OpenGLRenderer_3_2::ReadBackPixels()
@ -2464,7 +2511,17 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State &renderState, co
this->_geometryProgramFlags.OpaqueDrawMode = 1; this->_geometryProgramFlags.OpaqueDrawMode = 1;
} }
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; if (this->_enableMultisampledRendering)
{
OGLRef.selectedRenderingFBO = OGLRef.fboMSIntermediateRenderID;
OGLRef.selectedRenderingMutableFBO = OGLRef.fboMSIntermediateRenderMutableID;
}
else
{
OGLRef.selectedRenderingFBO = OGLRef.fboRenderID;
OGLRef.selectedRenderingMutableFBO = OGLRef.fboRenderMutableID;
}
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO); glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]); glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
@ -2487,6 +2544,7 @@ Render3DError OpenGLRenderer_3_2::PostprocessFramebuffer()
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
// Set up the postprocessing states // Set up the postprocessing states
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboColorOutMainID);
glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight); glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
@ -2524,7 +2582,6 @@ Render3DError OpenGLRenderer_3_2::PostprocessFramebuffer()
else else
{ {
glUseProgram(OGLRef.programEdgeMarkID); glUseProgram(OGLRef.programEdgeMarkID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@ -2545,7 +2602,6 @@ Render3DError OpenGLRenderer_3_2::PostprocessFramebuffer()
} }
OGLFogShaderID shaderID = this->_fogProgramMap[this->_fogProgramKey.key]; OGLFogShaderID shaderID = this->_fogProgramMap[this->_fogProgramKey.key];
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glUseProgram(shaderID.program); glUseProgram(shaderID.program);
glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -2576,8 +2632,7 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, opaquePolyID); this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, opaquePolyID);
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboClearImageID); glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboClearImageID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboRenderMutableID);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
if (this->_emulateDepthLEqualPolygonFacing) if (this->_emulateDepthLEqualPolygonFacing)
{ {
@ -2595,25 +2650,20 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
if (this->_enableFog) if (this->_enableFog)
{ {
// Blit the fog buffer // Blit the fog buffer
glReadBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID); glReadBuffer(OGL_CI_FOGATTRIBUTES_ATTACHMENT_ID);
glDrawBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID); glDrawBuffer(OGL_FOGATTRIBUTES_ATTACHMENT_ID);
glBlitFramebuffer(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
} }
// Blit the color and depth/stencil buffers. Do this last so that color attachment 0 is set to the read FBO. // Blit the color and depth/stencil buffers. Do this last so that color attachment 0 is set to the read FBO.
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_CI_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBlitFramebuffer(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID); if (this->_enableMultisampledRendering)
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID)
{ {
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboRenderID); glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboRenderID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.selectedRenderingFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderMutableID);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
if (this->_emulateDepthLEqualPolygonFacing) if (this->_emulateDepthLEqualPolygonFacing)
{ {
@ -2638,20 +2688,16 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
glBlitFramebuffer(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
} }
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
Render3DError OpenGLRenderer_3_2::ClearUsingValues(const Color4u8 &clearColor6665, const FragmentAttributes &clearAttributes) Render3DError OpenGLRenderer_3_2::ClearUsingValues(const Color4u8 &clearColor6665, const FragmentAttributes &clearAttributes)
{ {
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
const GLfloat oglColor[4] = {divide6bitBy63_LUT[clearColor6665.r], divide6bitBy63_LUT[clearColor6665.g], divide6bitBy63_LUT[clearColor6665.b], divide5bitBy31_LUT[clearColor6665.a]}; const GLfloat oglColor[4] = {divide6bitBy63_LUT[clearColor6665.r], divide6bitBy63_LUT[clearColor6665.g], divide6bitBy63_LUT[clearColor6665.b], divide5bitBy31_LUT[clearColor6665.a]};
glClearBufferfv(GL_COLOR, 0, oglColor); glClearBufferfv(GL_COLOR, 0, oglColor);