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),
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);
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
#include <OpenGl_VertexBufferCompat.hxx>
#include <OpenGl_Workspace.hxx>
#include <Graphic3d_TextureParams.hxx>
+#include <NCollection_AlignedAllocator.hxx>
namespace
{
myDrawMode (DRAW_MODE_NONE),
myIsVboInit (Standard_False)
{
- if (theDriver != NULL)
- {
- myUID = theDriver->GetNextPrimitiveArrayUID();
- }
-
if (!myIndices.IsNull()
&& myIndices->NbElements < 1)
{
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);
}
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;
}
}
}
+// =======================================================================
+// 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 :
myIndices = theIndices;
myAttribs = theAttribs;
myBounds = theBounds;
+#if defined(GL_ES_VERSION_2_0)
+ processIndices (theContext);
+#endif
setDrawMode (theType);
}