0027354: Visualization: TKOpenGl - OpenGl_TextureBufferArb API should be extended
[occt.git] / src / OpenGl / OpenGl_TextureBufferArb.cxx
index 405b6fd..b5e1d8b 100644 (file)
@@ -1,28 +1,24 @@
 // Created by: Kirill GAVRILOV
-// Copyright (c) 2012 OPEN CASCADE SAS
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 #include <OpenGl_TextureBufferArb.hxx>
 
 #include <OpenGl_Context.hxx>
 #include <Standard_Assert.hxx>
 
-IMPLEMENT_STANDARD_HANDLE (OpenGl_TextureBufferArb, OpenGl_VertexBuffer)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureBufferArb, OpenGl_VertexBuffer)
+
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureBufferArb,OpenGl_VertexBuffer)
 
 // =======================================================================
 // function : OpenGl_TextureBufferArb
@@ -51,14 +47,14 @@ OpenGl_TextureBufferArb::~OpenGl_TextureBufferArb()
 // =======================================================================
 GLenum OpenGl_TextureBufferArb::GetTarget() const
 {
-  return GL_TEXTURE_BUFFER_ARB; // GL_TEXTURE_BUFFER for OpenGL 3.1+
+  return GL_TEXTURE_BUFFER; // GL_TEXTURE_BUFFER for OpenGL 3.1+, OpenGL ES 3.2
 }
 
 // =======================================================================
 // function : Release
 // purpose  :
 // =======================================================================
-void OpenGl_TextureBufferArb::Release (const OpenGl_Context* theGlCtx)
+void OpenGl_TextureBufferArb::Release (OpenGl_Context* theGlCtx)
 {
   if (myTextureId != NO_TEXTURE)
   {
@@ -66,7 +62,10 @@ void OpenGl_TextureBufferArb::Release (const OpenGl_Context* theGlCtx)
     Standard_ASSERT_RETURN (theGlCtx != NULL,
       "OpenGl_TextureBufferExt destroyed without GL context! Possible GPU memory leakage...",);
 
-    glDeleteTextures (1, &myTextureId);
+    if (theGlCtx->IsValid())
+    {
+      glDeleteTextures (1, &myTextureId);
+    }
     myTextureId = NO_TEXTURE;
   }
   OpenGl_VertexBuffer::Release (theGlCtx);
@@ -99,13 +98,21 @@ bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
                                     const GLsizei  theElemsNb,
                                     const GLfloat* theData)
 {
-  if (theComponentsNb != 1
-   && theComponentsNb != 2
-   && theComponentsNb != 4)
+  if (theGlCtx->arbTBO == NULL)
+  {
+    return false;
+  }
+  else if (theComponentsNb < 1
+        || theComponentsNb > 4)
   {
     // unsupported format
     return false;
   }
+  else if (theComponentsNb == 3
+       && !theGlCtx->arbTboRGB32)
+  {
+    return false;
+  }
   else if (!Create (theGlCtx)
         || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
   {
@@ -116,13 +123,141 @@ bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
   {
     case 1: myTexFormat = GL_R32F;    break;
     case 2: myTexFormat = GL_RG32F;   break;
-    //case 3: myTexFormat = GL_RGB32F;  break; // GL_ARB_texture_buffer_object_rgb32
+    case 3: myTexFormat = GL_RGB32F;  break; // GL_ARB_texture_buffer_object_rgb32
     case 4: myTexFormat = GL_RGBA32F; break;
   }
 
   Bind (theGlCtx);
   BindTexture (theGlCtx);
-  theGlCtx->arbTBO->glTexBufferARB (GetTarget(), myTexFormat, myBufferId);
+  theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
+  UnbindTexture (theGlCtx);
+  Unbind (theGlCtx);
+  return true;
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
+                                    const GLuint   theComponentsNb,
+                                    const GLsizei  theElemsNb,
+                                    const GLuint*  theData)
+{
+  if (theGlCtx->arbTBO == NULL)
+  {
+    return false;
+  }
+  else if (theComponentsNb < 1
+        || theComponentsNb > 4)
+  {
+    // unsupported format
+    return false;
+  }
+  else if (theComponentsNb == 3
+       && !theGlCtx->arbTboRGB32)
+  {
+    return false;
+  }
+  else if (!Create (theGlCtx)
+        || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
+  {
+    return false;
+  }
+
+  switch (theComponentsNb)
+  {
+    case 1: myTexFormat = GL_R32I;    break;
+    case 2: myTexFormat = GL_RG32I;   break;
+    case 3: myTexFormat = GL_RGB32I;  break;
+    case 4: myTexFormat = GL_RGBA32I; break;
+  }
+
+  Bind (theGlCtx);
+  BindTexture (theGlCtx);
+  theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
+  UnbindTexture (theGlCtx);
+  Unbind (theGlCtx);
+  return true;
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
+                                    const GLuint theComponentsNb,
+                                    const GLsizei theElemsNb,
+                                    const GLushort* theData)
+{
+  if (theGlCtx->arbTBO == NULL)
+  {
+    return false;
+  }
+  else if (theComponentsNb < 1
+        || theComponentsNb > 4)
+  {
+    // unsupported format
+    return false;
+  }
+  else if (!Create (theGlCtx)
+        || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
+  {
+    return false;
+  }
+
+  switch (theComponentsNb)
+  {
+    case 1: myTexFormat = GL_R16I;    break;
+    case 2: myTexFormat = GL_RG16I;   break;
+    case 3: myTexFormat = GL_RGB16I;  break;
+    case 4: myTexFormat = GL_RGBA16I; break;
+  }
+
+  Bind (theGlCtx);
+  BindTexture (theGlCtx);
+  theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
+  UnbindTexture (theGlCtx);
+  Unbind (theGlCtx);
+  return true;
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
+                                    const GLuint   theComponentsNb,
+                                    const GLsizei  theElemsNb,
+                                    const GLubyte*  theData)
+{
+  if (theGlCtx->arbTBO == NULL)
+  {
+    return false;
+  }
+  else if (theComponentsNb < 1
+        || theComponentsNb > 4)
+  {
+    // unsupported format
+    return false;
+  }
+  else if (!Create (theGlCtx)
+        || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
+  {
+    return false;
+  }
+
+  switch (theComponentsNb)
+  {
+    case 1: myTexFormat = GL_R8;    break;
+    case 2: myTexFormat = GL_RG8;   break;
+    case 3: myTexFormat = GL_RGB8;  break;
+    case 4: myTexFormat = GL_RGBA8; break;
+  }
+
+  Bind (theGlCtx);
+  BindTexture (theGlCtx);
+  theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
   UnbindTexture (theGlCtx);
   Unbind (theGlCtx);
   return true;
@@ -135,7 +270,7 @@ bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
 void OpenGl_TextureBufferArb::BindTexture (const Handle(OpenGl_Context)& theGlCtx,
                                            const GLenum theTextureUnit) const
 {
-  theGlCtx->core20->glActiveTexture (theTextureUnit);
+  theGlCtx->core20fwd->glActiveTexture (theTextureUnit);
   glBindTexture (GetTarget(), myTextureId);
 }
 
@@ -146,6 +281,6 @@ void OpenGl_TextureBufferArb::BindTexture (const Handle(OpenGl_Context)& theGlCt
 void OpenGl_TextureBufferArb::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
                                              const GLenum theTextureUnit) const
 {
-  theGlCtx->core20->glActiveTexture (theTextureUnit);
+  theGlCtx->core20fwd->glActiveTexture (theTextureUnit);
   glBindTexture (GetTarget(), NO_TEXTURE);
 }