#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_Structure.hxx>
+#include <OpenGl_VertexBufferCompat.hxx>
#include <OpenGl_Workspace.hxx>
+#include <Graphic3d_TextureParams.hxx>
+#include <NCollection_AlignedAllocator.hxx>
namespace
{
- template<class T>
- void BindProgramWithMaterial (const Handle(OpenGl_Workspace)& theWS,
- const T* theAspect)
- {
- const Handle(OpenGl_Context)& aCtx = theWS->GetGlContext();
- const Handle(OpenGl_ShaderProgram)& aProgram = theAspect->ShaderProgramRes (theWS);
- if (aProgram.IsNull())
- {
- OpenGl_ShaderProgram::Unbind (aCtx);
- return;
- }
- aProgram->BindWithVariables (aCtx);
-
- const OpenGl_MaterialState* aMaterialState = aCtx->ShaderManager()->MaterialState (aProgram);
- if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
- {
- aCtx->ShaderManager()->UpdateMaterialStateTo (aProgram, theAspect);
- }
-
- aCtx->ShaderManager()->PushState (aProgram);
- }
-
- //! Convert index data type from size
- inline GLenum toGlIndexType (const Standard_Integer theStride)
- {
- switch (theStride)
- {
- case 2: return GL_UNSIGNED_SHORT;
- case 4: return GL_UNSIGNED_INT;
- default: return GL_NONE;
- }
- }
-
//! Convert data type to GL info
inline GLenum toGlDataType (const Graphic3d_TypeOfData theType,
GLint& theNbComp)
}
//! Auxiliary template for VBO with interleaved attributes.
-template<int NbAttributes>
-class OpenGl_VertexBufferT : public OpenGl_VertexBuffer
+template<class TheBaseClass, int NbAttributes>
+class OpenGl_VertexBufferT : public TheBaseClass
{
public:
return false;
}
- virtual void BindFixedPosition (const Handle(OpenGl_Context)& theGlCtx) const
+ virtual bool HasNormalAttribute() const
+ {
+ for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
+ {
+ const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+ if (anAttrib.Id == Graphic3d_TOA_NORM)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ virtual void BindPositionAttribute (const Handle(OpenGl_Context)& theGlCtx) const
{
- if (!IsValid())
+ if (!TheBaseClass::IsValid())
{
return;
}
- Bind (theGlCtx);
+ TheBaseClass::Bind (theGlCtx);
GLint aNbComp;
- const GLubyte* anOffset = NULL;
+ const GLubyte* anOffset = TheBaseClass::myOffset;
for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
{
const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
}
else if (anAttrib.Id == Graphic3d_TOA_POS)
{
- bindFixed (theGlCtx, Graphic3d_TOA_POS, aNbComp, aDataType, Stride, anOffset);
+ TheBaseClass::bindAttribute (theGlCtx, Graphic3d_TOA_POS, aNbComp, aDataType, Stride, anOffset);
break;
}
}
}
- virtual void BindFixed (const Handle(OpenGl_Context)& theGlCtx) const
+ virtual void BindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const
{
- if (!IsValid())
+ if (!TheBaseClass::IsValid())
{
return;
}
- Bind (theGlCtx);
+ TheBaseClass::Bind (theGlCtx);
GLint aNbComp;
- const GLubyte* anOffset = NULL;
+ const GLubyte* anOffset = TheBaseClass::myOffset;
for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
{
const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
continue;
}
- bindFixed (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset);
+ TheBaseClass::bindAttribute (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset);
anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType);
}
}
- virtual void UnbindFixed (const Handle(OpenGl_Context)& theGlCtx) const
+ virtual void UnbindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const
{
- if (!IsValid())
+ if (!TheBaseClass::IsValid())
{
return;
}
- Unbind (theGlCtx);
+ TheBaseClass::Unbind (theGlCtx);
for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
{
const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
- unbindFixed (theGlCtx, anAttrib.Id);
+ TheBaseClass::unbindAttribute (theGlCtx, anAttrib.Id);
}
}
}
// =======================================================================
-// function : BuildVBO
+// function : initNormalVbo
// purpose :
// =======================================================================
-Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
+Standard_Boolean OpenGl_PrimitiveArray::initNormalVbo (const Handle(OpenGl_Context)& theCtx) const
{
- const Handle(OpenGl_Context)& aGlCtx = theWorkspace->GetGlContext();
- if (myAttribs.IsNull()
- || myAttribs->IsEmpty()
- || myAttribs->NbElements < 1)
+ switch (myAttribs->NbAttributes)
{
- // vertices should be always defined - others are optional
+ case 1: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 1> (*myAttribs); break;
+ case 2: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 2> (*myAttribs); break;
+ case 3: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 3> (*myAttribs); break;
+ case 4: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 4> (*myAttribs); break;
+ case 5: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 5> (*myAttribs); break;
+ case 6: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 6> (*myAttribs); break;
+ case 7: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 7> (*myAttribs); break;
+ case 8: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 8> (*myAttribs); break;
+ case 9: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 9> (*myAttribs); break;
+ case 10: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 10>(*myAttribs); break;
+ }
+
+ if (!myVboAttribs->init (theCtx, 0, myAttribs->NbElements, myAttribs->Data(), GL_NONE, myAttribs->Stride))
+ {
+ TCollection_ExtendedString aMsg;
+ aMsg += "VBO creation for Primitive Array has failed for ";
+ aMsg += myAttribs->NbElements;
+ aMsg += " vertices. Out of memory?";
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
+
+ clearMemoryGL (theCtx);
return Standard_False;
}
+ else if (myIndices.IsNull())
+ {
+ return Standard_True;
+ }
- switch (myAttribs->NbAttributes)
+ myVboIndices = new OpenGl_IndexBuffer();
+ bool isOk = false;
+ switch (myIndices->Stride)
+ {
+ case 2:
+ {
+ isOk = myVboIndices->Init (theCtx, 1, myIndices->NbElements, reinterpret_cast<const GLushort*> (myIndices->Data()));
+ break;
+ }
+ case 4:
+ {
+ isOk = myVboIndices->Init (theCtx, 1, myIndices->NbElements, reinterpret_cast<const GLuint*> (myIndices->Data()));
+ break;
+ }
+ default:
+ {
+ clearMemoryGL (theCtx);
+ return Standard_False;
+ }
+ }
+ if (!isOk)
{
- case 1: myVboAttribs = new OpenGl_VertexBufferT<1> (*myAttribs); break;
- case 2: myVboAttribs = new OpenGl_VertexBufferT<2> (*myAttribs); break;
- case 3: myVboAttribs = new OpenGl_VertexBufferT<3> (*myAttribs); break;
- case 4: myVboAttribs = new OpenGl_VertexBufferT<4> (*myAttribs); break;
- case 5: myVboAttribs = new OpenGl_VertexBufferT<5> (*myAttribs); break;
- case 6: myVboAttribs = new OpenGl_VertexBufferT<6> (*myAttribs); break;
- case 7: myVboAttribs = new OpenGl_VertexBufferT<7> (*myAttribs); break;
- case 8: myVboAttribs = new OpenGl_VertexBufferT<8> (*myAttribs); break;
- case 9: myVboAttribs = new OpenGl_VertexBufferT<9> (*myAttribs); break;
- case 10: myVboAttribs = new OpenGl_VertexBufferT<10>(*myAttribs); break;
- default: return Standard_False;
+ TCollection_ExtendedString aMsg;
+ aMsg += "VBO creation for Primitive Array has failed for ";
+ aMsg += myIndices->NbElements;
+ aMsg += " indices. Out of memory?";
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
+ clearMemoryGL (theCtx);
+ return Standard_False;
}
+ return Standard_True;
+}
- if (!myVboAttribs->init (aGlCtx, 0, myAttribs->NbElements, myAttribs->Data(), GL_NONE, myAttribs->Stride))
+// =======================================================================
+// function : buildVBO
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_PrimitiveArray::buildVBO (const Handle(OpenGl_Context)& theCtx,
+ const Standard_Boolean theToKeepData) const
+{
+ bool isNormalMode = theCtx->ToUseVbo();
+ clearMemoryGL (theCtx);
+ if (myAttribs.IsNull()
+ || myAttribs->IsEmpty()
+ || myAttribs->NbElements < 1
+ || myAttribs->NbAttributes < 1
+ || myAttribs->NbAttributes > 10)
{
- clearMemoryGL (aGlCtx);
+ // vertices should be always defined - others are optional
return Standard_False;
}
+ if (isNormalMode
+ && initNormalVbo (theCtx))
+ {
+ if (!theCtx->caps->keepArrayData
+ && !theToKeepData)
+ {
+ myIndices.Nullify();
+ myAttribs.Nullify();
+ }
+ return Standard_True;
+ }
+
+ Handle(OpenGl_VertexBufferCompat) aVboAttribs;
+ switch (myAttribs->NbAttributes)
+ {
+ case 1: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 1> (*myAttribs); break;
+ case 2: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 2> (*myAttribs); break;
+ case 3: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 3> (*myAttribs); break;
+ case 4: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 4> (*myAttribs); break;
+ case 5: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 5> (*myAttribs); break;
+ case 6: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 6> (*myAttribs); break;
+ case 7: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 7> (*myAttribs); break;
+ case 8: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 8> (*myAttribs); break;
+ case 9: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 9> (*myAttribs); break;
+ case 10: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 10>(*myAttribs); break;
+ }
+ aVboAttribs->initLink (myAttribs, 0, myAttribs->NbElements, GL_NONE);
if (!myIndices.IsNull())
{
- myVboIndices = new OpenGl_IndexBuffer();
- bool isOk = Standard_False;
+ Handle(OpenGl_VertexBufferCompat) aVboIndices = new OpenGl_VertexBufferCompat();
switch (myIndices->Stride)
{
case 2:
{
- isOk = myVboIndices->Init (aGlCtx, 1, myIndices->NbElements, reinterpret_cast<const GLushort*> (myIndices->Data()));
+ aVboIndices->initLink (myIndices, 1, myIndices->NbElements, GL_UNSIGNED_SHORT);
break;
}
case 4:
{
- isOk = myVboIndices->Init (aGlCtx, 1, myIndices->NbElements, reinterpret_cast<const GLuint*> (myIndices->Data()));
+ aVboIndices->initLink (myIndices, 1, myIndices->NbElements, GL_UNSIGNED_INT);
break;
}
- default: break;
- }
- if (!isOk)
- {
- clearMemoryGL (aGlCtx);
- return Standard_False;
+ default:
+ {
+ return Standard_False;
+ }
}
+ myVboIndices = aVboIndices;
}
-
- if (!aGlCtx->caps->keepArrayData)
+ myVboAttribs = aVboAttribs;
+ if (!theCtx->caps->keepArrayData
+ && !theToKeepData)
{
- myIndices.Nullify();
- myAttribs.Nullify();
+ // does not make sense for compatibility mode
+ //myIndices.Nullify();
+ //myAttribs.Nullify();
}
-
+
return Standard_True;
}
// =======================================================================
-// function : DrawArray
+// function : drawArray
// purpose :
// =======================================================================
-void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
- const Aspect_InteriorStyle theInteriorStyle,
- Tint theEdgeFlag,
- const TEL_COLOUR* theInteriorColour,
- const TEL_COLOUR* theLineColour,
- const TEL_COLOUR* theEdgeColour,
- const Handle(OpenGl_Workspace)& theWorkspace) const
+void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorkspace,
+ const Graphic3d_Vec4* theFaceColors,
+ const Standard_Boolean theHasVertColor) const
{
const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
- const Graphic3d_Vec4* aFaceColors = myBounds.IsNull() ? NULL : myBounds->Colors;
const bool toHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0;
- bool hasVColors = false;
-
- glColor3fv (myDrawMode <= GL_LINE_STRIP ? theLineColour->rgb : theInteriorColour->rgb);
-
- // Temporarily disable environment mapping
- if (myDrawMode <= GL_LINE_STRIP)
+ bool hasVColors = theHasVertColor && !toHilight;
+ if (myVboAttribs.IsNull())
{
- glPushAttrib (GL_ENABLE_BIT);
- glDisable (GL_TEXTURE_1D);
- glDisable (GL_TEXTURE_2D);
+ #if !defined(GL_ES_VERSION_2_0)
+ if (myDrawMode == GL_POINTS)
+ {
+ // extreme compatibility mode - without sprites but with markers
+ drawMarkers (theWorkspace);
+ }
+ #endif
+ return;
}
- if ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
- (myDrawMode <= GL_LINE_STRIP))
+ myVboAttribs->BindAllAttributes (aGlContext);
+ if (theHasVertColor && toHilight)
+ {
+ // disable per-vertex color
+ OpenGl_VertexBuffer::unbindAttribute (aGlContext, Graphic3d_TOA_COLOR);
+ }
+ if (!myVboIndices.IsNull())
{
- if (toHilight)
+ myVboIndices->Bind (aGlContext);
+ GLubyte* anOffset = myVboIndices->GetDataOffset();
+ if (!myBounds.IsNull())
{
- aFaceColors = NULL;
+ // draw primitives by vertex count with the indices
+ const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
+ for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
+ {
+ const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+ if (theFaceColors != NULL) aGlContext->SetColor4fv (theFaceColors[aGroupIter]);
+ glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
+ anOffset += aStride * aNbElemsInGroup;
+ }
}
-
- if (theInteriorStyle == Aspect_IS_HIDDENLINE)
+ else
{
- theEdgeFlag = 1;
- aFaceColors = NULL;
+ // draw one (or sequential) primitive by the indices
+ glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset);
}
-
- // Sometimes the GL_LIGHTING mode is activated here
- // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
- // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
- if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
- glDisable (GL_LIGHTING);
- else
- glEnable (GL_LIGHTING);
-
- if (!myVboAttribs.IsNull())
+ myVboIndices->Unbind (aGlContext);
+ }
+ else if (!myBounds.IsNull())
+ {
+ GLint aFirstElem = 0;
+ for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
{
- myVboAttribs->BindFixed (aGlContext);
- if (myVboAttribs->HasColorAttribute())
- {
- if (toHilight)
- {
- // disable per-vertex colors
- OpenGl_VertexBuffer::unbindFixed (aGlContext, Graphic3d_TOA_COLOR);
- }
- else
- {
- hasVColors = true;
- }
- }
- if (!myVboIndices.IsNull())
- {
- myVboIndices->Bind (aGlContext);
- if (!myBounds.IsNull())
- {
- // draw primitives by vertex count with the indices
- const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
- GLubyte* anOffset = NULL;
- for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
- {
- const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData());
- glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
- anOffset += aStride * aNbElemsInGroup;
- }
- }
- else
- {
- // draw one (or sequential) primitive by the indices
- glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), NULL);
- }
- myVboIndices->Unbind (aGlContext);
- }
- else if (!myBounds.IsNull())
- {
- GLint aFirstElem = 0;
- for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
- {
- const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData());
- glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
- aFirstElem += aNbElemsInGroup;
- }
- }
- else
- {
- if (myDrawMode == GL_POINTS)
- {
- DrawMarkers (theWorkspace);
- }
- else
- {
- glDrawArrays (myDrawMode, 0, myVboAttribs->GetElemsNb());
- }
- }
-
- // bind with 0
- myVboAttribs->UnbindFixed (aGlContext);
+ const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+ if (theFaceColors != NULL) aGlContext->SetColor4fv (theFaceColors[aGroupIter]);
+ glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
+ aFirstElem += aNbElemsInGroup;
+ }
+ }
+ else
+ {
+ if (myDrawMode == GL_POINTS)
+ {
+ drawMarkers (theWorkspace);
}
else
{
- GLint aNbComp;
- for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter)
- {
- const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter);
- if (anAttrib.Id == Graphic3d_TOA_COLOR)
- {
- if (toHilight)
- {
- continue;
- }
- hasVColors = true;
- }
- const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp);
- const GLvoid* aData = myAttribs->Data (anAttribIter);
- if (aDataType == GL_NONE)
- {
- continue;
- }
-
- OpenGl_VertexBuffer::bindFixed (aGlContext, anAttrib.Id, aNbComp, aDataType, myAttribs->Stride, aData);
- }
-
- if (!myBounds.IsNull())
- {
- GLint aFirstElem = 0;
- if (!myIndices.IsNull())
- {
- const GLenum anIndexType = toGlIndexType (myIndices->Stride);
- for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
- {
- const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData());
- glDrawElements (myDrawMode, aNbElemsInGroup, anIndexType, myIndices->value (aFirstElem));
- aFirstElem += aNbElemsInGroup;
- }
- }
- else
- {
- for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
- {
- const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData());
- glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
- aFirstElem += aNbElemsInGroup;
- }
- }
- }
- else if (!myIndices.IsNull())
- {
- glDrawElements (myDrawMode, myIndices->NbElements, toGlIndexType (myIndices->Stride), myIndices->Data());
- }
- else
- {
- if (myDrawMode == GL_POINTS)
- {
- DrawMarkers (theWorkspace);
- }
- else
- {
- glDrawArrays (myDrawMode, 0, myAttribs->NbElements);
- }
- }
-
- for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter)
- {
- const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter);
- OpenGl_VertexBuffer::unbindFixed (aGlContext, anAttrib.Id);
- }
+ glDrawArrays (myDrawMode, 0, myVboAttribs->GetElemsNb());
}
}
+ // bind with 0
+ myVboAttribs->UnbindAllAttributes (aGlContext);
+
if (hasVColors)
{
theWorkspace->NamedStatus |= OPENGL_NS_RESMAT;
}
-
- if (theEdgeFlag && myDrawMode > GL_LINE_STRIP)
- {
- DrawEdges (theEdgeColour, theWorkspace);
- }
-
- if (myDrawMode <= GL_LINE_STRIP)
- glPopAttrib();
}
// =======================================================================
-// function : DrawEdges
+// function : drawEdges
// purpose :
// =======================================================================
-void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour,
+void OpenGl_PrimitiveArray::drawEdges (const TEL_COLOUR* theEdgeColour,
const Handle(OpenGl_Workspace)& theWorkspace) const
{
- glDisable (GL_LIGHTING);
-
const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
- const OpenGl_AspectLine* anAspectLineOld = NULL;
- if (myDrawMode > GL_LINE_STRIP)
+ if (myVboAttribs.IsNull())
{
- anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
- const OpenGl_AspectLine* anAspect = theWorkspace->AspectLine (Standard_True);
+ return;
+ }
- glPushAttrib (GL_POLYGON_BIT);
- glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
+#if !defined(GL_ES_VERSION_2_0)
+ if (aGlContext->core11 != NULL)
+ {
+ glDisable (GL_LIGHTING);
+ }
+#endif
- if (aGlContext->IsGlGreaterEqual (2, 0))
- {
- BindProgramWithMaterial (theWorkspace, anAspect);
- }
+ const OpenGl_AspectLine* anAspectLineOld = NULL;
+
+ anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
+ const OpenGl_AspectLine* anAspect = theWorkspace->AspectLine (Standard_True);
+
+#if !defined(GL_ES_VERSION_2_0)
+ glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
+#endif
+
+ if (aGlContext->core20fwd != NULL)
+ {
+ aGlContext->ShaderManager()->BindProgram (anAspect, NULL, Standard_False, Standard_False, anAspect->ShaderProgramRes (aGlContext));
}
/// OCC22236 NOTE: draw edges for all situations:
/// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indices array
/// 2) draw elements from vertex array, when bounds defines count of primitive's vertices.
/// 3) draw primitive's edges by vertexes if no edges and bounds array is specified
- if (!myVboAttribs.IsNull())
+ myVboAttribs->BindPositionAttribute (aGlContext);
+
+ aGlContext->SetColor4fv (*(const OpenGl_Vec4* )theEdgeColour->rgb);
+ aGlContext->SetTypeOfLine (anAspect->Type());
+ aGlContext->SetLineWidth (anAspect->Width());
+
+ if (!myVboIndices.IsNull())
{
- myVboAttribs->BindFixedPosition (aGlContext);
- glColor3fv (theEdgeColour->rgb);
- if (!myVboIndices.IsNull())
- {
- myVboIndices->Bind (aGlContext);
+ myVboIndices->Bind (aGlContext);
+ GLubyte* anOffset = myVboIndices->GetDataOffset();
- // draw primitives by vertex count with the indices
- if (!myBounds.IsNull())
- {
- const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
- GLubyte* anOffset = NULL;
- for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
- {
- const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
- anOffset += aStride * aNbElemsInGroup;
- }
- }
- // draw one (or sequential) primitive by the indices
- else
- {
- glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), NULL);
- }
- myVboIndices->Unbind (aGlContext);
- }
- else if (!myBounds.IsNull())
+ // draw primitives by vertex count with the indices
+ if (!myBounds.IsNull())
{
- GLint aFirstElem = 0;
+ const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
{
const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
- aFirstElem += aNbElemsInGroup;
+ glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
+ anOffset += aStride * aNbElemsInGroup;
}
}
+ // draw one (or sequential) primitive by the indices
else
{
- glDrawArrays (myDrawMode, 0, myAttribs->NbElements);
+ glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset);
}
-
- // unbind buffers
- myVboAttribs->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
+ myVboIndices->Unbind (aGlContext);
}
- else
+ else if (!myBounds.IsNull())
{
- GLint aNbComp;
- for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter)
+ GLint aFirstElem = 0;
+ for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
{
- const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter);
- if (anAttrib.Id == Graphic3d_TOA_POS)
- {
- const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp);
- const GLvoid* aData = myAttribs->Data (anAttribIter);
- OpenGl_VertexBuffer::bindFixed (aGlContext, anAttrib.Id, aNbComp, aDataType, myAttribs->Stride, aData);
- break;
- }
- }
-
- glColor3fv (theEdgeColour->rgb);
- if (!myBounds.IsNull())
- {
- if (!myIndices.IsNull())
- {
- const GLenum anIndexType = toGlIndexType (myIndices->Stride);
- GLint aFirstElem = 0;
- for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
- {
- const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- glDrawElements (myDrawMode, aNbElemsInGroup, anIndexType, myIndices->value (aFirstElem));
- aFirstElem += aNbElemsInGroup;
- }
- }
- else
- {
- GLint aFirstElem = 0;
- for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
- {
- const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
- glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
- aFirstElem += aNbElemsInGroup;
- }
- }
- }
- else if (!myIndices.IsNull())
- {
- glDrawElements (myDrawMode, myIndices->NbElements, toGlIndexType (myIndices->Stride), myIndices->Data());
- }
- else
- {
- glDrawArrays (myDrawMode, 0, myAttribs->NbElements);
+ const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+ glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
+ aFirstElem += aNbElemsInGroup;
}
}
-
- if (myDrawMode > GL_LINE_STRIP)
+ else
{
- // Restore line context
- theWorkspace->SetAspectLine (anAspectLineOld);
- glPopAttrib();
+ glDrawArrays (myDrawMode, 0, myAttribs->NbElements);
}
+
+ // unbind buffers
+ myVboAttribs->UnbindAttribute (aGlContext, Graphic3d_TOA_POS);
+
+ // restore line context
+ theWorkspace->SetAspectLine (anAspectLineOld);
}
// =======================================================================
-// function : DrawMarkers
+// function : drawMarkers
// purpose :
// =======================================================================
-void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const
+void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const
{
const OpenGl_AspectMarker* anAspectMarker = theWorkspace->AspectMarker (Standard_True);
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (theWorkspace);
- const Standard_Boolean isHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT);
- if (aCtx->IsGlGreaterEqual (2, 0)
- && !aSpriteNorm.IsNull() && !aSpriteNorm->IsDisplayList())
+ const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
+ if (!aSpriteNorm.IsNull()
+ && !aSpriteNorm->IsDisplayList())
{
// Textured markers will be drawn with the point sprites
- glPointSize (anAspectMarker->MarkerSize());
-
- Handle(OpenGl_Texture) aTextureBack;
- if (anAspectMarker->Type() != Aspect_TOM_POINT)
+ aCtx->SetPointSize (anAspectMarker->MarkerSize());
+ #if !defined(GL_ES_VERSION_2_0)
+ if (aCtx->core11 != NULL)
{
- const Handle(OpenGl_PointSprite)& aSprite = (isHilight && anAspectMarker->SpriteHighlightRes (theWorkspace)->IsValid())
- ? anAspectMarker->SpriteHighlightRes (theWorkspace)
- : aSpriteNorm;
- aTextureBack = theWorkspace->EnableTexture (aSprite);
-
- glEnable (GL_ALPHA_TEST);
- glAlphaFunc (GL_GEQUAL, 0.1f);
-
- glEnable (GL_BLEND);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ aCtx->core11fwd->glEnable (GL_ALPHA_TEST);
+ aCtx->core11fwd->glAlphaFunc (GL_GEQUAL, 0.1f);
}
+ #endif
- glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
+ aCtx->core11fwd->glEnable (GL_BLEND);
+ aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDisable (GL_BLEND);
- glDisable (GL_ALPHA_TEST);
- if (anAspectMarker->Type() != Aspect_TOM_POINT)
+ aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
+
+ aCtx->core11fwd->glDisable (GL_BLEND);
+ #if !defined(GL_ES_VERSION_2_0)
+ if (aCtx->core11 != NULL)
{
- theWorkspace->EnableTexture (aTextureBack);
+ aCtx->core11fwd->glDisable (GL_ALPHA_TEST);
}
- glPointSize (1.0f);
+ #endif
+ aCtx->SetPointSize (1.0f);
return;
}
-
- // Textured markers will be drawn with the glBitmap
- if (anAspectMarker->Type() == Aspect_TOM_POINT
- || anAspectMarker->Type() == Aspect_TOM_O_POINT)
+ else if (anAspectMarker->Type() == Aspect_TOM_POINT)
{
- const GLfloat aPntSize = anAspectMarker->Type() == Aspect_TOM_POINT
- ? anAspectMarker->MarkerSize()
- : 0.0f;
- if (aPntSize > 0.0f)
- {
- glPointSize (aPntSize);
- }
- glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
- if (aPntSize > 0.0f)
- {
- glPointSize (1.0f);
- }
+ aCtx->SetPointSize (anAspectMarker->MarkerSize());
+ aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
+ aCtx->SetPointSize (1.0f);
}
-
- if (anAspectMarker->Type() != Aspect_TOM_POINT
- && !aSpriteNorm.IsNull())
+#if !defined(GL_ES_VERSION_2_0)
+ // Textured markers will be drawn with the glBitmap
+ else if (anAspectMarker->Type() != Aspect_TOM_POINT
+ && !aSpriteNorm.IsNull())
{
/**if (!isHilight && (myPArray->vcolours != NULL))
{
{
for (Standard_Integer anIter = 0; anIter < myAttribs->NbElements; anIter++)
{
- glRasterPos3fv (myAttribs->Value<Graphic3d_Vec3> (anIter).GetData());
+ aCtx->core11->glRasterPos3fv (myAttribs->Value<Graphic3d_Vec3> (anIter).GetData());
aSpriteNorm->DrawBitmap (theWorkspace->GetGlContext());
}
}
}
+#endif
+}
+
+// =======================================================================
+// function : OpenGl_PrimitiveArray
+// purpose :
+// =======================================================================
+OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (const OpenGl_GraphicDriver* theDriver)
+
+: myDrawMode (DRAW_MODE_NONE),
+ myIsVboInit (Standard_False)
+{
+ if (theDriver != NULL)
+ {
+ myUID = theDriver->GetNextPrimitiveArrayUID();
+ }
}
// =======================================================================
myAttribs (theAttribs),
myBounds (theBounds),
myDrawMode (DRAW_MODE_NONE),
- myIsVboInit (Standard_False),
- myUID (theDriver->GetNextPrimitiveArrayUID())
+ myIsVboInit (Standard_False)
{
if (!myIndices.IsNull()
&& myIndices->NbElements < 1)
// dummy index buffer?
myIndices.Nullify();
}
- if (myAttribs.IsNull())
- {
- return;
- }
- switch (theType)
+ if (theDriver != NULL)
{
- case Graphic3d_TOPA_POINTS:
- myDrawMode = GL_POINTS;
- break;
- case Graphic3d_TOPA_POLYLINES:
- myDrawMode = GL_LINE_STRIP;
- break;
- case Graphic3d_TOPA_SEGMENTS:
- myDrawMode = GL_LINES;
- break;
- case Graphic3d_TOPA_POLYGONS:
- myDrawMode = GL_POLYGON;
- break;
- case Graphic3d_TOPA_TRIANGLES:
- myDrawMode = GL_TRIANGLES;
- break;
- case Graphic3d_TOPA_QUADRANGLES:
- myDrawMode = GL_QUADS;
- break;
- case Graphic3d_TOPA_TRIANGLESTRIPS:
- myDrawMode = GL_TRIANGLE_STRIP;
- break;
- case Graphic3d_TOPA_QUADRANGLESTRIPS:
- myDrawMode = GL_QUAD_STRIP;
- break;
- case Graphic3d_TOPA_TRIANGLEFANS:
- myDrawMode = GL_TRIANGLE_FAN;
- break;
- case Graphic3d_TOPA_UNDEFINED:
- break;
+ 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);
}
// =======================================================================
// =======================================================================
void OpenGl_PrimitiveArray::Release (OpenGl_Context* theContext)
{
+ myIsVboInit = Standard_False;
if (!myVboIndices.IsNull())
{
if (theContext)
// create VBOs on first render call
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- if (!myIsVboInit
- && !aCtx->caps->vboDisable
- && aCtx->core15 != NULL
- && (myDrawMode != GL_POINTS || anAspectMarker->SpriteRes (theWorkspace).IsNull() || !anAspectMarker->SpriteRes (theWorkspace)->IsDisplayList()))
- {
- if (!BuildVBO (theWorkspace))
- {
- TCollection_ExtendedString aMsg;
- aMsg += "VBO creation for Primitive Array has failed for ";
- aMsg += myAttribs->NbElements;
- aMsg += " vertices. Out of memory?";
- aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
- }
+ if (!myIsVboInit)
+ {
+ // compatibility - keep data to draw markers using display lists
+ 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;
}
- if (myDrawMode <= GL_LINE_STRIP)
- {
- glDisable (GL_LIGHTING);
- }
-
Tint aFrontLightingModel = anAspectFace->IntFront().color_mask;
const TEL_COLOUR* anInteriorColor = &anAspectFace->IntFront().matcol;
const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
aFrontLightingModel = 0;
}
- if (aCtx->IsGlGreaterEqual (2, 0))
+ const Standard_Boolean hasColorAttrib = !myVboAttribs.IsNull()
+ && myVboAttribs->HasColorAttribute();
+ const Standard_Boolean isLightOn = aFrontLightingModel != 0
+ && !myVboAttribs.IsNull()
+ && myVboAttribs->HasNormalAttribute();
+#if !defined(GL_ES_VERSION_2_0)
+ // manage FFP lighting
+ if (aCtx->core11 != NULL)
{
- switch (myDrawMode)
+ if (!isLightOn)
{
- case GL_POINTS:
- {
- BindProgramWithMaterial (theWorkspace, anAspectMarker);
- break;
- }
- case GL_LINES:
- case GL_LINE_STRIP:
+ glDisable (GL_LIGHTING);
+ }
+ else
+ {
+ glEnable (GL_LIGHTING);
+ }
+ }
+#endif
+ // Temporarily disable environment mapping
+ Handle(OpenGl_Texture) aTextureBack;
+ if (myDrawMode <= GL_LINE_STRIP)
+ {
+ aTextureBack = theWorkspace->DisableTexture();
+ }
+
+ if ((myDrawMode > GL_LINE_STRIP && anAspectFace->InteriorStyle() != Aspect_IS_EMPTY) ||
+ (myDrawMode <= GL_LINE_STRIP))
+ {
+ const bool toHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0;
+ const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->InteriorStyle() != Aspect_IS_HIDDENLINE
+ ? myBounds->Colors
+ : NULL;
+ const Standard_Boolean hasVertColor = hasColorAttrib && !toHilight;
+ if (aCtx->core20fwd != NULL)
+ {
+ switch (myDrawMode)
{
- BindProgramWithMaterial (theWorkspace, anAspectLine);
- break;
+ case GL_POINTS:
+ {
+ const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
+ if (!aSpriteNorm.IsNull()
+ && !aSpriteNorm->IsDisplayList())
+ {
+ const Handle(OpenGl_PointSprite)& aSprite = (toHilight && anAspectMarker->SpriteHighlightRes (aCtx)->IsValid())
+ ? anAspectMarker->SpriteHighlightRes (aCtx)
+ : aSpriteNorm;
+ theWorkspace->EnableTexture (aSprite);
+ aCtx->ShaderManager()->BindProgram (anAspectMarker, aSprite, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
+ }
+ else
+ {
+ aCtx->ShaderManager()->BindProgram (anAspectMarker, NULL, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
+ }
+ break;
+ }
+ case GL_LINES:
+ case GL_LINE_STRIP:
+ {
+ aCtx->ShaderManager()->BindProgram (anAspectLine, NULL, isLightOn, hasVertColor, anAspectLine->ShaderProgramRes (aCtx));
+ break;
+ }
+ default:
+ {
+ const Handle(OpenGl_Texture)& aTexture = theWorkspace->ActiveTexture();
+ const Standard_Boolean isLightOnFace = isLightOn
+ && (aTexture.IsNull()
+ || aTexture->GetParams()->IsModulate());
+ aCtx->ShaderManager()->BindProgram (anAspectFace, aTexture, isLightOnFace, hasVertColor, anAspectFace->ShaderProgramRes (aCtx));
+ break;
+ }
}
- default: // polygonal array
+ }
+
+ if (!theWorkspace->ActiveTexture().IsNull()
+ && myDrawMode != GL_POINTS) // transformation is not supported within point sprites
+ {
+ aCtx->SetTextureMatrix (theWorkspace->ActiveTexture()->GetParams());
+ }
+
+ aCtx->SetColor4fv (*(const OpenGl_Vec4* )(myDrawMode <= GL_LINE_STRIP ? aLineColor->rgb : anInteriorColor->rgb));
+ if (myDrawMode == GL_LINES
+ || myDrawMode == GL_LINE_STRIP)
+ {
+ aCtx->SetTypeOfLine (anAspectLine->Type());
+ aCtx->SetLineWidth (anAspectLine->Width());
+ }
+
+ drawArray (theWorkspace, aFaceColors, hasColorAttrib);
+ }
+
+ if (myDrawMode <= GL_LINE_STRIP)
+ {
+ theWorkspace->EnableTexture (aTextureBack);
+ }
+ else
+ {
+ if (anAspectFace->Edge()
+ || anAspectFace->InteriorStyle() == Aspect_IS_HIDDENLINE)
+ {
+ drawEdges (anEdgeColor, theWorkspace);
+
+ // restore OpenGL polygon mode if needed
+ #if !defined(GL_ES_VERSION_2_0)
+ if (anAspectFace->InteriorStyle() >= Aspect_IS_HATCH)
{
- BindProgramWithMaterial (theWorkspace, anAspectFace);
- break;
+ glPolygonMode (GL_FRONT_AND_BACK,
+ anAspectFace->InteriorStyle() == Aspect_IS_POINT ? GL_POINT : GL_FILL);
}
+ #endif
}
}
- DrawArray (aFrontLightingModel,
- anAspectFace->InteriorStyle(),
- anAspectFace->Edge(),
- anInteriorColor,
- aLineColor,
- anEdgeColor,
- theWorkspace);
+ aCtx->BindProgram (NULL);
+}
+
+// =======================================================================
+// function : setDrawMode
+// purpose :
+// =======================================================================
+void OpenGl_PrimitiveArray::setDrawMode (const Graphic3d_TypeOfPrimitiveArray theType)
+{
+ if (myAttribs.IsNull())
+ {
+ myDrawMode = DRAW_MODE_NONE;
+ return;
+ }
+
+ switch (theType)
+ {
+ case Graphic3d_TOPA_POINTS:
+ myDrawMode = GL_POINTS;
+ break;
+ case Graphic3d_TOPA_POLYLINES:
+ myDrawMode = GL_LINE_STRIP;
+ break;
+ case Graphic3d_TOPA_SEGMENTS:
+ myDrawMode = GL_LINES;
+ break;
+ case Graphic3d_TOPA_TRIANGLES:
+ myDrawMode = GL_TRIANGLES;
+ break;
+ case Graphic3d_TOPA_TRIANGLESTRIPS:
+ myDrawMode = GL_TRIANGLE_STRIP;
+ break;
+ case Graphic3d_TOPA_TRIANGLEFANS:
+ myDrawMode = GL_TRIANGLE_FAN;
+ break;
+ #if !defined(GL_ES_VERSION_2_0)
+ case Graphic3d_TOPA_POLYGONS:
+ myDrawMode = GL_POLYGON;
+ break;
+ case Graphic3d_TOPA_QUADRANGLES:
+ myDrawMode = GL_QUADS;
+ break;
+ case Graphic3d_TOPA_QUADRANGLESTRIPS:
+ myDrawMode = GL_QUAD_STRIP;
+ break;
+ #else
+ case Graphic3d_TOPA_POLYGONS:
+ case Graphic3d_TOPA_QUADRANGLES:
+ case Graphic3d_TOPA_QUADRANGLESTRIPS:
+ #endif
+ case Graphic3d_TOPA_UNDEFINED:
+ break;
+ }
+}
+
+// =======================================================================
+// 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 :
+// =======================================================================
+void OpenGl_PrimitiveArray::InitBuffers (const Handle(OpenGl_Context)& theContext,
+ const Graphic3d_TypeOfPrimitiveArray theType,
+ const Handle(Graphic3d_IndexBuffer)& theIndices,
+ const Handle(Graphic3d_Buffer)& theAttribs,
+ const Handle(Graphic3d_BoundBuffer)& theBounds)
+{
+ // Release old graphic resources
+ Release (theContext.operator->());
+
+ myIndices = theIndices;
+ myAttribs = theAttribs;
+ myBounds = theBounds;
+#if defined(GL_ES_VERSION_2_0)
+ processIndices (theContext);
+#endif
+
+ setDrawMode (theType);
}