From 86a29d768a1888b5f600bf0cc0d8e0bfa69ba6b6 Mon Sep 17 00:00:00 2001 From: rogerman Date: Wed, 10 Jul 2024 13:59:02 -0700 Subject: [PATCH] OpenGL ES Renderer: Do some minor changes/fixes. - Fix a bug where _isShaderFixedLocationSupported wasn't being set to true, causing shaders to fail. - OpenGL version checks now account for non-compliant ES drivers that contain text before the version number. - Manually set the default read/draw buffers for all FBOs upon creation. We shouldn't need to do this, since they should always be set later, but just in case... - Add missing GL_BGRA macro. - Tidy up the OpenGL naming in some error strings. --- desmume/src/OGLRender.cpp | 63 ++++++++++++++++++++++++----------- desmume/src/OGLRender.h | 6 ++++ desmume/src/OGLRender_3_2.cpp | 8 +++++ desmume/src/OGLRender_ES3.cpp | 3 ++ 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 515d55e93..1ce3b26b2 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -754,30 +754,46 @@ static void OGLGetDriverVersion(const char *oglVersionString, // First, check for the dot in the revision string. There should be at // least one present. - const char *versionStrEnd = strstr(oglVersionString, "."); - if (versionStrEnd == NULL) + const char *versionStrDot = strstr(oglVersionString, "."); + if (versionStrDot == NULL) { return; } - // Next, check for the space before the vendor-specific info (if present). - versionStrEnd = strstr(oglVersionString, " "); - if (versionStrEnd == NULL) + // Next, check for a space that is after the dot, but before the vendor-specific info (if present). + versionStringLength = strlen(oglVersionString); // Set our default string length here + const size_t endCheckLength = versionStringLength - (versionStrDot - oglVersionString); // Maximum possible length to check + const char *checkStringLimit = (endCheckLength < 10) ? versionStrDot + endCheckLength : versionStrDot + 10; // But we're going to limit ourselves to checking only the first 10 characters + + char *versionStrEnd = (char *)versionStrDot; + while (versionStrEnd < checkStringLimit) { - // If a space was not found, then the vendor-specific info is not present, - // and therefore the entire string must be the version number. - versionStringLength = strlen(oglVersionString); + versionStrEnd++; + if (*versionStrEnd == ' ') + { + versionStringLength = versionStrEnd - oglVersionString; + break; + } } - else + + // Check for any spaces before the dot. There shouldn't be any text before the version number, so + // this step shouldn't be necessary. However, some drivers can defy the OpenGL spec and include + // text before the version number, and so we need to handle such non-compliant drivers just in case. + char *versionStrStart = (char *)versionStrDot; + while (versionStrStart > oglVersionString) { - // If a space was found, then the vendor-specific info is present, - // and therefore the version number is everything before the space. - versionStringLength = versionStrEnd - oglVersionString; + versionStrStart--; + if (*versionStrStart == ' ') + { + versionStrStart++; // Don't include the space we just checked. + versionStringLength -= versionStrStart - oglVersionString; + break; + } } // Copy the version substring and parse it. char *versionSubstring = (char *)malloc(versionStringLength * sizeof(char)); - strncpy(versionSubstring, oglVersionString, versionStringLength); + strncpy(versionSubstring, versionStrStart, versionStringLength); unsigned int major = 0; unsigned int minor = 0; @@ -977,28 +993,28 @@ static Render3D* OpenGLRendererCreate() switch (VARIANTID) { case OpenGLVariantID_Legacy_1_2: - strncpy(variantString, "Open GL 1.2 (forced)", sizeof(variantString)); + strncpy(variantString, "OpenGL 1.2 (forced)", sizeof(variantString)); break; case OpenGLVariantID_Legacy_2_0: - strncpy(variantString, "Open GL 2.0 (forced)", sizeof(variantString)); + strncpy(variantString, "OpenGL 2.0 (forced)", sizeof(variantString)); break; case OpenGLVariantID_Legacy_2_1: - strncpy(variantString, "Open GL 2.1 (forced)", sizeof(variantString)); + strncpy(variantString, "OpenGL 2.1 (forced)", sizeof(variantString)); break; case OpenGLVariantID_CoreProfile_3_2: - strncpy(variantString, "Open GL 3.2 (forced)", sizeof(variantString)); + strncpy(variantString, "OpenGL 3.2 (forced)", sizeof(variantString)); break; case OpenGLVariantID_LegacyAuto: case OpenGLVariantID_StandardAuto: - strncpy(variantString, "Open GL (auto)", sizeof(variantString)); + strncpy(variantString, "OpenGL (auto)", sizeof(variantString)); break; case OpenGLVariantID_ES_3_0: - strncpy(variantString, "Open GL ES 3.0", sizeof(variantString)); + strncpy(variantString, "OpenGL ES 3.0", sizeof(variantString)); break; default: @@ -2983,6 +2999,10 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs() 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.fboFramebufferFlipID); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_WORKING_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0); @@ -2995,6 +3015,10 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs() 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); 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); @@ -3011,6 +3035,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs() return OGLERROR_FBO_CREATE_ERROR; } + // Assign the default read/draw buffers. glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 94243de01..8928fdf9f 100755 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -306,6 +306,12 @@ EXTERNOGLEXT(PFNGLDELETERENDERBUFFERSEXTPROC, glDeleteRenderbuffersEXT) #endif // GL_EXT_framebuffer_object +// Some headers, such as the OpenGL ES headers, may not include this macro. +// Add it manually to avoid compiling issues. +#ifndef GL_BGRA +#define GL_BGRA 0x80E1 +#endif + // OPENGL CORE EQUIVALENTS FOR LEGACY FUNCTIONS // Some OpenGL variants, such as OpenGL ES, do not include certain legacy functions in their // API. The loss of these functions will cause compile time errors when referenced, and so diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 490c1fdce..3ff077fb7 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -949,6 +949,10 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs() 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); 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); @@ -964,6 +968,10 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs() return OGLERROR_FBO_CREATE_ERROR; } + // Assign the default read/draw buffers. + glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID); + glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID); + OGLRef.selectedRenderingFBO = OGLRef.fboRenderID; INFO("OpenGL: Successfully created FBOs.\n"); diff --git a/desmume/src/OGLRender_ES3.cpp b/desmume/src/OGLRender_ES3.cpp index 374518238..152009574 100644 --- a/desmume/src/OGLRender_ES3.cpp +++ b/desmume/src/OGLRender_ES3.cpp @@ -278,6 +278,9 @@ Render3DError OpenGLESRenderer_3_0::InitExtensions() // TBOs are only supported in ES 3.2. this->_isTBOSupported = IsOpenGLDriverVersionSupported(3, 2, 0); + // Fixed locations in shaders are supported in ES 3.0 by default. + this->_isShaderFixedLocationSupported = true; + GLfloat maxAnisotropyOGL = 1.0f; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL); this->_deviceInfo.maxAnisotropy = (float)maxAnisotropyOGL;