0028826: Visualization, TKOpenGl - fix compatibility with strict OpenGL ES drivers
authorkgv <kgv@opencascade.com>
Thu, 8 Jun 2017 07:44:17 +0000 (10:44 +0300)
committermkv <mkv@opencascade.com>
Tue, 13 Jun 2017 09:01:42 +0000 (12:01 +0300)
OpenGl_ShaderProgram::Initialize() - precision declarations have been moved
after the list of enabled extensions.

Declarations.glsl - the fragment shader outputs have been re-declared as array
for proper assignment of default locations (draw buffers).

OpenGl_FrameBuffer - GL_HALF_FLOAT is now used instead of GL_HALF_FLOAT_OES on OpenGL ES 3.2+.
OpenGl_Texture - fixed initialization of Image_Format_RGB32 image format on OpenGL ES 3.0+.

src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_GlFunctions.hxx
src/OpenGl/OpenGl_GraphicDriver.cxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_View_Redraw.cxx
src/Shaders/Declarations.glsl
src/Shaders/Shaders_Declarations_glsl.pxx

index ef3cdf6..f58dd92 100644 (file)
@@ -65,7 +65,8 @@ namespace
   }
 
   //! Determine data type from texture sized format.
-  static bool getColorDataFormat (GLint   theTextFormat,
+  static bool getColorDataFormat (const Handle(OpenGl_Context)& theGlContext,
+                                  GLint   theTextFormat,
                                   GLenum& thePixelFormat,
                                   GLenum& theDataType)
   {
@@ -87,12 +88,28 @@ namespace
       {
         thePixelFormat = GL_RGBA;
         theDataType    = GL_HALF_FLOAT;
+        if (theGlContext->hasHalfFloatBuffer == OpenGl_FeatureInExtensions)
+        {
+        #if defined(GL_ES_VERSION_2_0)
+          theDataType = GL_HALF_FLOAT_OES;
+        #else
+          theDataType = GL_FLOAT;
+        #endif
+        }
         return true;
       }
       case GL_R16F:
       {
         thePixelFormat = GL_RED;
         theDataType    = GL_HALF_FLOAT;
+        if (theGlContext->hasHalfFloatBuffer == OpenGl_FeatureInExtensions)
+        {
+        #if defined(GL_ES_VERSION_2_0)
+          theDataType = GL_HALF_FLOAT_OES;
+        #else
+          theDataType = GL_FLOAT;
+        #endif
+        }
         return true;
       }
       case GL_RGBA8:
@@ -255,7 +272,7 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
       const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
       const GLint                   aColorFormat  = myColorFormats  (aColorBufferIdx);
       if (aColorFormat != 0
-      &&  getColorDataFormat (aColorFormat, aPixelFormat, aDataType)
+      &&  getColorDataFormat (theGlContext, aColorFormat, aPixelFormat, aDataType)
       && !aColorTexture->Init (theGlContext, aColorFormat,
                                aPixelFormat, aDataType,
                                aSizeX, aSizeY, Graphic3d_TOT_2D))
@@ -386,7 +403,7 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
       const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
       const GLint                   aColorFormat  = myColorFormats  (aColorBufferIdx);
       if (aColorFormat != 0
-      &&  getColorDataFormat (aColorFormat, aPixelFormat, aDataType)
+      &&  getColorDataFormat (theGlContext, aColorFormat, aPixelFormat, aDataType)
       && !aColorTexture->Init (theGlContext, aColorFormat,
                                aPixelFormat, aDataType,
                                aSizeX, aSizeY, Graphic3d_TOT_2D))
index daebf8e..fca42c5 100644 (file)
   #define GL_MAX_COLOR_ATTACHMENTS      0x8CDF
   #define GL_MAX_DRAW_BUFFERS           0x8824
 
-  // OES_texture_half_float
-  #define GL_HALF_FLOAT                 0x8D61
+  // OpenGL ES 3.0+ or OES_texture_half_float
+  #define GL_HALF_FLOAT                 0x140B
+  #define GL_HALF_FLOAT_OES             0x8D61
 #endif
 
 #if !defined(HAVE_EGL) && (defined(__ANDROID__) || defined(__QNX__) || defined(HAVE_GLES2) || defined(OCCT_UWP))
index d3c178a..a409eb1 100644 (file)
@@ -416,9 +416,13 @@ Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit
     case Graphic3d_TypeOfLimit_HasRayTracingAdaptiveSampling:
       return (!aCtx.IsNull() && aCtx->HasRayTracingAdaptiveSampling()) ? 1 : 0;
     case Graphic3d_TypeOfLimit_HasBlendedOit:
-      return (!aCtx.IsNull() && aCtx->hasDrawBuffers && (aCtx->hasFloatBuffer || aCtx->hasHalfFloatBuffer)) ? 1 : 0;
+      return (!aCtx.IsNull()
+            && aCtx->hasDrawBuffers != OpenGl_FeatureNotAvailable
+            && (aCtx->hasFloatBuffer != OpenGl_FeatureNotAvailable || aCtx->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable)) ? 1 : 0;
     case Graphic3d_TypeOfLimit_HasBlendedOitMsaa:
-      return (!aCtx.IsNull() && aCtx->hasSampleVariables && (InquireLimit (Graphic3d_TypeOfLimit_HasBlendedOit) == 1)) ? 1 : 0;
+      return (!aCtx.IsNull()
+            && aCtx->hasSampleVariables != OpenGl_FeatureNotAvailable
+            && (InquireLimit (Graphic3d_TypeOfLimit_HasBlendedOit) == 1)) ? 1 : 0;
     case Graphic3d_TypeOfLimit_NB:
       return 0;
   }
index 7e3b8ad..7d8fe6d 100755 (executable)
@@ -206,7 +206,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     }
 
     TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
