0026081: Visualization, TKOpenGl - rebuild vertex attributes in order to not render...
authordbp <dbp@opencascade.com>
Thu, 16 Apr 2015 13:03:55 +0000 (16:03 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 30 Apr 2015 10:21:52 +0000 (13:21 +0300)
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_PrimitiveArray.hxx

index 7e53da0..060576c 100644 (file)
@@ -83,9 +83,11 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
 #if defined(GL_ES_VERSION_2_0)
   hasHighp   (Standard_False),
+  hasUintIndex(Standard_False),
   hasTexRGBA8(Standard_False),
 #else
   hasHighp   (Standard_True),
+  hasUintIndex(Standard_True),
   hasTexRGBA8(Standard_True),
 #endif
   arbNPTW  (Standard_False),
@@ -1057,7 +1059,9 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
   }
 
-  hasHighp = CheckExtension ("GL_OES_fragment_precision_high");
+  hasUintIndex = IsGlGreaterEqual (3, 0)
+              || CheckExtension ("GL_OES_element_index_uint");
+  hasHighp     = CheckExtension ("GL_OES_fragment_precision_high");
   GLint aRange[2] = {0, 0};
   GLint aPrec     = 0;
   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
index ce67d60..47caab9 100644 (file)
@@ -595,6 +595,7 @@ public: //! @name core profiles
 public: //! @name extensions
 
   Standard_Boolean       hasHighp;       //!< highp in GLSL ES fragment shader is supported
+  Standard_Boolean       hasUintIndex;   //!< GLuint for index buffer is supported (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_element_index_uint)
   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
index 4e8810e..6ee9083 100644 (file)
@@ -25,6 +25,7 @@
 #include <OpenGl_VertexBufferCompat.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <Graphic3d_TextureParams.hxx>
+#include <NCollection_AlignedAllocator.hxx>
 
 namespace
 {
@@ -628,11 +629,6 @@ OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (const OpenGl_GraphicDriver*
   myDrawMode  (DRAW_MODE_NONE),
   myIsVboInit (Standard_False)
 {
-  if (theDriver != NULL)
-  {
-    myUID = theDriver->GetNextPrimitiveArrayUID();
-  }
-
   if (!myIndices.IsNull()
     && myIndices->NbElements < 1)
   {
@@ -640,6 +636,18 @@ OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (const OpenGl_GraphicDriver*
     myIndices.Nullify();
   }
 
+  if (theDriver != NULL)
+  {
+    myUID = theDriver->GetNextPrimitiveArrayUID();
+  #if defined (GL_ES_VERSION_2_0)
+    const Handle(OpenGl_Context)& aCtx = theDriver->GetSharedContext();
+    if (!aCtx.IsNull())
+    {
+      processIndices (aCtx);
+    }
+  #endif
+  }
+
   setDrawMode (theType);
 }
 
@@ -700,6 +708,9 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
     const Standard_Boolean toKeepData = myDrawMode == GL_POINTS
                                     && !anAspectMarker->SpriteRes (aCtx).IsNull()
                                     &&  anAspectMarker->SpriteRes (aCtx)->IsDisplayList();
+  #if defined (GL_ES_VERSION_2_0)
+    processIndices (aCtx);
+  #endif
     buildVBO (aCtx, toKeepData);
     myIsVboInit = Standard_True;
   }
@@ -872,6 +883,41 @@ void OpenGl_PrimitiveArray::setDrawMode (const Graphic3d_TypeOfPrimitiveArray th
 }
 
 // =======================================================================
+// function : processIndices
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_PrimitiveArray::processIndices (const Handle(OpenGl_Context)& theContext) const
+{
+  if (myIndices.IsNull()
+   || theContext->hasUintIndex)
+  {
+    return Standard_True;
+  }
+
+  if (myIndices->NbElements > std::numeric_limits<GLushort>::max())
+  {
+    Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (new NCollection_AlignedAllocator (16));
+    if (!anAttribs->Init (myIndices->NbElements, myAttribs->AttributesArray(), myAttribs->NbAttributes))
+    {
+      return Standard_False; // failed to initialize attribute array
+    }
+
+    for (Standard_Integer anIdxIdx = 0; anIdxIdx < myIndices->NbElements; ++anIdxIdx)
+    {
+      const Standard_Integer anIndex = myIndices->Index (anIdxIdx);
+      memcpy (anAttribs->ChangeData() + myAttribs->Stride * anIdxIdx,
+              myAttribs->Data()       + myAttribs->Stride * anIndex,
+              myAttribs->Stride);
+    }
+
+    myIndices.Nullify();
+    myAttribs = anAttribs;
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
 // function : InitBuffers
 // purpose  :
 // =======================================================================
@@ -887,6 +933,9 @@ void OpenGl_PrimitiveArray::InitBuffers (const Handle(OpenGl_Context)&        th
   myIndices = theIndices;
   myAttribs = theAttribs;
   myBounds = theBounds;
+#if defined(GL_ES_VERSION_2_0)
+  processIndices (theContext);
+#endif
 
   setDrawMode (theType);
 }
index c642f01..261da15 100644 (file)
@@ -122,6 +122,9 @@ private:
   //! @param theType type of primitive array.
   void setDrawMode (const Graphic3d_TypeOfPrimitiveArray theType);
 
+  //! Rebuilds the array of vertex attributes so that it can be drawn without indices.
+  Standard_Boolean processIndices (const Handle(OpenGl_Context)& theContext) const;
+
 protected:
 
   mutable Handle(OpenGl_VertexBuffer)   myVboIndices;