From fcfaad8c71c13bdbe1dda88e1de5703a49623cbf Mon Sep 17 00:00:00 2001 From: kgv Date: Fri, 29 Jan 2021 11:12:01 +0300 Subject: [PATCH] 0032089: Visualization, TKOpenGl - support GL_EXT_sRGB extension to OpenGL ES 2.0 --- src/OpenGl/OpenGl_Context.cxx | 17 +++++++++++++---- src/OpenGl/OpenGl_GLESExtensions.hxx | 4 ++++ src/OpenGl/OpenGl_Texture.cxx | 20 +++++++++++++++++++- src/OpenGl/OpenGl_TextureFormat.cxx | 26 +++++++++++++++++++++++--- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 9147d26bcf..ec662d21bf 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -1553,8 +1553,10 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile) hasTexRGBA8 = IsGlGreaterEqual (3, 0) || CheckExtension ("GL_OES_rgb8_rgba8"); - hasTexSRGB = IsGlGreaterEqual (3, 0); - hasFboSRGB = IsGlGreaterEqual (3, 0); + hasTexSRGB = IsGlGreaterEqual (3, 0) + || CheckExtension ("GL_EXT_sRGB"); + hasFboSRGB = IsGlGreaterEqual (3, 0) + || CheckExtension ("GL_EXT_sRGB"); hasFboRenderMipmap = IsGlGreaterEqual (3, 0) || CheckExtension ("GL_OES_fbo_render_mipmap"); hasSRGBControl = CheckExtension ("GL_EXT_sRGB_write_control"); @@ -3349,8 +3351,15 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile) GL_BACK; #endif GLint aWinColorEncoding = 0; // GL_LINEAR - arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, aDefWinBuffer, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &aWinColorEncoding); - ResetErrors (true); + bool toSkipCheck = false; + #ifdef __EMSCRIPTEN__ + toSkipCheck = !IsGlGreaterEqual (3, 0); + #endif + if (!toSkipCheck) + { + arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, aDefWinBuffer, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &aWinColorEncoding); + ResetErrors (true); + } myIsSRgbWindow = aWinColorEncoding == GL_SRGB; // On desktop OpenGL, pixel formats are almost always sRGB-ready, even when not requested; diff --git a/src/OpenGl/OpenGl_GLESExtensions.hxx b/src/OpenGl/OpenGl_GLESExtensions.hxx index 03fb90b2ec..30d0181f50 100644 --- a/src/OpenGl/OpenGl_GLESExtensions.hxx +++ b/src/OpenGl/OpenGl_GLESExtensions.hxx @@ -33,6 +33,10 @@ typedef double GLclampd; // GL_EXT_texture_format_BGRA8888 #define GL_BGRA_EXT 0x80E1 // same as GL_BGRA on desktop +// GL_EXT_sRGB +#define GL_SRGB_EXT 0x8C40 // GL_SRGB_EXT +#define GL_SRGB_ALPHA_EXT 0x8C42 // GL_SRGB_ALPHA_EXT + #define GL_R16 0x822A #define GL_RGB4 0x804F #define GL_RGB5 0x8050 diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index 939e5bc991..0667fb6ec8 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -1006,6 +1006,20 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, return false; } +#if defined(GL_ES_VERSION_2_0) + if (theToGenMipmap + && !theCtx->IsGlGreaterEqual (3, 0) + && (aFormat.PixelFormat() == GL_SRGB_EXT + || aFormat.PixelFormat() == GL_SRGB_ALPHA_EXT)) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, + TCollection_AsciiString ("Warning, GL_EXT_sRGB disallows generation of mipmaps - fallback using non-sRGB format") + + " [" + myResourceId +"]"); + aFormat.SetPixelFormat (aFormat.PixelFormat() == GL_SRGB_EXT ? GL_RGB : GL_RGBA); + aFormat.SetInternalFormat(aFormat.PixelFormat() == GL_SRGB_EXT ? GL_RGB8 : GL_RGBA8); + } +#endif + myTarget = GL_TEXTURE_CUBE_MAP; myNbSamples = 1; mySizeX = (GLsizei )theSize; @@ -1124,7 +1138,11 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, if (anErr != GL_NO_ERROR) { theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, - TCollection_AsciiString ("Unable to initialize side of cubemap. Error ") + OpenGl_Context::FormatGlError (anErr)); + TCollection_AsciiString ("Error: cubemap side ") + (int )theSize + "x" + (int )theSize + + " IF: " + OpenGl_TextureFormat::FormatFormat (anIntFormat) + + " PF: " + OpenGl_TextureFormat::FormatFormat (aFormat.PixelFormat()) + + " DT: " + OpenGl_TextureFormat::FormatDataType (aFormat.DataType()) + + " can not be created with error " + OpenGl_Context::FormatGlError (anErr) + "."); Unbind (theCtx); Release (theCtx.get()); return false; diff --git a/src/OpenGl/OpenGl_TextureFormat.cxx b/src/OpenGl/OpenGl_TextureFormat.cxx index ec07a2c2d2..c59a45425d 100644 --- a/src/OpenGl/OpenGl_TextureFormat.cxx +++ b/src/OpenGl/OpenGl_TextureFormat.cxx @@ -46,6 +46,7 @@ TCollection_AsciiString OpenGl_TextureFormat::FormatFormat (GLint theInternalFor case 0x8050: return "GL_RGB5"; case GL_RGB8: return "GL_RGB8"; case GL_SRGB8: return "GL_SRGB8"; + case GL_SRGB_EXT: return "GL_SRGB_EXT"; case 0x8052: return "GL_RGB10"; case 0x8053: return "GL_RGB12"; case 0x8054: return "GL_RGB16"; @@ -55,7 +56,8 @@ TCollection_AsciiString OpenGl_TextureFormat::FormatFormat (GLint theInternalFor // RGBA variations case GL_RGBA: return "GL_RGBA"; case GL_RGBA8: return "GL_RGBA8"; - case GL_SRGB8_ALPHA8: return "GL_SRGB8_ALPHA8"; + case GL_SRGB8_ALPHA8: return "GL_SRGB8_ALPHA8"; + case GL_SRGB_ALPHA_EXT: return "GL_SRGB_ALPHA_EXT"; case GL_RGB10_A2: return "GL_RGB10_A2"; case 0x805A: return "GL_RGBA12"; case 0x805B: return "GL_RGBA16"; @@ -226,6 +228,12 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte if (theIsColorMap && theCtx->ToRenderSRGB()) { + #if defined(GL_ES_VERSION_2_0) + if (!theCtx->IsGlGreaterEqual (3, 0)) + { + aFormat.SetPixelFormat (GL_SRGB_ALPHA_EXT); + } + #endif aFormat.SetInternalFormat (GL_SRGB8_ALPHA8); } return aFormat; @@ -280,6 +288,10 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte if (theIsColorMap && theCtx->ToRenderSRGB()) { + if (!theCtx->IsGlGreaterEqual (3, 0)) + { + aFormat.SetPixelFormat (GL_SRGB_ALPHA_EXT); + } aFormat.SetInternalFormat (GL_SRGB8_ALPHA8); } #endif @@ -327,6 +339,12 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte if (theIsColorMap && theCtx->ToRenderSRGB()) { + #if defined(GL_ES_VERSION_2_0) + if (!theCtx->IsGlGreaterEqual (3, 0)) + { + aFormat.SetPixelFormat (GL_SRGB_EXT); + } + #endif aFormat.SetInternalFormat (GL_SRGB8); } return aFormat; @@ -471,6 +489,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindSizedFormat (const Handle(OpenGl_ return aFormat; } case GL_SRGB8_ALPHA8: + case GL_SRGB_ALPHA_EXT: case GL_RGBA8: case GL_RGBA: { @@ -479,7 +498,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindSizedFormat (const Handle(OpenGl_ aFormat.SetPixelFormat (GL_RGBA); aFormat.SetDataType (GL_UNSIGNED_BYTE); aFormat.SetImageFormat (Image_Format_RGBA); - if (theSizedFormat == GL_SRGB8_ALPHA8 + if ((theSizedFormat == GL_SRGB8_ALPHA8 || theSizedFormat == GL_SRGB_ALPHA_EXT) && !theCtx->ToRenderSRGB()) { aFormat.SetInternalFormat (GL_RGBA8); // fallback format @@ -487,6 +506,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindSizedFormat (const Handle(OpenGl_ return aFormat; } case GL_SRGB8: + case GL_SRGB_EXT: case GL_RGB8: case GL_RGB: { @@ -495,7 +515,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindSizedFormat (const Handle(OpenGl_ aFormat.SetPixelFormat (GL_RGB); aFormat.SetDataType (GL_UNSIGNED_BYTE); aFormat.SetImageFormat (Image_Format_RGB); - if (theSizedFormat == GL_SRGB8 + if ((theSizedFormat == GL_SRGB8 || theSizedFormat == GL_SRGB_EXT) && !theCtx->ToRenderSRGB()) { aFormat.SetInternalFormat (GL_RGB8); // fallback format -- 2.39.5