0026892: Visualization, TKOpenGl - support 3D textures within OpenGl_Texture
authorisk <isk@opencascade.com>
Wed, 25 Nov 2015 08:35:38 +0000 (11:35 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 17 Dec 2015 12:58:58 +0000 (15:58 +0300)
Add a new arbTexFloat extension in OpenGl_Context.
Add a new prototype glTexImage in OpenGl_GlFunctions.
Push error message if glTexImage3D is unavailable.

src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_GlFunctions.hxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_Texture.hxx

index 8e8a0af..203de45 100644 (file)
@@ -105,6 +105,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
 #endif
   arbNPTW  (Standard_False),
   arbTexRG (Standard_False),
+  arbTexFloat (Standard_False),
   arbTexBindless (NULL),
   arbTBO (NULL),
   arbTboRGB32 (Standard_False),
@@ -1138,17 +1139,22 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
   {
     hasHighp = Standard_True;
   }
+
+  arbTexFloat = IsGlGreaterEqual (3, 0)
+             && FindProc ("glTexImage3D", myFuncs->glTexImage3D);
 #else
 
   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
 
   hasTexRGBA8 = Standard_True;
-  arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
-  extBgra = CheckExtension ("GL_EXT_bgra");
-  extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
-  extPDS  = CheckExtension ("GL_EXT_packed_depth_stencil");
-  atiMem  = CheckExtension ("GL_ATI_meminfo");
-  nvxMem  = CheckExtension ("GL_NVX_gpu_memory_info");
+  arbNPTW     = CheckExtension ("GL_ARB_texture_non_power_of_two");
+  arbTexFloat = IsGlGreaterEqual (3, 0)
+             || CheckExtension ("GL_ARB_texture_float");
+  extBgra     = CheckExtension ("GL_EXT_bgra");
+  extAnis     = CheckExtension ("GL_EXT_texture_filter_anisotropic");
+  extPDS      = CheckExtension ("GL_EXT_packed_depth_stencil");
+  atiMem      = CheckExtension ("GL_ATI_meminfo");
+  nvxMem      = CheckExtension ("GL_NVX_gpu_memory_info");
 
   GLint aStereo = GL_FALSE;
   glGetIntegerv (GL_STEREO, &aStereo);
index 4c7024d..f18f571 100644 (file)
@@ -635,6 +635,7 @@ public: //! @name extensions
   Standard_Boolean       hasTexRGBA8;    //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8
   Standard_Boolean       arbNPTW;        //!< GL_ARB_texture_non_power_of_two
   Standard_Boolean       arbTexRG;       //!< GL_ARB_texture_rg
+  Standard_Boolean       arbTexFloat;    //!< GL_ARB_texture_float (on desktop OpenGL - since 3.0 or as extension GL_ARB_texture_float; on OpenGL ES - since 3.0)
   OpenGl_ArbTexBindless* arbTexBindless; //!< GL_ARB_bindless_texture
   OpenGl_ArbTBO*         arbTBO;         //!< GL_ARB_texture_buffer_object
   Standard_Boolean       arbTboRGB32;    //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0
index 6b479b5..0ffef34 100644 (file)
   #define GL_READ_FRAMEBUFFER               0x8CA8
   #define GL_DRAW_FRAMEBUFFER               0x8CA9
 
+  #define GL_TEXTURE_3D                     0x806F
+  #define GL_TEXTURE_WRAP_R                 0x8072
+
   // GL_EXT_texture_filter_anisotropic
   #define GL_TEXTURE_MAX_ANISOTROPY_EXT     0x84FE
   #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
@@ -712,6 +715,9 @@ public: //! @name OpenGL ES 3.0
   typedef void (*glBlitFramebuffer_t)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
   glBlitFramebuffer_t glBlitFramebuffer;
 
+  typedef void (*glTexImage3D_t)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* data);
+  glTexImage3D_t glTexImage3D;
+
 public: //! @name OpenGL ES 3.1
 
   typedef void (*glTexStorage2DMultisample_t)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
index 93f7008..3a83bd0 100644 (file)
@@ -55,6 +55,7 @@ OpenGl_Texture::OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams
   myTarget (GL_TEXTURE_2D),
   mySizeX (0),
   mySizeY (0),
+  mySizeZ (0),
   myTextFormat (GL_RGBA),
   myHasMipmaps (Standard_False),
   myIsAlpha    (false),
@@ -379,6 +380,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
 #else
   // ES does not support sized formats and format conversions - them detected from data type
   const GLint anIntFormat  = thePixelFormat;
+  (void) theTextFormat;
 #endif
   const GLsizei aWidth     = theSizeX;
   const GLsizei aHeight    = theSizeY;
@@ -794,3 +796,123 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
   return false;
 #endif
 }
