1 // Created on: 2011-07-13
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2013 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_AspectFace.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_GraphicDriver.hxx>
19 #include <OpenGl_IndexBuffer.hxx>
20 #include <OpenGl_PointSprite.hxx>
21 #include <OpenGl_PrimitiveArray.hxx>
22 #include <OpenGl_ShaderManager.hxx>
23 #include <OpenGl_ShaderProgram.hxx>
24 #include <OpenGl_Structure.hxx>
25 #include <OpenGl_Workspace.hxx>
27 #include <InterfaceGraphic_PrimitiveArray.hxx>
32 void BindProgramWithMaterial (const Handle(OpenGl_Workspace)& theWS,
35 const Handle(OpenGl_Context)& aCtx = theWS->GetGlContext();
36 const Handle(OpenGl_ShaderProgram)& aProgram = theAspect->ShaderProgramRes (theWS);
37 if (aProgram.IsNull())
39 OpenGl_ShaderProgram::Unbind (aCtx);
42 aProgram->BindWithVariables (aCtx);
44 const OpenGl_MaterialState* aMaterialState = aCtx->ShaderManager()->MaterialState (aProgram);
45 if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
47 aCtx->ShaderManager()->UpdateMaterialStateTo (aProgram, theAspect);
50 aCtx->ShaderManager()->PushState (aProgram);
54 // =======================================================================
55 // function : clearMemoryOwn
57 // =======================================================================
58 void OpenGl_PrimitiveArray::clearMemoryOwn() const
60 Standard::Free ((Standard_Address& )myPArray->edges);
61 Standard::Free ((Standard_Address& )myPArray->vertices);
62 Standard::Free ((Standard_Address& )myPArray->vcolours);
63 Standard::Free ((Standard_Address& )myPArray->vnormals);
64 Standard::Free ((Standard_Address& )myPArray->vtexels);
65 Standard::Free ((Standard_Address& )myPArray->edge_vis); /// ???
67 myPArray->edges = NULL;
68 myPArray->vertices = NULL;
69 myPArray->vcolours = NULL;
70 myPArray->vnormals = NULL;
71 myPArray->vtexels = NULL;
72 myPArray->edge_vis = NULL;
75 // =======================================================================
76 // function : clearMemoryGL
78 // =======================================================================
79 void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const
81 for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
83 if (!myVbos[anIter].IsNull())
85 myVbos[anIter]->Release (theGlCtx.operator->());
86 myVbos[anIter].Nullify();
91 // =======================================================================
92 // function : BuildVBO
94 // =======================================================================
95 Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
97 const Handle(OpenGl_Context)& aGlCtx = theWorkspace->GetGlContext();
98 if (myPArray->vertices == NULL)
100 // vertices should be always defined - others are optional
101 return Standard_False;
103 myVbos[VBOVertices] = new OpenGl_VertexBuffer();
104 if (!myVbos[VBOVertices]->Init (aGlCtx, 3, myPArray->num_vertexs, &myPArray->vertices[0].xyz[0]))
106 clearMemoryGL (aGlCtx);
107 return Standard_False;
110 if (myPArray->edges != NULL
111 && myPArray->num_edges > 0)
113 myVbos[VBOEdges] = new OpenGl_IndexBuffer();
114 if (!myVbos[VBOEdges]->Init (aGlCtx, 1, myPArray->num_edges, (GLuint* )myPArray->edges))
116 clearMemoryGL (aGlCtx);
117 return Standard_False;
120 if (myPArray->vcolours != NULL)
122 myVbos[VBOVcolours] = new OpenGl_VertexBuffer();
123 if (!myVbos[VBOVcolours]->Init (aGlCtx, 4, myPArray->num_vertexs, (GLubyte* )myPArray->vcolours))
125 clearMemoryGL (aGlCtx);
126 return Standard_False;
129 if (myPArray->vnormals != NULL)
131 myVbos[VBOVnormals] = new OpenGl_VertexBuffer();
132 if (!myVbos[VBOVnormals]->Init (aGlCtx, 3, myPArray->num_vertexs, &myPArray->vnormals[0].xyz[0]))
134 clearMemoryGL (aGlCtx);
135 return Standard_False;
138 if (myPArray->vtexels)
140 myVbos[VBOVtexels] = new OpenGl_VertexBuffer();
141 if (!myVbos[VBOVtexels]->Init (aGlCtx, 2, myPArray->num_vertexs, &myPArray->vtexels[0].xy[0]))
143 clearMemoryGL (aGlCtx);
144 return Standard_False;
148 if (!aGlCtx->caps->keepArrayData)
153 return Standard_True;
156 // =======================================================================
157 // function : DrawArray
159 // =======================================================================
160 void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
161 const Aspect_InteriorStyle theInteriorStyle,
163 const TEL_COLOUR* theInteriorColour,
164 const TEL_COLOUR* theLineColour,
165 const TEL_COLOUR* theEdgeColour,
166 const OPENGL_SURF_PROP* theFaceProp,
167 const Handle(OpenGl_Workspace)& theWorkspace) const
169 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
173 // Following pointers have been provided for performance improvement
174 tel_colour pfc = myPArray->fcolours;
175 Tint* pvc = myPArray->vcolours;
178 for (i = 0; i < myPArray->num_vertexs; ++i)
180 transp = int(theFaceProp->trans * 255.0f);
181 #if defined (sparc) || defined (__sparc__) || defined (__sparc)
182 pvc[i] = (pvc[i] & 0xffffff00);
185 pvc[i] = (pvc[i] & 0x00ffffff);
186 pvc[i] += transp << 24;
191 switch (myPArray->type)
193 case TelPointsArrayType:
194 case TelPolylinesArrayType:
195 case TelSegmentsArrayType:
196 glColor3fv (theLineColour->rgb);
198 case TelPolygonsArrayType:
199 case TelTrianglesArrayType:
200 case TelQuadranglesArrayType:
201 case TelTriangleStripsArrayType:
202 case TelQuadrangleStripsArrayType:
203 case TelTriangleFansArrayType:
204 glColor3fv (theInteriorColour->rgb);
206 case TelUnknownArrayType:
210 // Temporarily disable environment mapping
211 if (myDrawMode <= GL_LINE_STRIP)
213 glPushAttrib (GL_ENABLE_BIT);
214 glDisable (GL_TEXTURE_1D);
215 glDisable (GL_TEXTURE_2D);
218 if ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
219 (myDrawMode <= GL_LINE_STRIP))
221 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
227 if (theInteriorStyle == Aspect_IS_HIDDENLINE)
234 // Sometimes the GL_LIGHTING mode is activated here
235 // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
236 // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
237 if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
238 glDisable (GL_LIGHTING);
240 glEnable (GL_LIGHTING);
244 if (myPArray->vertices != NULL)
246 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
247 glEnableClientState (GL_VERTEX_ARRAY);
249 if (myPArray->vnormals != NULL)
251 glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
252 glEnableClientState (GL_NORMAL_ARRAY);
254 if (myPArray->vtexels != NULL)
256 glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
257 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
260 if ((pvc != NULL) && (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) == 0)
262 glColorPointer (4, GL_UNSIGNED_BYTE, 0, pvc); // array of colors
263 glEnableClientState (GL_COLOR_ARRAY);
264 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
265 glEnable (GL_COLOR_MATERIAL);
270 // Bindings concrete pointer in accordance with VBO buffer
271 myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
272 if (!myVbos[VBOVnormals].IsNull())
274 myVbos[VBOVnormals]->BindFixed (aGlContext, GL_NORMAL_ARRAY);
276 if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
278 myVbos[VBOVtexels]->BindFixed (aGlContext, GL_TEXTURE_COORD_ARRAY);
280 if (!myVbos[VBOVcolours].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) == 0)
282 myVbos[VBOVcolours]->BindFixed (aGlContext, GL_COLOR_ARRAY);
283 glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
284 glEnable (GL_COLOR_MATERIAL);
288 /// OCC22236 NOTE: draw for all situations:
289 /// 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
290 /// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
291 /// 3) draw primitive by vertexes if no edges and bounds array is specified
294 if (!myVbos[VBOEdges].IsNull())
296 myVbos[VBOEdges]->Bind (aGlContext);
297 if (myPArray->num_bounds > 0)
299 // draw primitives by vertex count with the indicies
300 Tint* anOffset = NULL;
301 for (i = 0; i < myPArray->num_bounds; ++i)
303 if (pfc != NULL) glColor3fv (pfc[i].rgb);
304 glDrawElements (myDrawMode, myPArray->bounds[i], myVbos[VBOEdges]->GetDataType(), anOffset);
305 anOffset += myPArray->bounds[i];
310 // draw one (or sequential) primitive by the indicies
311 glDrawElements (myDrawMode, myPArray->num_edges, myVbos[VBOEdges]->GetDataType(), NULL);
313 myVbos[VBOEdges]->Unbind (aGlContext);
315 else if (myPArray->num_bounds > 0)
317 for (i = n = 0; i < myPArray->num_bounds; ++i)
319 if (pfc != NULL) glColor3fv (pfc[i].rgb);
320 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
321 n += myPArray->bounds[i];
326 if (myDrawMode == GL_POINTS)
328 DrawMarkers (theWorkspace);
332 glDrawArrays (myDrawMode, 0, myVbos[VBOVertices]->GetElemsNb());
337 myVbos[VBOVertices]->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
338 if (!myVbos[VBOVnormals].IsNull())
340 myVbos[VBOVnormals]->UnbindFixed (aGlContext, GL_NORMAL_ARRAY);
342 if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
344 myVbos[VBOVtexels]->UnbindFixed (aGlContext, GL_TEXTURE_COORD_ARRAY);
346 if (!myVbos[VBOVcolours].IsNull())
348 myVbos[VBOVcolours]->UnbindFixed (aGlContext, GL_COLOR_ARRAY);
349 glDisable (GL_COLOR_MATERIAL);
350 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
355 if (myPArray->num_bounds > 0)
357 if (myPArray->num_edges > 0)
359 for (i = n = 0; i < myPArray->num_bounds; ++i)
361 if (pfc != NULL) glColor3fv (pfc[i].rgb);
362 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
363 n += myPArray->bounds[i];
368 for (i = n = 0; i < myPArray->num_bounds; ++i)
370 if (pfc != NULL) glColor3fv (pfc[i].rgb);
371 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
372 n += myPArray->bounds[i];
376 else if (myPArray->num_edges > 0)
378 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
382 if (myDrawMode == GL_POINTS)
384 DrawMarkers (theWorkspace);
388 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
394 glDisable (GL_COLOR_MATERIAL);
395 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
398 glDisableClientState (GL_VERTEX_ARRAY);
399 if (myPArray->vcolours != NULL)
400 glDisableClientState (GL_COLOR_ARRAY);
401 if (myPArray->vnormals != NULL)
402 glDisableClientState (GL_NORMAL_ARRAY);
403 if (myPArray->vtexels != NULL)
404 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
408 // On some NVIDIA graphic cards, using glEdgeFlagPointer() in
409 // combination with VBO (edge flag data put into a VBO buffer)
410 // leads to a crash in a driver. Therefore, edge flags are simply
411 // igonored when VBOs are enabled, so all the edges are drawn if
412 // edge visibility is turned on. In order to draw edges selectively,
413 // either disable VBO or turn off edge visibilty in the current
414 // primitive array and create a separate primitive array (segments)
415 // and put edges to be drawn into it.
416 if (theEdgeFlag && myDrawMode > GL_LINE_STRIP)
418 DrawEdges (theEdgeColour, theWorkspace);
421 if (myDrawMode <= GL_LINE_STRIP)
425 // =======================================================================
426 // function : DrawEdges
428 // =======================================================================
429 void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour,
430 const Handle(OpenGl_Workspace)& theWorkspace) const
432 glDisable (GL_LIGHTING);
434 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
435 const OpenGl_AspectLine* anAspectLineOld = NULL;
436 if (myDrawMode > GL_LINE_STRIP)
438 anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
439 const OpenGl_AspectLine* anAspect = theWorkspace->AspectLine (Standard_True);
441 glPushAttrib (GL_POLYGON_BIT);
442 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
444 if (aGlContext->IsGlGreaterEqual (2, 0))
446 BindProgramWithMaterial (theWorkspace, anAspect);
452 /// OCC22236 NOTE: draw edges for all situations:
453 /// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
454 /// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
455 /// 3) draw primitive's edges by vertexes if no edges and bounds array is specified
458 myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
459 glColor3fv (theEdgeColour->rgb);
460 if (!myVbos[VBOEdges].IsNull())
462 myVbos[VBOEdges]->Bind (aGlContext);
464 // draw primitives by vertex count with the indicies
465 if (myPArray->num_bounds > 0)
468 for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
470 glDrawElements (myDrawMode, myPArray->bounds[i], myVbos[VBOEdges]->GetDataType(), offset);
471 offset += myPArray->bounds[i];
474 // draw one (or sequential) primitive by the indicies
477 glDrawElements (myDrawMode, myVbos[VBOEdges]->GetElemsNb(), myVbos[VBOEdges]->GetDataType(), NULL);
479 myVbos[VBOEdges]->Unbind (aGlContext);
481 else if (myPArray->num_bounds > 0)
483 for (i = n = 0; i < myPArray->num_bounds; ++i)
485 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
486 n += myPArray->bounds[i];
491 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
495 myVbos[VBOVertices]->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
499 glEnableClientState (GL_VERTEX_ARRAY);
500 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
502 glColor3fv (theEdgeColour->rgb);
503 if (myPArray->num_bounds > 0)
505 if (myPArray->num_edges > 0)
507 for (i = n = 0; i < myPArray->num_bounds; ++i)
509 if (myPArray->edge_vis)
511 glBegin (myDrawMode);
512 for (j = 0; j < myPArray->bounds[i]; ++j)
514 glEdgeFlag (myPArray->edge_vis[n+j]);
515 glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
521 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
523 n += myPArray->bounds[i];
528 for (i = n = 0 ; i < myPArray->num_bounds; ++i)
530 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
531 n += myPArray->bounds[i];
535 else if (myPArray->num_edges > 0)
537 if (myPArray->edge_vis)
539 glBegin (myDrawMode);
540 for (i = 0; i < myPArray->num_edges; ++i)
542 glEdgeFlag (myPArray->edge_vis[i]);
543 glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
549 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
554 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
558 if (myDrawMode > GL_LINE_STRIP)
560 // Restore line context
561 theWorkspace->SetAspectLine (anAspectLineOld);
566 // =======================================================================
567 // function : DrawMarkers
569 // =======================================================================
570 void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const
572 const OpenGl_AspectMarker* anAspectMarker = theWorkspace->AspectMarker (Standard_True);
573 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
574 const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (theWorkspace);
575 const Standard_Boolean isHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT);
576 if (aCtx->IsGlGreaterEqual (2, 0)
577 && !aSpriteNorm.IsNull() && !aSpriteNorm->IsDisplayList())
579 // Textured markers will be drawn with the point sprites
580 glPointSize (anAspectMarker->MarkerSize());
582 Handle(OpenGl_Texture) aTextureBack;
583 if (anAspectMarker->Type() != Aspect_TOM_POINT)
585 const Handle(OpenGl_PointSprite)& aSprite = (isHilight && anAspectMarker->SpriteHighlightRes (theWorkspace)->IsValid())
586 ? anAspectMarker->SpriteHighlightRes (theWorkspace)
588 aTextureBack = theWorkspace->EnableTexture (aSprite);
590 glEnable (GL_ALPHA_TEST);
591 glAlphaFunc (GL_GEQUAL, 0.1f);
594 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
597 glDrawArrays (myDrawMode, 0, toDrawVbo() ? myVbos[VBOVertices]->GetElemsNb() : myPArray->num_vertexs);
599 glDisable (GL_BLEND);
600 glDisable (GL_ALPHA_TEST);
601 if (anAspectMarker->Type() != Aspect_TOM_POINT)
603 theWorkspace->EnableTexture (aTextureBack);
609 // Textured markers will be drawn with the glBitmap
610 if (anAspectMarker->Type() == Aspect_TOM_POINT
611 || anAspectMarker->Type() == Aspect_TOM_O_POINT)
613 const GLfloat aPntSize = anAspectMarker->Type() == Aspect_TOM_POINT
614 ? anAspectMarker->MarkerSize()
618 glPointSize (aPntSize);
620 glDrawArrays (myDrawMode, 0, toDrawVbo() ? myVbos[VBOVertices]->GetElemsNb() : myPArray->num_vertexs);
627 if (anAspectMarker->Type() != Aspect_TOM_POINT
628 && !aSpriteNorm.IsNull())
630 if (!isHilight && (myPArray->vcolours != NULL))
632 for (Standard_Integer anIter = 0; anIter < myPArray->num_vertexs; anIter++)
634 glColor4ubv ((GLubyte* )&myPArray->vcolours[anIter]);
635 glRasterPos3fv (myPArray->vertices[anIter].xyz);
636 aSpriteNorm->DrawBitmap (theWorkspace->GetGlContext());
641 for (Standard_Integer anIter = 0; anIter < myPArray->num_vertexs; anIter++)
643 glRasterPos3fv (myPArray->vertices[anIter].xyz);
644 aSpriteNorm->DrawBitmap (theWorkspace->GetGlContext());
650 // =======================================================================
651 // function : OpenGl_PrimitiveArray
653 // =======================================================================
654 OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
655 : myPArray (thePArray),
656 myDrawMode (DRAW_MODE_NONE),
657 myIsVboInit (Standard_False)
659 switch (myPArray->type)
661 case TelPointsArrayType:
662 myDrawMode = GL_POINTS;
664 case TelPolylinesArrayType:
665 myDrawMode = GL_LINE_STRIP;
667 case TelSegmentsArrayType:
668 myDrawMode = GL_LINES;
670 case TelPolygonsArrayType:
671 myDrawMode = GL_POLYGON;
673 case TelTrianglesArrayType:
674 myDrawMode = GL_TRIANGLES;
676 case TelQuadranglesArrayType:
677 myDrawMode = GL_QUADS;
679 case TelTriangleStripsArrayType:
680 myDrawMode = GL_TRIANGLE_STRIP;
682 case TelQuadrangleStripsArrayType:
683 myDrawMode = GL_QUAD_STRIP;
685 case TelTriangleFansArrayType:
686 myDrawMode = GL_TRIANGLE_FAN;
688 case TelUnknownArrayType:
693 // =======================================================================
694 // function : ~OpenGl_PrimitiveArray
696 // =======================================================================
697 OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray()
702 // =======================================================================
703 // function : Release
705 // =======================================================================
706 void OpenGl_PrimitiveArray::Release (const Handle(OpenGl_Context)& theContext)
708 for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
710 if (!myVbos[anIter].IsNull())
712 if (!theContext.IsNull())
714 theContext->DelayedRelease (myVbos[anIter]);
716 myVbos[anIter].Nullify();
721 // =======================================================================
724 // =======================================================================
725 void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
727 if (myPArray == NULL || myDrawMode == DRAW_MODE_NONE || myPArray->num_vertexs <= 0)
732 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
733 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
734 const OpenGl_AspectMarker* anAspectMarker = theWorkspace->AspectMarker (myDrawMode == GL_POINTS);
736 // create VBOs on first render call
737 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
739 && !aCtx->caps->vboDisable
740 && aCtx->core15 != NULL
741 && (myDrawMode != GL_POINTS || anAspectMarker->SpriteRes (theWorkspace).IsNull() || !anAspectMarker->SpriteRes (theWorkspace)->IsDisplayList()))
743 if (!BuildVBO (theWorkspace))
745 TCollection_ExtendedString aMsg;
746 aMsg += "VBO creation for Primitive Array has failed for ";
747 aMsg += myPArray->num_vertexs;
748 aMsg += " vertices. Out of memory?";
749 aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
751 myIsVboInit = Standard_True;
754 switch (myPArray->type)
756 case TelPointsArrayType:
757 case TelPolylinesArrayType:
758 case TelSegmentsArrayType:
760 glDisable (GL_LIGHTING);
767 Tint aFrontLightingModel = anAspectFace->IntFront().color_mask;
768 const TEL_COLOUR* anInteriorColor = &anAspectFace->IntFront().matcol;
769 const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
770 const TEL_COLOUR* aLineColor = (myPArray->type == TelPointsArrayType) ? &anAspectMarker->Color() : &anAspectLine->Color();
772 // Use highlight colors
773 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
775 anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor;
776 aFrontLightingModel = 0;
779 if (aCtx->IsGlGreaterEqual (2, 0))
781 switch (myPArray->type)
783 case TelPointsArrayType:
785 BindProgramWithMaterial (theWorkspace, anAspectMarker);
788 case TelSegmentsArrayType:
789 case TelPolylinesArrayType:
791 BindProgramWithMaterial (theWorkspace, anAspectLine);
794 default: // polygonal array
796 BindProgramWithMaterial (theWorkspace, anAspectFace);
802 DrawArray (aFrontLightingModel,
803 anAspectFace->InteriorStyle(),
804 anAspectFace->Edge(),
808 &anAspectFace->IntFront(),