-    TCollection_AsciiString anExtensions = "// This section enables extensions used in OCCT GLSL programs\n";
+    TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
     if (theCtx->hasDrawBuffers)
     {
       anExtensions += "#define OCC_ENABLE_draw_buffers\n";
@@ -253,7 +253,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
                                          "precision highp int;\n"
                                        : "precision mediump float;\n"
                                          "precision mediump int;\n");
-        aSource = aHeader + aPrefix + anExtensions + aSource;
+        aSource = aHeader + anExtensions + aPrefix + aSource;
       #else
         aSource = aHeader + anExtensions + aSource;
       #endif
index 0603ce5..04bad58 100644 (file)
@@ -266,29 +266,51 @@ bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx,
     }
     case Image_Format_BGRA:
     {
+    #if !defined(GL_ES_VERSION_2_0)
       if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
       {
         return false;
       }
       theTextFormat  = GL_RGBA8;
+    #else
+      if (!theCtx->extBgra)
+      {
+        return false;
+      }
+      theTextFormat  = GL_BGRA_EXT;
+    #endif
       thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
       theDataType    = GL_UNSIGNED_BYTE;
       return true;
     }
     case Image_Format_RGB32:
     {
-      theTextFormat = GL_RGB8;
+    #if !defined(GL_ES_VERSION_2_0)
+      // ask driver to convert data to RGB8 to save memory
+      theTextFormat  = GL_RGB8;
+    #else
+      // conversion is not supported
+      theTextFormat  = GL_RGBA8;
+    #endif
       thePixelFormat = GL_RGBA;
       theDataType    = GL_UNSIGNED_BYTE;
       return true;
     }
     case Image_Format_BGR32:
     {
-      if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
+    #if !defined(GL_ES_VERSION_2_0)
+      if (!theCtx->IsGlGreaterEqual(1, 2) && !theCtx->extBgra)
       {
         return false;
       }
       theTextFormat  = GL_RGB8;
+    #else
+      if (!theCtx->extBgra)
+      {
+        return false;
+      }
+      theTextFormat  = GL_BGRA_EXT;
+    #endif
       thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
       theDataType    = GL_UNSIGNED_BYTE;
       return true;
@@ -590,8 +612,13 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
                     theSizeX, theSizeY, 0,
                     thePixelFormat, theDataType, aDataPtr);
-      if (glGetError() != GL_NO_ERROR)
+      const GLenum anErr = glGetError();
+      if (anErr != GL_NO_ERROR)
       {
+        theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+                             TCollection_AsciiString ("Error: 2D texture ") + theSizeX + "x" + theSizeY
+                                                   + " IF: " + int(anIntFormat) + " PF: " + int(thePixelFormat) + " DT: " + int(theDataType)
+                                                   + " can not be created with error " + int(anErr) + ".");
         Unbind (theCtx);
         Release (theCtx.operator->());
         return false;
@@ -663,8 +690,13 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
                     theSizeX, theSizeY, 0,
                     thePixelFormat, theDataType, theImage->Data());