+
+// =======================================================================
+// function : Init3D
+// purpose  :
+// =======================================================================
+bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
+                             const GLint                   theTextFormat,
+                             const GLenum                  thePixelFormat,
+                             const GLenum                  theDataType,
+                             const Standard_Integer        theSizeX,
+                             const Standard_Integer        theSizeY,
+                             const Standard_Integer        theSizeZ,
+                             const void*                   thePixels)
+{
+  if (theCtx->Functions()->glTexImage3D == NULL)
+  {
+    TCollection_ExtendedString aMsg ("Error: three-dimensional textures are not supported by hardware.");
+
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                         GL_DEBUG_TYPE_ERROR,
+                         0,
+                         GL_DEBUG_SEVERITY_HIGH,
+                         aMsg);
+
+    return false;
+  }
+
+  if (!Create(theCtx))
+  {
+    return false;
+  }
+
+  myTarget = GL_TEXTURE_3D;
+
+  const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
+  const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
+  const GLsizei aSizeZ = Min (theCtx->MaxTextureSize(), theSizeZ);
+
+  Bind (theCtx);
+
+  if (theDataType == GL_FLOAT && !theCtx->arbTexFloat)
+  {
+    TCollection_ExtendedString aMsg ("Error: floating-point textures are not supported by hardware.");
+
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                         GL_DEBUG_TYPE_ERROR,
+                         0,
+                         GL_DEBUG_SEVERITY_HIGH,
+                         aMsg);
+
+    Release (theCtx.operator->());
+    Unbind (theCtx);
+    return false;
+  }
+
+  const GLint anIntFormat = theTextFormat;
+
+#if !defined (GL_ES_VERSION_2_0)
+  theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D,
+                                   0,
+                                   anIntFormat,
+                                   aSizeX,
+                                   aSizeY,
+                                   aSizeZ,
+                                   0,
+                                   thePixelFormat,
+                                   theDataType,
+                                   NULL);
+
+  GLint aTestSizeX = 0;
+  GLint aTestSizeY = 0;
+  GLint aTestSizeZ = 0;
+
+  glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
+  glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
+  glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &aTestSizeZ);
+
+  if (aTestSizeX == 0 || aTestSizeY == 0 || aTestSizeZ == 0)
+  {
+    Unbind (theCtx);
+    Release (theCtx.operator->());
+    return false;
+  }
+#endif
+
+  const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT :  theCtx->TextureWrapClamp();
+  const GLenum aFilter   = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
+
+  glTexParameteri (myTarget, GL_TEXTURE_WRAP_S, aWrapMode);
+  glTexParameteri (myTarget, GL_TEXTURE_WRAP_T, aWrapMode);
+  glTexParameteri (myTarget, GL_TEXTURE_WRAP_R, aWrapMode);
+
+  glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
+  glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
+
+  theCtx->Functions()->glTexImage3D (myTarget,
+                                     0,
+                                     anIntFormat,
+                                     aSizeX,
+                                     aSizeY,
+                                     aSizeZ,
+                                     0,
+                                     thePixelFormat,
+                                     theDataType,
+                                     thePixels);
+
+  if (glGetError() != GL_NO_ERROR)
+  {
+    Unbind (theCtx);
+    Release (theCtx.operator->());
+    return false;
+  }
+
+  mySizeX = aSizeX;
+  mySizeY = aSizeY;
+  mySizeZ = aSizeZ;
+
+  Unbind (theCtx);
+  return true;
+}
index 34455ce..c7242b0 100644 (file)
@@ -394,6 +394,16 @@ public:
                                       const Standard_Integer        theSizeY,
                                       const OpenGl_TextureFormat&   theFormat);
 
+  //! Initializes 3D texture rectangle with specified format and size.
+  Standard_EXPORT bool Init3D (const Handle(OpenGl_Context)& theCtx,
+                               const GLint                   theTextFormat,
+                               const GLenum                  thePixelFormat,
+                               const GLenum                  theDataType,
+                               const Standard_Integer        theSizeX,
+                               const Standard_Integer        theSizeY,
+                               const Standard_Integer        theSizeZ,
+                               const void*                   thePixels);
+
   //! @return true if texture was generated within mipmaps
   Standard_EXPORT Standard_Boolean HasMipmaps() const;
 
@@ -413,9 +423,10 @@ public:
 protected:
 
   GLuint           myTextureId;  //!< GL resource ID
-  GLenum           myTarget;     //!< GL_TEXTURE_1D/GL_TEXTURE_2D
+  GLenum           myTarget;     //!< GL_TEXTURE_1D/GL_TEXTURE_2D/GL_TEXTURE_3D
   GLsizei          mySizeX;      //!< texture width
   GLsizei          mySizeY;      //!< texture height
+  GLsizei          mySizeZ;      //!< texture depth
   GLenum           myTextFormat; //!< texture format - GL_RGB, GL_RGBA,...
   Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps
   bool             myIsAlpha;    //!< indicates alpha format