0026165: Visualization, TKOpenGl - fix FBO blitting on some mobile devices
authorkgv <kgv@opencascade.com>
Wed, 6 May 2015 13:05:47 +0000 (16:05 +0300)
committerabv <abv@opencascade.com>
Fri, 8 May 2015 05:51:47 +0000 (08:51 +0300)
OpenGl_Texture::Init() - initialize FBO textures with GL_TEXTURE_WRAP_ set to GL_CLAMP_TO_EDGE,
since some devices do not support GL_REPEAT (which is default) in such combination.
OpenGl_Font::createTexture() - define texture parameters explicitly.

OpenGl_FrameBuffer::Init() create Depth render buffer object instead of texture
on devices which do not support GL_DEPTH24_STENCIL8.

src/OpenGl/OpenGl_Font.cxx
src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_FrameBuffer.hxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_Workspace.cxx

index c29f3c7..1a17c60 100755 (executable)
@@ -16,6 +16,7 @@
 #include <OpenGl_Font.hxx>
 
 #include <OpenGl_Context.hxx>
+#include <Graphic3d_TextureParams.hxx>
 #include <Standard_Assert.hxx>
 #include <TCollection_ExtendedString.hxx>
 
@@ -113,7 +114,13 @@ bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
   memset (&myLastTilePx, 0, sizeof(myLastTilePx));
   myLastTilePx.Bottom = myTileSizeY;
 
-  myTextures.Append (new OpenGl_Texture());
+  Handle(Graphic3d_TextureParams) aParams = new Graphic3d_TextureParams();
+  aParams->SetModulate    (Standard_False);
+  aParams->SetRepeat      (Standard_False);
+  aParams->SetFilter      (Graphic3d_TOTF_BILINEAR);
+  aParams->SetAnisoFilter (Graphic3d_LOTA_OFF);
+
+  myTextures.Append (new OpenGl_Texture (aParams));
   Handle(OpenGl_Texture)& aTexture = myTextures.ChangeLast();
 
   Image_PixMap aBlackImg;
@@ -130,10 +137,6 @@ bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
     return false;
   }
 
-  aTexture->Bind (theCtx);
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, theCtx->TextureWrapClamp());
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, theCtx->TextureWrapClamp());
-  aTexture->Unbind (theCtx);
   return true;
 }
 
index 59f99c8..2e0c192 100644 (file)
@@ -69,26 +69,56 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
   myVPSizeY = theViewportSizeY;
 
   // Create the textures (will be used as color buffer and depth-stencil buffer)
-  if (!initTrashTextures (theGlContext))
+  if (!myColorTexture->Init (theGlContext, myTextFormat,
+                             GL_RGBA, GL_UNSIGNED_BYTE,
+                             myVPSizeX, myVPSizeY, Graphic3d_TOT_2D))
   {
     Release (theGlContext.operator->());
     return Standard_False;
   }
 
+  // extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats
+  // instead of just trying to create such texture
+  if (!myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
+                                    GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
+                                    myVPSizeX, myVPSizeY, Graphic3d_TOT_2D))
+  {
+    TCollection_ExtendedString aMsg = TCollection_ExtendedString()
+      + "Warning! Depth textures are not supported by hardware!";
+    theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                               GL_DEBUG_TYPE_PORTABILITY_ARB,
+                               0,
+                               GL_DEBUG_SEVERITY_HIGH_ARB,
+                               aMsg);
+
+    theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
+    theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
+    theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, myVPSizeX, myVPSizeY);
+    theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
+  }
+
   // Build FBO and setup it as texture
   theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
   theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
   theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                 GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
-#ifdef GL_DEPTH_STENCIL_ATTACHMENT
-  theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
-                                                GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
-#else
-  theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                                GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
-  theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                                                GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
-#endif
+  if (myDepthStencilTexture->IsValid())
+  {
+  #ifdef GL_DEPTH_STENCIL_ATTACHMENT
+    theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                                  GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
+  #else
+    theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                                  GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
+    theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                                  GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
+  #endif
+  }
+  else if (myGlDepthRBufferId != NO_RENDERBUFFER)
+  {
+    theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                                     GL_RENDERBUFFER, myGlDepthRBufferId);
+  }
   if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   {
     Release (theGlContext.operator->());
@@ -288,20 +318,6 @@ void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx)
 }
 
 // =======================================================================
