+/// Step between icons
+static const double MyDist = 0.02;
+
+/// Function to convert opengl data type
+GLenum toGlDataType (const Graphic3d_TypeOfData theType, GLint& theNbComp)
+{
+ switch (theType) {
+ case Graphic3d_TOD_USHORT:
+ theNbComp = 1;
+ return GL_UNSIGNED_SHORT;
+ case Graphic3d_TOD_UINT:
+ theNbComp = 1;
+ return GL_UNSIGNED_INT;
+ case Graphic3d_TOD_VEC2:
+ theNbComp = 2;
+ return GL_FLOAT;
+ case Graphic3d_TOD_VEC3:
+ theNbComp = 3;
+ return GL_FLOAT;
+ case Graphic3d_TOD_VEC4:
+ theNbComp = 4;
+ return GL_FLOAT;
+ case Graphic3d_TOD_VEC4UB:
+ theNbComp = 4;
+ return GL_UNSIGNED_BYTE;
+ }
+ theNbComp = 0;
+ return GL_NONE;
+}
+
+
+//*******************************************************************
+//! Auxiliary class for Vertex buffer with interleaved attributes.
+class SketcherPrs_VertexBuffer : public OpenGl_VertexBuffer
+{
+
+public:
+
+ //! Create uninitialized VBO..
+ //! \param theAttribs attributes
+ //! \param theStride a flag
+ SketcherPrs_VertexBuffer (const Graphic3d_Attribute* theAttribs,
+ const Standard_Integer theStride)
+ : Stride (theStride), NbAttributes(1)
+ {
+
+ memcpy (Attribs, theAttribs, sizeof(Graphic3d_Attribute) * NbAttributes);
+ }
+
+ //! Create uninitialized VBO.
+ SketcherPrs_VertexBuffer (const Graphic3d_Buffer& theAttribs)
+ : Stride (theAttribs.Stride), NbAttributes(1)
+ {
+ memcpy (Attribs, theAttribs.AttributesArray(), sizeof(Graphic3d_Attribute) * NbAttributes);
+ }
+
+ /// Returns True if color attribute is defined
+ virtual bool HasColorAttribute() const
+ {
+ for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) {
+ const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+ if (anAttrib.Id == Graphic3d_TOA_COLOR) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// Returns True if normal attribute is defined
+ 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;
+ }
+
+ /// Bind position of the attribute
+ /// \param theGlCtx OpenGl context
+ virtual void BindPositionAttribute (const Handle(OpenGl_Context)& theGlCtx) const
+ {
+ if (!OpenGl_VertexBuffer::IsValid()) {
+ return;
+ }
+
+ OpenGl_VertexBuffer::Bind (theGlCtx);
+ GLint aNbComp;
+ const GLubyte* anOffset = OpenGl_VertexBuffer::myOffset;
+ for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) {
+ const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+ const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp);
+ if (aDataType == GL_NONE) {
+ continue;
+ } else if (anAttrib.Id == Graphic3d_TOA_POS) {
+ OpenGl_VertexBuffer::bindAttribute (theGlCtx, Graphic3d_TOA_POS, aNbComp, aDataType, Stride, anOffset);
+ break;
+ }
+
+ anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType);
+ }
+ }
+
+ /// Bind all attributes
+ /// \param theGlCtx OpenGl context
+ virtual void BindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const
+ {
+ if (!OpenGl_VertexBuffer::IsValid())
+ return;
+
+ OpenGl_VertexBuffer::Bind (theGlCtx);
+ GLint aNbComp;
+ const GLubyte* anOffset = OpenGl_VertexBuffer::myOffset;
+ for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
+ {
+ const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+ const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp);
+ if (aDataType == GL_NONE)
+ continue;
+
+ OpenGl_VertexBuffer::bindAttribute (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset);
+ anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType);
+ }
+ }
+
+ /// Unbind all attributes
+ /// \param theGlCtx OpenGl context
+ virtual void UnbindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const
+ {
+ if (!OpenGl_VertexBuffer::IsValid())
+ return;
+ OpenGl_VertexBuffer::Unbind (theGlCtx);
+
+ for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) {
+ const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+ OpenGl_VertexBuffer::unbindAttribute (theGlCtx, anAttrib.Id);
+ }
+ }
+
+public:
+
+ /// Array of attributes
+ Graphic3d_Attribute Attribs[1];
+
+ /// A flag
+ Standard_Integer Stride;
+
+ /// Number of attributes
+ Standard_Integer NbAttributes;
+};
+
+//**************************************************************
+//! Redefinition of OpenGl_Element
+class SketcherPrs_Element: public OpenGl_Element
+{
+public:
+ /// Constructor
+ /// \param theObj a presentation
+ SketcherPrs_Element(const Handle(SketcherPrs_SymbolPrs)& theObj) :
+ OpenGl_Element(), myObj(theObj) {}
+
+ /// Render the current presentation
+ /// \param theWorkspace OpenGL workspace
+ virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
+ {
+ if (!myObj.IsNull())
+ myObj->Render(theWorkspace);
+ }
+
+ /// Releases OpenGL resources
+ /// \param theContext OpenGL context
+ virtual void Release (OpenGl_Context* theContext)
+ {
+ if (!myObj.IsNull())
+ myObj->Release(theContext);
+ }
+
+private:
+ Handle(SketcherPrs_SymbolPrs) myObj;
+};
+
+
+//**************************************************************
+//! Definition of call back
+OpenGl_Element* SymbolPrsCallBack(const CALL_DEF_USERDRAW * theUserDraw)
+{
+ Handle(SketcherPrs_SymbolPrs) anIObj = (SketcherPrs_SymbolPrs*)theUserDraw->Data;
+ if (anIObj.IsNull()) {
+ std::cout << "VUserDrawCallback error: null object passed, the custom scene element will not be rendered" << std::endl;
+ }
+ return new SketcherPrs_Element(anIObj);
+}
+
+
+//*****************************************************************************