diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 301c6e5e5..ce63cc59f 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -274,7 +274,6 @@ static const char *fragmentShader_100 = {"\ { \n\ vec4 texColor = vec4(1.0, 1.0, 1.0, 1.0); \n\ vec4 fragColor; \n\ - float flagDepth; \n\ \n\ if(hasTexture) \n\ { \n\ @@ -599,7 +598,10 @@ static char OGLInit(void) error = _OGLRenderer->InitExtensions(); if (error != OGLERROR_NOERR) { - if (IsVersionSupported(2, 0, 0) && error == OGLERROR_SHADER_CREATE_ERROR) + if ( IsVersionSupported(2, 0, 0) && + (error == OGLERROR_SHADER_CREATE_ERROR || + error == OGLERROR_VERTEX_SHADER_PROGRAM_LOAD_ERROR || + error == OGLERROR_FRAGMENT_SHADER_PROGRAM_LOAD_ERROR) ) { INFO("OpenGL: Shaders are not working, even though they should be. Disabling 3D renderer.\n"); result = 0; @@ -884,10 +886,6 @@ Render3DError OpenGLRenderer_1_2::InitExtensions() Render3DError error = OGLERROR_NOERR; OGLRenderRef &OGLRef = *this->ref; - // Load shader programs - const std::string vertexShaderProgram = vertexShader_100; - const std::string fragmentShaderProgram = fragmentShader_100; - // Get OpenGL extensions std::set oglExtensionSet; this->GetExtensionSet(&oglExtensionSet); @@ -902,19 +900,30 @@ Render3DError OpenGLRenderer_1_2::InitExtensions() if (this->isShaderSupported) { - error = this->CreateShaders(&vertexShaderProgram, &fragmentShaderProgram); - if (error != OGLERROR_NOERR) + std::string vertexShaderProgram; + std::string fragmentShaderProgram; + + error = this->LoadShaderPrograms(&vertexShaderProgram, &fragmentShaderProgram); + if (error == OGLERROR_NOERR) { - this->isShaderSupported = false; - - if (error == OGLERROR_SHADER_CREATE_ERROR) + error = this->CreateShaders(&vertexShaderProgram, &fragmentShaderProgram); + if (error != OGLERROR_NOERR) { - return error; + this->isShaderSupported = false; + + if (error == OGLERROR_SHADER_CREATE_ERROR) + { + return error; + } + } + else + { + this->CreateToonTable(); } } else { - this->CreateToonTable(); + this->isShaderSupported = false; } } else @@ -1075,6 +1084,23 @@ void OpenGLRenderer_1_2::DestroyPBOs() this->isPBOSupported = false; } +Render3DError OpenGLRenderer_1_2::LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram) +{ + outVertexShaderProgram->clear(); + outFragmentShaderProgram->clear(); + + //not only does this hardware not work, it flat-out freezes the system. + //the problem is due to writing gl_FragDepth (it seems theres no way to successfully use it) + //so, we disable that feature. it still works pretty well. + if(isIntel965) + *outFragmentShaderProgram = std::string("#define WANT_DEPTHLOGIC\n"); + + *outVertexShaderProgram += std::string(vertexShader_100); + *outFragmentShaderProgram += std::string(fragmentShader_100); + + return OGLERROR_NOERR; +} + Render3DError OpenGLRenderer_1_2::SetupShaderIO() { OGLRenderRef &OGLRef = *this->ref; @@ -1098,15 +1124,7 @@ Render3DError OpenGLRenderer_1_2::CreateShaders(const std::string *vertexShaderP } const char *vertexShaderProgramChar = vertexShaderProgram->c_str(); - const char* sources[] = { "#define WANT_DEPTHLOGIC\n", vertexShaderProgramChar }; - - //not only does this hardware not work, it flat-out freezes the system. - //the problem is due to writing gl_FragDepth (it seems theres no way to successfully use it) - //so, we disable that feature. it still works pretty well. - if(isIntel965) - sources[0] = ""; - - glShaderSource(OGLRef.vertexShaderID, 2, (const GLchar **)sources, NULL); + glShaderSource(OGLRef.vertexShaderID, 1, (const GLchar **)&vertexShaderProgramChar, NULL); glCompileShader(OGLRef.vertexShaderID); if (!this->ValidateShaderCompile(OGLRef.vertexShaderID)) { @@ -2749,10 +2767,6 @@ Render3DError OpenGLRenderer_2_0::InitExtensions() Render3DError error = OGLERROR_NOERR; OGLRenderRef &OGLRef = *this->ref; - // Load shader programs - const std::string vertexShaderProgram = std::string(vertexShader_100); - const std::string fragmentShaderProgram = std::string(fragmentShader_100); - // Get OpenGL extensions std::set oglExtensionSet; this->GetExtensionSet(&oglExtensionSet); @@ -2760,24 +2774,27 @@ Render3DError OpenGLRenderer_2_0::InitExtensions() // Initialize OpenGL this->InitTables(); + // Load and create shaders. Return on any error, since a v2.0 driver will assume that shaders are available. this->isShaderSupported = true; + + std::string vertexShaderProgram; + std::string fragmentShaderProgram; + error = this->LoadShaderPrograms(&vertexShaderProgram, &fragmentShaderProgram); + if (error != OGLERROR_NOERR) + { + this->isShaderSupported = false; + return error; + } + error = this->CreateShaders(&vertexShaderProgram, &fragmentShaderProgram); if (error != OGLERROR_NOERR) { this->isShaderSupported = false; - - if (error == OGLERROR_SHADER_CREATE_ERROR) - { - // Return on OGLERROR_SHADER_CREATE_ERROR, since a v2.0 driver should be able to - // support shaders. - return error; - } - } - else - { - this->CreateToonTable(); + return error; } + this->CreateToonTable(); + this->isVBOSupported = true; this->CreateVBOs(); diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index feced97ec..b372db78e 100644 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -279,6 +279,7 @@ enum OGLTextureUnitID enum OGLErrorCode { OGLERROR_NOERR = RENDER3DERROR_NOERR, + OGLERROR_FEATURE_UNSUPPORTED, OGLERROR_VBO_UNSUPPORTED, OGLERROR_PBO_UNSUPPORTED, @@ -287,7 +288,10 @@ enum OGLErrorCode OGLERROR_FBO_UNSUPPORTED, OGLERROR_MULTISAMPLED_FBO_UNSUPPORTED, + OGLERROR_VERTEX_SHADER_PROGRAM_LOAD_ERROR, + OGLERROR_FRAGMENT_SHADER_PROGRAM_LOAD_ERROR, OGLERROR_SHADER_CREATE_ERROR, + OGLERROR_FBO_CREATE_ERROR }; @@ -436,6 +440,7 @@ protected: virtual Render3DError InitFinalRenderStates(const std::set *oglExtensionSet) = 0; virtual Render3DError InitTables() = 0; + virtual Render3DError LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram) = 0; virtual Render3DError SetupShaderIO() = 0; virtual Render3DError CreateToonTable() = 0; virtual Render3DError DestroyToonTable() = 0; @@ -508,6 +513,7 @@ protected: virtual Render3DError InitFinalRenderStates(const std::set *oglExtensionSet); virtual Render3DError InitTables(); + virtual Render3DError LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram); virtual Render3DError SetupShaderIO(); virtual Render3DError CreateToonTable(); virtual Render3DError DestroyToonTable(); diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 404cda4c1..f7af3f56a 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -123,36 +123,36 @@ static const char *fragmentShader_150 = {"\ void main() \n\ { \n\ vec4 texColor = vec4(1.0, 1.0, 1.0, 1.0); \n\ - vec4 flagColor; \n\ - float flagDepth; \n\ + vec4 fragColor; \n\ + float fragDepth; \n\ \n\ if(hasTexture) \n\ { \n\ texColor = texture(texMainRender, vtxTexCoord); \n\ } \n\ \n\ - flagColor = texColor; \n\ + fragColor = texColor; \n\ \n\ if(polygonMode == 0) \n\ { \n\ - flagColor = vtxColor * texColor; \n\ + fragColor = vtxColor * texColor; \n\ } \n\ else if(polygonMode == 1) \n\ { \n\ if (texColor.a == 0.0 || !hasTexture) \n\ { \n\ - flagColor.rgb = vtxColor.rgb; \n\ + fragColor.rgb = vtxColor.rgb; \n\ } \n\ else if (texColor.a == 1.0) \n\ { \n\ - flagColor.rgb = texColor.rgb; \n\ + fragColor.rgb = texColor.rgb; \n\ } \n\ else \n\ { \n\ - flagColor.rgb = texColor.rgb * (1.0-texColor.a) + vtxColor.rgb * texColor.a; \n\ + fragColor.rgb = texColor.rgb * (1.0-texColor.a) + vtxColor.rgb * texColor.a; \n\ } \n\ \n\ - flagColor.a = vtxColor.a; \n\ + fragColor.a = vtxColor.a; \n\ } \n\ else if(polygonMode == 2) \n\ { \n\ @@ -160,24 +160,24 @@ static const char *fragmentShader_150 = {"\ \n\ if (toonShadingMode == 0) \n\ { \n\ - flagColor.rgb = texColor.rgb * toonColor.rgb; \n\ + fragColor.rgb = texColor.rgb * toonColor.rgb; \n\ } \n\ else \n\ { \n\ - flagColor.rgb = texColor.rgb * vtxColor.rgb + toonColor.rgb; \n\ + fragColor.rgb = texColor.rgb * vtxColor.rgb + toonColor.rgb; \n\ } \n\ \n\ - flagColor.a = texColor.a * vtxColor.a; \n\ + fragColor.a = texColor.a * vtxColor.a; \n\ } \n\ else if(polygonMode == 3) \n\ { \n\ if (polyID != 0) \n\ { \n\ - flagColor = vtxColor; \n\ + fragColor = vtxColor; \n\ } \n\ } \n\ \n\ - if (flagColor.a == 0.0 || (enableAlphaTest && flagColor.a < alphaTestRef)) \n\ + if (fragColor.a == 0.0 || (enableAlphaTest && fragColor.a < alphaTestRef)) \n\ { \n\ discard; \n\ } \n\ @@ -185,15 +185,15 @@ static const char *fragmentShader_150 = {"\ if (oglWBuffer == 1) \n\ { \n\ // TODO \n\ - flagDepth = (vtxPosition.z / vtxPosition.w) * 0.5 + 0.5; \n\ + fragDepth = (vtxPosition.z / vtxPosition.w) * 0.5 + 0.5; \n\ } \n\ else \n\ { \n\ - flagDepth = (vtxPosition.z / vtxPosition.w) * 0.5 + 0.5; \n\ + fragDepth = (vtxPosition.z / vtxPosition.w) * 0.5 + 0.5; \n\ } \n\ \n\ - outFragColor = flagColor; \n\ - gl_FragDepth = flagDepth; \n\ + outFragColor = fragColor; \n\ + gl_FragDepth = fragDepth; \n\ } \n\ "}; @@ -220,10 +220,6 @@ Render3DError OpenGLRenderer_3_2::InitExtensions() Render3DError error = OGLERROR_NOERR; OGLRenderRef &OGLRef = *this->ref; - // Load shader programs - const std::string vertexShaderProgram = vertexShader_150; - const std::string fragmentShaderProgram = fragmentShader_150; - // Get OpenGL extensions std::set oglExtensionSet; this->GetExtensionSet(&oglExtensionSet); @@ -231,24 +227,27 @@ Render3DError OpenGLRenderer_3_2::InitExtensions() // Initialize OpenGL this->InitTables(); + // Load and create shaders. Return on any error, since v3.2 Core Profile makes shaders mandatory. this->isShaderSupported = true; + + std::string vertexShaderProgram; + std::string fragmentShaderProgram; + error = this->LoadShaderPrograms(&vertexShaderProgram, &fragmentShaderProgram); + if (error != OGLERROR_NOERR) + { + this->isShaderSupported = false; + return error; + } + error = this->CreateShaders(&vertexShaderProgram, &fragmentShaderProgram); if (error != OGLERROR_NOERR) { this->isShaderSupported = false; - - if (error == OGLERROR_SHADER_CREATE_ERROR) - { - // Return on OGLERROR_SHADER_CREATE_ERROR, since a v2.0 driver should be able to - // support shaders. - return error; - } - } - else - { - this->CreateToonTable(); + return error; } + this->CreateToonTable(); + this->isVBOSupported = true; this->CreateVBOs(); @@ -258,19 +257,14 @@ Render3DError OpenGLRenderer_3_2::InitExtensions() this->isVAOSupported = true; this->CreateVAOs(); + // Load and create FBOs. Return on any error, since v3.2 Core Profile makes FBOs mandatory. this->isFBOSupported = true; error = this->CreateFBOs(); if (error != OGLERROR_NOERR) { OGLRef.fboFinalOutputID = 0; this->isFBOSupported = false; - - if (error == OGLERROR_FBO_CREATE_ERROR) - { - // Return on OGLERROR_FBO_CREATE_ERROR, since a v3.0 driver should be able to - // support FBOs. - return error; - } + return error; } this->isMultisampledFBOSupported = true; @@ -489,6 +483,14 @@ void OpenGLRenderer_3_2::DestroyVAOs() this->isVAOSupported = false; } +Render3DError OpenGLRenderer_3_2::LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram) +{ + *outVertexShaderProgram = std::string(vertexShader_150); + *outFragmentShaderProgram = std::string(fragmentShader_150); + + return OGLERROR_NOERR; +} + Render3DError OpenGLRenderer_3_2::SetupShaderIO() { OGLRenderRef &OGLRef = *this->ref; diff --git a/desmume/src/OGLRender_3_2.h b/desmume/src/OGLRender_3_2.h index 79a78efb1..036bc39e9 100644 --- a/desmume/src/OGLRender_3_2.h +++ b/desmume/src/OGLRender_3_2.h @@ -68,6 +68,7 @@ protected: virtual Render3DError CreateVAOs(); virtual void DestroyVAOs(); + virtual Render3DError LoadShaderPrograms(std::string *outVertexShaderProgram, std::string *outFragmentShaderProgram); virtual Render3DError SetupShaderIO(); virtual void GetExtensionSet(std::set *oglExtensionSet);