-      if (glGetError() != GL_NO_ERROR)
+      const GLenum aTexImgErr = glGetError();
+      if (aTexImgErr != GL_NO_ERROR)
       {
+        theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+                             TCollection_AsciiString ("Error: 2D texture ") + theSizeX + "x" + theSizeY
+                                                    + " IF: " + int(anIntFormat) + " PF: " + int(thePixelFormat) + " DT: " + int(theDataType)
+                                                    + " can not be created with error " + int(aTexImgErr) + ".");
         Unbind (theCtx);
         Release (theCtx.operator->());
         return false;
index 0c4aa80..1491a7c 100644 (file)
@@ -1699,16 +1699,16 @@ Standard_Boolean OpenGl_View::checkOitCompatibility (const Handle(OpenGl_Context
   }
 
   TCollection_ExtendedString aCompatibilityMsg;
-  if (!theGlContext->hasFloatBuffer
-   && !theGlContext->hasHalfFloatBuffer)
+  if (theGlContext->hasFloatBuffer     == OpenGl_FeatureNotAvailable
+   && theGlContext->hasHalfFloatBuffer == OpenGl_FeatureNotAvailable)
   {
     aCompatibilityMsg += "OpenGL context does not support floating-point RGBA color buffer format.\n";
   }
-  if (theMSAA && !theGlContext->hasSampleVariables)
+  if (theMSAA && theGlContext->hasSampleVariables == OpenGl_FeatureNotAvailable)
   {
     aCompatibilityMsg += "Current version of GLSL does not support built-in sample variables.\n";
   }
-  if (!theGlContext->hasDrawBuffers)
+  if (theGlContext->hasDrawBuffers == OpenGl_FeatureNotAvailable)
   {
     aCompatibilityMsg += "OpenGL context does not support multiple draw buffers.\n";
   }
@@ -1741,14 +1741,14 @@ bool OpenGl_View::chooseOitColorConfiguration (const Handle(OpenGl_Context)& the
   {
     case 0: // choose best applicable color format combination
     {
-      theFormats.Append (theGlContext->hasHalfFloatBuffer ? GL_RGBA16F : GL_RGBA32F);
-      theFormats.Append (theGlContext->hasHalfFloatBuffer ? GL_R16F    : GL_R32F);
+      theFormats.Append (theGlContext->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable ? GL_RGBA16F : GL_RGBA32F);
+      theFormats.Append (theGlContext->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable ? GL_R16F    : GL_R32F);
       return true;
     }
     case 1: // choose non-optimal applicable color format combination
     {
-      theFormats.Append (theGlContext->hasHalfFloatBuffer ? GL_RGBA16F : GL_RGBA32F);
-      theFormats.Append (theGlContext->hasHalfFloatBuffer ? GL_RGBA16F : GL_RGBA32F);
+      theFormats.Append (theGlContext->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable ? GL_RGBA16F : GL_RGBA32F);
+      theFormats.Append (theGlContext->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable ? GL_RGBA16F : GL_RGBA32F);
       return true;
     }
   }
index 001565e..be565d0 100644 (file)
   THE_ATTRIBUTE vec4 occTexCoord;
   THE_ATTRIBUTE vec4 occVertColor;
 #elif (__VERSION__ >= 130)
-  out vec4 occFragColor;
   #ifdef OCC_ENABLE_draw_buffers
-    out vec4 occFragCoverage;
+    out vec4 occFragColorArray[2];
+    #define occFragColor    occFragColorArray[0]
+    #define occFragCoverage occFragColorArray[1]
+  #else
+    out vec4 occFragColor;
   #endif
 #else
   #ifdef OCC_ENABLE_draw_buffers
index 7476af2..ea1a087 100644 (file)
@@ -53,9 +53,12 @@ static const char Shaders_Declarations_glsl[] =
   "  THE_ATTRIBUTE vec4 occTexCoord;\n"
   "  THE_ATTRIBUTE vec4 occVertColor;\n"
   "#elif (__VERSION__ >= 130)\n"
-  "  out vec4 occFragColor;\n"
   "  #ifdef OCC_ENABLE_draw_buffers\n"
-  "    out vec4 occFragCoverage;\n"
+  "    out vec4 occFragColorArray[2];\n"
+  "    #define occFragColor    occFragColorArray[0]\n"
+  "    #define occFragCoverage occFragColorArray[1]\n"
+  "  #else\n"
+  "    out vec4 occFragColor;\n"
   "  #endif\n"
   "#else\n"
   "  #ifdef OCC_ENABLE_draw_buffers\n"