-// function : initTrashTexture
-// purpose  :
-// =======================================================================
-Standard_Boolean OpenGl_FrameBuffer::initTrashTextures (const Handle(OpenGl_Context)& theGlContext)
-{
-  return    myColorTexture->Init (theGlContext, myTextFormat,
-                                  GL_RGBA, GL_UNSIGNED_BYTE,
-                                  myVPSizeX, myVPSizeY, Graphic3d_TOT_2D)
-  && myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
-                                  GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
-                                  myVPSizeX, myVPSizeY, Graphic3d_TOT_2D);
-}
-
-// =======================================================================
 // function : SetupViewport
 // purpose  :
 // =======================================================================
index 799b292..c2f03d6 100644 (file)
@@ -153,9 +153,6 @@ public:
 
 protected:
 
-  //! Generate textures with undefined data
-  Standard_Boolean initTrashTextures (const Handle(OpenGl_Context)& theGlContext);
-
   Standard_Boolean isValidFrameBuffer() const
   {
     return myGlFBufferId != NO_FRAMEBUFFER;
index 6d752b2..32a837f 100644 (file)
@@ -390,6 +390,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
   const bool    toForceP2  = !theCtx->IsGlGreaterEqual (3, 0) && !theCtx->arbNPTW;
   const GLsizei aWidthOut  = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aWidth,  aMaxSize) : Min (aWidth,  aMaxSize);
   const GLsizei aHeightOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aHeight, aMaxSize) : Min (aHeight, aMaxSize);
+  const GLenum  aFilter    = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
+  const GLenum  aWrapMode  = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
 
 #if !defined(GL_ES_VERSION_2_0)
   GLint aTestWidth  = 0;
@@ -419,8 +421,9 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
     #if !defined(GL_ES_VERSION_2_0)
       myTarget = GL_TEXTURE_1D;
       Bind (theCtx);
-      glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-      glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+      glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
+      glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
+      glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,     aWrapMode);
 
       Image_PixMap aCopy;
       if (aDataPtr != NULL)
@@ -480,8 +483,10 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
     {
       myTarget = GL_TEXTURE_2D;
       Bind (theCtx);
-      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilter);
+      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
+      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     aWrapMode);
+      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     aWrapMode);
 
       Image_PixMap aCopy;
       if (aDataPtr != NULL)
@@ -548,9 +553,23 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
     {
       myTarget     = GL_TEXTURE_2D;
       myHasMipmaps = Standard_True;
+
+      GLenum aFilterMin = aFilter;
+      aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
+      if (myParams->Filter() == Graphic3d_TOTF_BILINEAR)
+      {
+        aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
+      }
+      else if (myParams->Filter() == Graphic3d_TOTF_TRILINEAR)
+      {
+        aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
+      }
+
       Bind (theCtx);
-      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
+      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
+      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     aWrapMode);
+      glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     aWrapMode);
 
       if (theCtx->arbFBO != NULL
        && aWidth == aWidthOut && aHeight == aHeightOut)
@@ -667,21 +686,16 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
 #if !defined(GL_ES_VERSION_2_0)
   myTarget = GL_TEXTURE_RECTANGLE;
 
-  const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
-  const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
+  const GLsizei aSizeX    = Min (theCtx->MaxTextureSize(), theSizeX);
+  const GLsizei aSizeY    = Min (theCtx->MaxTextureSize(), theSizeY);
+  const GLenum  aFilter   = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
+  const GLenum  aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
 
   Bind (theCtx);
-
-  if (myParams->Filter() == Graphic3d_TOTF_NEAREST)
-  {
-    glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  }
-  else
-  {
-    glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  }
+  glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
+  glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
+  glTexParameteri (myTarget, GL_TEXTURE_WRAP_S,     aWrapMode);
+  glTexParameteri (myTarget, GL_TEXTURE_WRAP_T,     aWrapMode);
 
   const GLint anIntFormat = theFormat.Internal();
   myTextFormat = theFormat.Format();
index 237ece8..b93bd86 100644 (file)
@@ -775,11 +775,11 @@ bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo,
     {
       theReadFbo->ColorTexture()       ->Bind   (myGlContext, GL_TEXTURE0 + 0);
       theReadFbo->DepthStencilTexture()->Bind   (myGlContext, GL_TEXTURE0 + 1);
-      myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
+      myFullScreenQuad.BindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
 
       myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
 
-      myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0);
+      myFullScreenQuad.UnbindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
       theReadFbo->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
       theReadFbo->ColorTexture()       ->Unbind (myGlContext, GL_TEXTURE0 + 0);
     }