1 // File: OpenGl_PrimitiveArray.cxx
2 // Created: 13 July 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_tgl_all.hxx>
7 #include <OpenGl_PrimitiveArray.hxx>
9 #include <OpenGl_AspectFace.hxx>
10 #include <OpenGl_GraphicDriver.hxx>
11 #include <OpenGl_Memory.hxx>
12 #include <OpenGl_ResourceCleaner.hxx>
13 #include <OpenGl_ResourceVBO.hxx>
14 #include <OpenGl_Structure.hxx>
15 #include <OpenGl_TextureBox.hxx>
17 #include <InterfaceGraphic_PrimitiveArray.hxx>
21 VBO_NOT_INITIALIZED = -1,
28 static unsigned long vRand = 1L;
29 #define OGL_Rand() (vRand = vRand * 214013L + 2531011L)
32 // =======================================================================
33 // function : clearMemoryOwn
35 // =======================================================================
36 void OpenGl_PrimitiveArray::clearMemoryOwn() const
38 if (myPArray->bufferVBO[VBOEdges] != 0)
40 Standard::Free ((Standard_Address& )myPArray->edges);
41 myPArray->edges = NULL;
43 if (myPArray->bufferVBO[VBOVertices] != 0)
45 Standard::Free ((Standard_Address& )myPArray->vertices);
46 myPArray->vertices = NULL;
48 if (myPArray->bufferVBO[VBOVcolours] != 0)
50 Standard::Free ((Standard_Address& )myPArray->vcolours);
51 myPArray->vcolours = NULL;
53 if (myPArray->bufferVBO[VBOVnormals] != 0)
55 Standard::Free ((Standard_Address& )myPArray->vnormals);
56 myPArray->vnormals = NULL;
58 if (myPArray->bufferVBO[VBOVtexels] != 0)
60 Standard::Free ((Standard_Address& )myPArray->vtexels);
61 myPArray->vtexels = NULL;
63 if (myPArray->edge_vis != NULL) /// ????
65 Standard::Free ((Standard_Address& )myPArray->edge_vis);
66 myPArray->edge_vis = NULL;
70 // =======================================================================
71 // function : clearMemoryGL
73 // =======================================================================
74 void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlContext) const
76 if (myPArray->bufferVBO[VBOEdges] != 0)
78 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
80 if (myPArray->bufferVBO[VBOVertices] != 0)
82 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
84 if (myPArray->bufferVBO[VBOVcolours] != 0)
86 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
88 if (myPArray->bufferVBO[VBOVnormals] != 0)
90 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
92 if (myPArray->bufferVBO[VBOVtexels] != 0)
94 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
96 theGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
97 theGlContext->arbVBO->glBindBufferARB (GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
100 // =======================================================================
101 // function : checkSizeForGraphicMemory
103 // =======================================================================
104 Standard_Boolean OpenGl_PrimitiveArray::checkSizeForGraphicMemory (const Handle(OpenGl_Context)& theGlContext) const
106 if (glGetError() == GL_OUT_OF_MEMORY)
108 myPArray->flagBufferVBO = VBO_ERROR;
109 clearMemoryGL (theGlContext);
113 myPArray->flagBufferVBO = VBO_OK;
115 return myPArray->flagBufferVBO == VBO_OK;
118 // =======================================================================
119 // function : BuildVBO
121 // =======================================================================
122 Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
125 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
126 if (myPArray->edges != NULL)
128 size_reqd = myPArray->num_edges * sizeof(Tint);
129 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
130 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENTS_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
131 aGlContext->arbVBO->glBufferDataARB (GL_ELEMENTS_ARRAY_BUFFER_ARB, size_reqd, myPArray->edges, GL_STATIC_DRAW_ARB);
132 if (!checkSizeForGraphicMemory (aGlContext))
133 return Standard_False;
136 if (myPArray->vertices != NULL)
138 size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
139 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
140 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
141 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vertices, GL_STATIC_DRAW_ARB);
142 if (!checkSizeForGraphicMemory (aGlContext))
143 return Standard_False;
146 if (myPArray->vcolours != NULL)
148 size_reqd = myPArray->num_vertexs * sizeof(Tint);
149 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
150 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
151 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vcolours, GL_STATIC_DRAW_ARB);
152 if (!checkSizeForGraphicMemory (aGlContext))
153 return Standard_False;
156 if (myPArray->vnormals != NULL)
158 size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
159 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
160 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
161 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vnormals, GL_STATIC_DRAW_ARB);
162 if (!checkSizeForGraphicMemory (aGlContext))
163 return Standard_False;
166 if (myPArray->vtexels)
168 size_reqd = myPArray->num_vertexs * sizeof(TEL_TEXTURE_COORD);
169 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
170 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
171 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vtexels, GL_STATIC_DRAW_ARB);
172 if (!checkSizeForGraphicMemory (aGlContext))
173 return Standard_False;
176 if (myPArray->flagBufferVBO == VBO_OK)
179 // specify context for VBO resource
180 myPArray->contextId = (Standard_Address )theWorkspace->GetGContext();
181 return Standard_True;
184 // =======================================================================
185 // function : DrawArrays
186 // purpose : Auxiliary method to split Feedback/Normal rendering modes
187 // =======================================================================
188 inline void DrawArrays (const Handle(OpenGl_Workspace)& theWorkspace,
189 const CALL_DEF_PARRAY* thePArray,
190 const Standard_Boolean theIsFeedback,
197 glDrawArrays (theMode, theFirst, theCount);
202 for (int anIter = theFirst; anIter < (theFirst + theCount); ++anIter)
204 if (thePArray->vnormals != NULL)
205 glNormal3fv (thePArray->vnormals[anIter].xyz);
206 if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
207 glTexCoord3fv (thePArray->vtexels[anIter].xy);
208 if (thePArray->vertices != NULL)
209 glVertex3fv (thePArray->vertices[anIter].xyz);
210 if (thePArray->vcolours != NULL)
211 glColor4ubv((GLubyte* )thePArray->vcolours[anIter]);
216 // =======================================================================
217 // function : DrawElements
218 // purpose : Auxiliary method to split Feedback/Normal rendering modes
219 // =======================================================================
220 inline void DrawElements (const Handle(OpenGl_Workspace)& theWorkspace,
221 const CALL_DEF_PARRAY* thePArray,
222 const Standard_Boolean theIsFeedback,
229 glDrawElements (theMode, theCount, GL_UNSIGNED_INT, theIndices);
235 for (GLsizei anIter = 0; anIter < theCount; ++anIter)
237 anIndex = theIndices[anIter];
238 if (thePArray->vnormals != NULL)
239 glNormal3fv (thePArray->vnormals[anIndex].xyz);
240 if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
241 glTexCoord3fv (thePArray->vtexels[anIndex].xy);
242 if (thePArray->vertices != NULL)
243 glVertex3fv (thePArray->vertices[anIndex].xyz);
244 if (thePArray->vcolours != NULL)
245 glColor4ubv ((GLubyte* )thePArray->vcolours[anIndex]);
250 // =======================================================================
251 // function : DrawArray
253 // =======================================================================
254 void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
255 const Aspect_InteriorStyle theInteriorStyle,
257 const TEL_COLOUR* theInteriorColour,
258 const TEL_COLOUR* theLineColour,
259 const TEL_COLOUR* theEdgeColour,
260 const OPENGL_SURF_PROP* theFaceProp,
261 const Handle(OpenGl_Workspace)& theWorkspace) const
263 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
268 // Following pointers have been provided for performance improvement
269 tel_colour pfc = myPArray->fcolours;
270 Tint* pvc = myPArray->vcolours;
273 for (i = 0; i < myPArray->num_vertexs; ++i)
275 transp = int(theFaceProp->trans * 255.0f);
276 #if defined (sparc) || defined (__sparc__) || defined (__sparc)
277 pvc[i] = (pvc[i] & 0xffffff00);
280 pvc[i] = (pvc[i] & 0x00ffffff);
281 pvc[i] += transp << 24;
286 switch (myPArray->type)
288 case TelPointsArrayType:
289 case TelPolylinesArrayType:
290 case TelSegmentsArrayType:
291 glColor3fv (theLineColour->rgb);
293 case TelPolygonsArrayType:
294 case TelTrianglesArrayType:
295 case TelQuadranglesArrayType:
296 case TelTriangleStripsArrayType:
297 case TelQuadrangleStripsArrayType:
298 case TelTriangleFansArrayType:
299 glColor3fv (theInteriorColour->rgb);
303 // Temporarily disable environment mapping
304 if (myDrawMode <= GL_LINE_STRIP)
306 glPushAttrib (GL_ENABLE_BIT);
307 glDisable (GL_TEXTURE_1D);
308 glDisable (GL_TEXTURE_2D);
311 if (theWorkspace->DegenerateModel < 2 &&
312 ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
313 (myDrawMode <= GL_LINE_STRIP)))
315 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
321 if (theInteriorStyle == Aspect_IS_HIDDENLINE)
328 // Sometimes the GL_LIGHTING mode is activated here
329 // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
330 // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
331 if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
332 glDisable (GL_LIGHTING);
334 glEnable (GL_LIGHTING);
336 glGetIntegerv (GL_RENDER_MODE, &renderMode);
338 if (myPArray->num_vertexs > 0
339 && myPArray->flagBufferVBO != VBO_OK
340 && renderMode != GL_FEEDBACK)
342 if (myPArray->vertices != NULL)
344 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
345 glEnableClientState (GL_VERTEX_ARRAY);
347 if (myPArray->vnormals != NULL)
349 glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
350 glEnableClientState (GL_NORMAL_ARRAY);
352 if (myPArray->vtexels != NULL)
354 glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
355 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
360 glColorPointer (4, GL_UNSIGNED_BYTE, 0, pvc); // array of colors
361 glEnableClientState (GL_COLOR_ARRAY);
362 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
363 glEnable (GL_COLOR_MATERIAL);
366 else if (myPArray->num_vertexs > 0
367 && myPArray->flagBufferVBO == VBO_OK)
369 // Bindings concrete pointer in accordance with VBO buffer
370 if (myPArray->bufferVBO[VBOVertices] != 0)
372 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
373 glVertexPointer (3, GL_FLOAT, 0, NULL); // array of vertices
374 glEnableClientState (GL_VERTEX_ARRAY);
376 if (myPArray->bufferVBO[VBOVnormals] != 0)
378 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
379 glNormalPointer (GL_FLOAT, 0, NULL); // array of normals
380 glEnableClientState (GL_NORMAL_ARRAY);
382 if (myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
384 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
385 glTexCoordPointer (2, GL_FLOAT, 0, NULL); // array of texture coordinates
386 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
388 if (myPArray->bufferVBO[VBOVcolours] != 0)
390 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
391 glColorPointer (4, GL_UNSIGNED_BYTE, 0, NULL); // array of colors
392 glEnableClientState (GL_COLOR_ARRAY);
393 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
394 glEnable (GL_COLOR_MATERIAL);
398 // OCC22236 NOTE: draw for all situations:
399 // 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
400 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
401 // 3) draw primitive by vertexes if no edges and bounds array is specified
402 if (myPArray->flagBufferVBO == VBO_OK)
404 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges] != 0)
406 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENTS_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]); // for edge indices
407 if (myPArray->num_bounds > 0)
409 // draw primitives by vertex count with the indicies
410 Tint* anOffset = NULL;
411 for (i = 0; i < myPArray->num_bounds; ++i)
413 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, anOffset);
414 anOffset += myPArray->bounds[i];
419 // draw one (or sequential) primitive by the indicies
420 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
423 else if (myPArray->num_bounds > 0)
425 for (i = n = 0; i < myPArray->num_bounds; ++i)
427 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
428 n += myPArray->bounds[i];
433 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
437 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
438 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
442 if (myPArray->num_bounds > 0)
444 if (myPArray->num_edges > 0)
446 for (i = n = 0; i < myPArray->num_bounds; ++i)
448 if (pfc != NULL) glColor3fv (pfc[i].rgb);
449 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
450 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
451 n += myPArray->bounds[i];
456 for (i = n = 0; i < myPArray->num_bounds; ++i)
460 glColor3fv (pfc[i].rgb);
462 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
463 n, myPArray->bounds[i]);
464 n += myPArray->bounds[i];
468 else if (myPArray->num_edges > 0)
470 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
471 myPArray->num_edges, (GLenum* )myPArray->edges);
475 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
476 0, myPArray->num_vertexs);
480 if (myPArray->bufferVBO[VBOVcolours] != 0 || pvc != NULL)
482 glDisable (GL_COLOR_MATERIAL);
483 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
486 if (myPArray->bufferVBO[VBOVertices] != 0 || myPArray->vertices != NULL)
487 glDisableClientState (GL_VERTEX_ARRAY);
488 if (myPArray->bufferVBO[VBOVcolours] != 0 || myPArray->vcolours != NULL)
489 glDisableClientState (GL_COLOR_ARRAY);
490 if (myPArray->bufferVBO[VBOVnormals] != 0 || myPArray->vnormals != NULL)
491 glDisableClientState (GL_NORMAL_ARRAY);
492 if ((myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) || myPArray->vtexels != NULL)
493 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
495 if (theWorkspace->DegenerateModel)
497 if (myDrawMode <= GL_LINE_STRIP)
505 if (theEdgeFlag || theWorkspace->DegenerateModel)
507 switch (theWorkspace->DegenerateModel)
509 default: // XXX_TDM_NODE or TINY
510 // On some NVIDIA graphic cards, using glEdgeFlagPointer() in
511 // combination with VBO ( edge flag data put into a VBO buffer)
512 // leads to a crash in a driver. Therefore, edge flags are simply
513 // igonored when VBOs are enabled, so all the edges are drawn if
514 // edge visibility is turned on. In order to draw edges selectively,
515 // either disable VBO or turn off edge visibilty in the current
516 // primitive array and create a separate primitive array (segments)
517 // and put edges to be drawn into it.
518 DrawEdges (theEdgeFlag ? theEdgeColour : theInteriorColour, theWorkspace);
520 // DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
521 case 2: // XXX_TDM_WIREFRAME
522 if (myPArray->VBOEnabled == 0)
523 DrawDegeneratesAsLines ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace);
525 case 3: // XXX_TDM_MARKER
526 if (myPArray->VBOEnabled == 0)
527 DrawDegeneratesAsPoints ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace->SkipRatio);
529 case 4: // XXX_TDM_BBOX
530 if (myPArray->VBOEnabled == 0)
531 DrawDegeneratesAsBBoxs (theEdgeFlag ? theEdgeColour : theInteriorColour);
536 if (myDrawMode <= GL_LINE_STRIP)
540 // =======================================================================
541 // function : DrawEdges
543 // =======================================================================
544 void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour,
545 const Handle(OpenGl_Workspace)& theWorkspace) const
547 glDisable (GL_LIGHTING);
549 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
550 const OpenGl_AspectLine* anAspectLineOld = NULL;
551 if (myDrawMode > GL_LINE_STRIP)
553 anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
554 theWorkspace->AspectLine (Standard_True);
556 glPushAttrib (GL_POLYGON_BIT);
557 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
563 // OCC22236 NOTE: draw edges for all situations:
564 // 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
565 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
566 // 3) draw primitive's edges by vertexes if no edges and bounds array is specified
567 if (myPArray->flagBufferVBO == VBO_OK)
569 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
570 glEnableClientState (GL_VERTEX_ARRAY);
571 glColor3fv (theEdgeColour->rgb);
572 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges])
574 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENTS_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
576 // draw primitives by vertex count with the indicies
577 if (myPArray->num_bounds > 0)
580 for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
582 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, offset);
583 offset += myPArray->bounds[i];
586 // draw one (or sequential) primitive by the indicies
589 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
592 else if (myPArray->num_bounds > 0)
594 for (i = n = 0; i < myPArray->num_bounds; ++i)
596 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
597 n += myPArray->bounds[i];
602 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
606 glDisableClientState (GL_VERTEX_ARRAY);
607 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
608 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
612 glEnableClientState (GL_VERTEX_ARRAY);
613 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
614 glGetIntegerv (GL_RENDER_MODE, &renderMode);
616 glColor3fv (theEdgeColour->rgb);
617 if (myPArray->num_bounds > 0)
619 if (myPArray->num_edges > 0)
621 for (i = n = 0; i < myPArray->num_bounds; ++i)
623 if (myPArray->edge_vis)
625 glBegin (myDrawMode);
626 for (j = 0; j < myPArray->bounds[i]; ++j)
628 glEdgeFlag (myPArray->edge_vis[n+j]);
629 glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
635 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
636 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
638 n += myPArray->bounds[i];
643 for (i = n = 0 ; i < myPArray->num_bounds; ++i)
645 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
646 n, myPArray->bounds[i]);
647 n += myPArray->bounds[i];
651 else if (myPArray->num_edges > 0)
653 if (myPArray->edge_vis)
655 glBegin (myDrawMode);
656 for (i = 0; i < myPArray->num_edges; ++i)
658 glEdgeFlag (myPArray->edge_vis[i]);
659 glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
665 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
666 myPArray->num_edges, (GLenum* )myPArray->edges);
671 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
672 0, myPArray->num_vertexs);
676 if (myDrawMode > GL_LINE_STRIP)
678 // Restore line context
679 theWorkspace->SetAspectLine (anAspectLineOld);
684 // =======================================================================
685 // function : DrawDegeneratesPointsAsPoints
687 // =======================================================================
688 void OpenGl_PrimitiveArray::DrawDegeneratesPointsAsPoints() const
690 tel_point pv = myPArray->vertices;
691 for (Tint aVertId = 0; aVertId < myPArray->num_vertexs; ++aVertId)
693 glVertex3fv (&pv[aVertId].xyz[0]);
697 // =======================================================================
698 // function : DrawDegeneratesLinesAsPoints
700 // =======================================================================
701 void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsPoints() const
704 tel_point pv = myPArray->vertices;
707 while (j < myPArray->num_vertexs)
709 pt[0] = pv[j].xyz[0];
710 pt[1] = pv[j].xyz[1];
711 pt[2] = pv[j].xyz[2]; ++j;
712 pt[0] += pv[j].xyz[0];
713 pt[1] += pv[j].xyz[1];
714 pt[2] += pv[j].xyz[2]; ++j;
722 // =======================================================================
723 // function : DrawDegeneratesTrianglesAsPoints
725 // =======================================================================
726 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsPoints() const
730 tel_point pv = myPArray->vertices;
732 if (myPArray->num_edges > 0)
734 for (j = 0; j < myPArray->num_edges; j += 3)
736 iv = myPArray->edges[j];
737 pt[0] = pv[iv].xyz[0];
738 pt[1] = pv[iv].xyz[1];
739 pt[2] = pv[iv].xyz[2];
740 for (i = 1; i < 3; ++i)
742 iv = myPArray->edges[j+i];
743 pt[0] += pv[iv].xyz[0];
744 pt[1] += pv[iv].xyz[1];
745 pt[2] += pv[iv].xyz[2];
755 for (j = 0; j < myPArray->num_vertexs; j += 3)
757 pt[0] = pv[j].xyz[0];
758 pt[1] = pv[j].xyz[1];
759 pt[2] = pv[j].xyz[2];
760 for (i = 1; i < 3; ++i)
762 pt[0] += pv[j+i].xyz[0];
763 pt[1] += pv[j+i].xyz[1];
764 pt[2] += pv[j+i].xyz[2];
774 // =======================================================================
775 // function : DrawDegeneratesTrianglesAsPoints
777 // =======================================================================
778 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsPoints() const
782 tel_point pv = myPArray->vertices;
784 if (myPArray->num_bounds > 0)
786 for (k = n = 0; k < myPArray->num_bounds; ++k)
788 for (j = 0; j < myPArray->bounds[k] - 2; ++j)
790 pt[0] = pv[n+j].xyz[0];
791 pt[1] = pv[n+j].xyz[1];
792 pt[2] = pv[n+j].xyz[2];
793 for (i = 1; i < 3; ++i)
795 pt[0] += pv[n+j+i].xyz[0];
796 pt[1] += pv[n+j+i].xyz[1];
797 pt[2] += pv[n+j+i].xyz[2];
804 n += myPArray->bounds[k];
809 for (j = 0; j < myPArray->num_vertexs - 2; ++j)
811 pt[0] = pv[j].xyz[0];
812 pt[1] = pv[j].xyz[1];
813 pt[2] = pv[j].xyz[2];
814 for (i = 1; i < 3; ++i)
816 pt[0] += pv[j+i].xyz[0];
817 pt[1] += pv[j+i].xyz[1];
818 pt[2] += pv[j+i].xyz[2];
828 // =======================================================================
829 // function : DrawDegeneratesPolygonsAsPoints
831 // =======================================================================
832 void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsPoints() const
836 tel_point pv = myPArray->vertices;
838 if (myPArray->num_bounds > 0)
840 if (myPArray->num_edges > 0)
842 for (k = n = 0; k < myPArray->num_bounds; ++k)
844 pt[0] = pt[1] = pt[2] = 0.0;
845 for (j = 0; j < myPArray->bounds[k]; ++j)
847 iv = myPArray->edges[n+j];
848 pt[0] += pv[iv].xyz[0];
849 pt[1] += pv[iv].xyz[1];
850 pt[2] += pv[iv].xyz[2];
852 pt[0] /= myPArray->bounds[k];
853 pt[1] /= myPArray->bounds[k];
854 pt[2] /= myPArray->bounds[k];
856 n += myPArray->bounds[k];
861 for (k = n = 0; k < myPArray->num_bounds; ++k)
863 pt[0] = pt[1] = pt[2] = 0.0;
864 for (j = 0; j < myPArray->bounds[k]; ++j)
866 pt[0] += pv[n+j].xyz[0];
867 pt[1] += pv[n+j].xyz[1];
868 pt[2] += pv[n+j].xyz[2];
870 pt[0] /= myPArray->bounds[k];
871 pt[1] /= myPArray->bounds[k];
872 pt[2] /= myPArray->bounds[k];
874 n += myPArray->bounds[k];
878 else if (myPArray->num_edges > 0)
880 pt[0] = pt[1] = pt[2] = 0.0;
881 for (j = 0; j < myPArray->num_edges; ++j)
883 iv = myPArray->edges[j];
884 pt[0] += pv[iv].xyz[0];
885 pt[1] += pv[iv].xyz[1];
886 pt[2] += pv[iv].xyz[2];
888 pt[0] /= myPArray->num_edges;
889 pt[1] /= myPArray->num_edges;
890 pt[2] /= myPArray->num_edges;
895 pt[0] = pt[1] = pt[2] = 0.0;
896 for (j = 0; j < myPArray->num_vertexs; ++j)
898 pt[0] += pv[j].xyz[0];
899 pt[1] += pv[j].xyz[1];
900 pt[2] += pv[j].xyz[2];
902 pt[0] /= myPArray->num_vertexs;
903 pt[1] /= myPArray->num_vertexs;
904 pt[2] /= myPArray->num_vertexs;
909 // =======================================================================
910 // function : DrawDegeneratesQuadranglesAsPoints
912 // =======================================================================
913 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsPoints() const
917 tel_point pv = myPArray->vertices;
919 if (myPArray->num_edges > 0)
921 for (j = 0; j < myPArray->num_edges; j += 4)
923 pt[0] = pt[1] = pt[2] = 0.0;
924 for (i = 0; i < 4; ++i)
926 iv = myPArray->edges[j+i];
927 pt[0] += pv[iv].xyz[0];
928 pt[1] += pv[iv].xyz[1];
929 pt[2] += pv[iv].xyz[2];
939 for (j = 0; j < myPArray->num_vertexs; j += 4)
941 pt[0] = pt[1] = pt[2] = 0.0;
942 for (i = 0; i < 4; ++i)
944 pt[0] += pv[j+i].xyz[0];
945 pt[1] += pv[j+i].xyz[1];
946 pt[2] += pv[j+i].xyz[2];
956 // =======================================================================
957 // function : DrawDegeneratesAsPoints
959 // =======================================================================
960 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsPoints() const
964 tel_point pv = myPArray->vertices;
966 if (myPArray->num_bounds > 0)
968 for (k = n = 0; k < myPArray->num_bounds; ++k)
970 for (j = 0; j < myPArray->bounds[k] - 2; j += 2)
972 pt[0] = pt[1] = pt[2] = 0.;
973 for (i = 0; i < 4; ++i)
975 pt[0] += pv[n+j+i].xyz[0];
976 pt[1] += pv[n+j+i].xyz[1];
977 pt[2] += pv[n+j+i].xyz[2];
984 n += myPArray->bounds[k];
989 for (j = 0; j < myPArray->num_vertexs - 2; j += 2)
991 pt[0] = pt[1] = pt[2] = 0.;
992 for (i = 0; i < 4; ++i)
994 pt[0] += pv[j+i].xyz[0];
995 pt[1] += pv[j+i].xyz[1];
996 pt[2] += pv[j+i].xyz[2];
1006 // =======================================================================
1007 // function : DrawDegeneratesAsPoints
1009 // =======================================================================
1010 void OpenGl_PrimitiveArray::DrawDegeneratesAsPoints (const TEL_COLOUR* theEdgeColour,
1011 const float theSkipRatio) const
1013 if (theSkipRatio >= 1.0f)
1016 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1017 glDisable (GL_LIGHTING);
1019 glDisable (GL_DEPTH_TEST);
1020 glColor3fv (theEdgeColour->rgb);
1022 glBegin (GL_POINTS);
1026 DrawDegeneratesPointsAsPoints();
1029 DrawDegeneratesLinesAsPoints();
1033 DrawDegeneratesPolygonsAsPoints();
1036 DrawDegeneratesTrianglesAsPoints();
1039 DrawDegeneratesQuadranglesAsPoints();
1041 case GL_TRIANGLE_FAN:
1042 case GL_TRIANGLE_STRIP:
1043 DrawDegeneratesTrianglestripsAsPoints();
1046 DrawDegeneratesQuadranglestripsAsPoints();
1053 glEnable (GL_DEPTH_TEST);
1056 // =======================================================================
1057 // function : DrawDegeneratesLinesAsLines
1059 // =======================================================================
1060 void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsLines (const float theSkipRatio) const
1063 tel_point pv = myPArray->vertices;
1065 Tint n = myPArray->num_vertexs;
1066 Tint j = int((1.0f - theSkipRatio) * n);
1070 myPArray->keys[i] = -myPArray->keys[i];
1073 if (myPArray->num_bounds > 0)
1075 if (myPArray->num_edges > 0)
1077 for (i = n = 0; i < myPArray->num_bounds; ++i)
1080 for (j = 0; j < myPArray->bounds[i]; ++j)
1082 iv = myPArray->edges[n + j];
1083 if (myPArray->keys[iv] < 0)
1085 myPArray->keys[iv] = -myPArray->keys[iv];
1086 glVertex3fv (pv[iv].xyz);
1090 n += myPArray->bounds[i];
1095 for (i = n = 0; i < myPArray->num_bounds; ++i)
1098 for (j = 0; j < myPArray->bounds[i]; ++j)
1100 if (myPArray->keys[n+j] < 0)
1102 myPArray->keys[n+j] = -myPArray->keys[n+j];
1103 glVertex3fv (pv[n+j].xyz);
1107 n += myPArray->bounds[i];
1111 else if (myPArray->num_edges > 0)
1114 for (j = 0; j < myPArray->num_edges; ++j)
1116 iv = myPArray->edges[j];
1117 if (myPArray->keys[iv] < 0)
1119 myPArray->keys[iv] = -myPArray->keys[iv];
1120 glVertex3fv (pv[iv].xyz);
1128 for (j = 0; j < myPArray->num_vertexs; ++j)
1130 if (myPArray->keys[j] < 0)
1132 myPArray->keys[j] = -myPArray->keys[j];
1133 glVertex3fv (pv[j].xyz);
1140 // =======================================================================
1141 // function : DrawDegeneratesTrianglesAsLines
1143 // =======================================================================
1144 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsLines (const float theSkipRatio) const
1147 tel_point pv = myPArray->vertices;
1149 Tint n = myPArray->num_vertexs / 3;
1150 Tint j = int((1.0f - theSkipRatio) * n);
1153 i = OGL_Rand() % n; i *= 3;
1154 myPArray->keys[i] = -myPArray->keys[i];
1157 if (myPArray->num_edges > 0)
1159 for (j = 0; j < myPArray->num_edges; j += 3)
1161 iv = myPArray->edges[j];
1162 if (myPArray->keys[iv] < 0)
1164 myPArray->keys[iv] = -myPArray->keys[iv];
1165 glBegin (GL_LINE_LOOP);
1166 for (i = 0; i < 3; ++i)
1168 iv = myPArray->edges[j+i];
1169 glVertex3fv (pv[iv].xyz);
1177 for (j = 0; j < myPArray->num_vertexs; j += 3)
1179 if (myPArray->keys[j] < 0)
1181 myPArray->keys[j] = -myPArray->keys[j];
1182 glBegin (GL_LINE_LOOP);
1183 for (i = 0; i < 3; ++i)
1185 glVertex3fv (pv[j+i].xyz);
1193 // =======================================================================
1194 // function : DrawDegeneratesTrianglesAsLines
1196 // =======================================================================
1197 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsLines (const float theSkipRatio) const
1199 Tint i, j, k, n, ni;
1200 tel_point pv = myPArray->vertices;
1202 if (myPArray->num_bounds > 0)
1204 for (i = n = 0; i < myPArray->num_bounds; ++i)
1206 ni = myPArray->bounds[i] - 2;
1207 k = int((1.0f - theSkipRatio) * ni);
1210 j = OGL_Rand() % ni; j += 2;
1211 myPArray->keys[n+j] = -myPArray->keys[n+j];
1213 for (j = 2; j < myPArray->bounds[i]; ++j)
1215 if (myPArray->keys[n+j] < 0)
1217 myPArray->keys[n+j] = -myPArray->keys[n+j];
1218 glBegin (GL_LINE_LOOP);
1219 glVertex3fv (pv[n+j-2].xyz);
1220 glVertex3fv (pv[n+j-1].xyz);
1221 glVertex3fv (pv[n+j].xyz);
1225 n += myPArray->bounds[i];
1230 ni = myPArray->num_vertexs - 2;
1231 k = int((1.0f - theSkipRatio) * ni);
1234 j = OGL_Rand() % ni; j += 2;
1235 myPArray->keys[j] = -myPArray->keys[j];
1237 for (j = 2; j < myPArray->num_vertexs; ++j)
1239 if (myPArray->keys[j] < 0)
1241 myPArray->keys[j] = -myPArray->keys[j];
1242 glBegin (GL_LINE_LOOP);
1243 glVertex3fv (pv[j-2].xyz);
1244 glVertex3fv (pv[j-1].xyz);
1245 glVertex3fv (pv[j].xyz);
1252 // =======================================================================
1253 // function : DrawDegeneratesPolygonsAsLines
1255 // =======================================================================
1256 void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsLines (const float theSkipRatio) const
1259 tel_point pv = myPArray->vertices;
1261 Tint n = myPArray->num_vertexs;
1262 Tint j = int((1.0f - theSkipRatio) * n);
1266 myPArray->keys[i] = -myPArray->keys[i];
1269 if (myPArray->num_bounds > 0)
1271 if (myPArray->num_edges > 0)
1273 for (i = n = 0; i < myPArray->num_bounds; ++i)
1275 glBegin (GL_LINE_LOOP);
1276 for (j = 0; j < myPArray->bounds[i]; ++j)
1278 iv = myPArray->edges[n+j];
1279 if (myPArray->keys[iv] < 0)
1281 myPArray->keys[iv] = -myPArray->keys[iv];
1282 glVertex3fv (pv[iv].xyz);
1286 n += myPArray->bounds[i];
1291 for (i = n = 0; i < myPArray->num_bounds; ++i)
1293 glBegin (GL_LINE_LOOP);
1294 for (j = 0; j < myPArray->bounds[i]; ++j)
1296 if (myPArray->keys[n+j] < 0)
1298 myPArray->keys[n+j] = -myPArray->keys[n+j];
1299 glVertex3fv (pv[n+j].xyz);
1303 n += myPArray->bounds[i];
1307 else if (myPArray->num_edges > 0)
1309 glBegin (GL_LINE_LOOP);
1310 for (j = 0; j < myPArray->num_edges; ++j)
1312 iv = myPArray->edges[j];
1313 if (myPArray->keys[iv] < 0)
1315 myPArray->keys[iv] = -myPArray->keys[iv];
1316 glVertex3fv (pv[iv].xyz);
1323 glBegin (GL_LINE_LOOP);
1324 for (j = 0; j < myPArray->num_vertexs; ++j)
1326 if (myPArray->keys[j] < 0)
1328 myPArray->keys[j] = -myPArray->keys[j];
1329 glVertex3fv (pv[j].xyz);
1336 // =======================================================================
1337 // function : DrawDegeneratesQuadranglesAsLines
1339 // =======================================================================
1340 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsLines (const float theSkipRatio) const
1343 tel_point pv = myPArray->vertices;
1345 Tint n = myPArray->num_vertexs / 4;
1346 Tint j = int((1.0f - theSkipRatio) * n);
1349 i = OGL_Rand() % n; i *= 4;
1350 myPArray->keys[i] = -myPArray->keys[i];
1353 if (myPArray->num_edges > 0)
1355 for (j = 0; j < myPArray->num_edges; j += 4)
1357 iv = myPArray->edges[j];
1358 if (myPArray->keys[iv] < 0)
1360 myPArray->keys[iv] = -myPArray->keys[iv];
1361 glBegin (GL_LINE_LOOP);
1362 for (i = 0; i < 4; ++i)
1364 iv = myPArray->edges[j+i];
1365 glVertex3fv (pv[iv].xyz);
1373 for (j = 0; j < myPArray->num_vertexs; j += 4)
1375 if (myPArray->keys[j] < 0)
1377 myPArray->keys[j] = -myPArray->keys[j];
1378 glBegin (GL_LINE_LOOP);
1379 for (i = 0; i < 4; ++i)
1381 glVertex3fv (pv[j+i].xyz);
1389 // =======================================================================
1390 // function : DrawDegeneratesQuadranglesAsLines
1392 // =======================================================================
1393 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsLines (const float theSkipRatio) const
1395 Tint i, j, k, n, ni;
1396 tel_point pv = myPArray->vertices;
1398 if (myPArray->num_bounds > 0)
1400 for (i = n = 0; i < myPArray->num_bounds; ++i)
1402 ni = myPArray->bounds[i] / 2 - 2;
1403 k = int((1.0f - theSkipRatio) * ni);
1406 j = OGL_Rand() % ni; j = j * 2 + 2;
1407 myPArray->keys[n+j] = -myPArray->keys[n+j];
1409 for (j = 3; j < myPArray->bounds[i]; j += 2)
1411 if (myPArray->keys[n+j] < 0)
1413 myPArray->keys[n+j] = -myPArray->keys[n+j];
1414 glBegin (GL_LINE_LOOP);
1415 glVertex3fv (pv[n+j-3].xyz);
1416 glVertex3fv (pv[n+j-2].xyz);
1417 glVertex3fv (pv[n+j-1].xyz);
1418 glVertex3fv (pv[n+j].xyz);
1422 n += myPArray->bounds[i];
1427 ni = myPArray->num_vertexs / 2 - 2;
1428 k = int((1.0f - theSkipRatio) * ni);
1431 j = OGL_Rand() % ni; j = j * 2 + 2;
1432 myPArray->keys[j] = -myPArray->keys[j];
1434 for (j = 3; j < myPArray->num_vertexs; j += 2)
1436 if (myPArray->keys[j] < 0)
1438 myPArray->keys[j] = -myPArray->keys[j];
1439 glBegin (GL_LINE_LOOP);
1440 glVertex3fv (pv[j-3].xyz);
1441 glVertex3fv (pv[j-2].xyz);
1442 glVertex3fv (pv[j-1].xyz);
1443 glVertex3fv (pv[j].xyz);
1450 // =======================================================================
1451 // function : DrawDegeneratesAsLines
1453 // =======================================================================
1454 void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR* theEdgeColour,
1455 const Handle(OpenGl_Workspace)& theWorkspace) const
1457 const float aSkipRatio = theWorkspace->SkipRatio;
1459 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1461 glDisable (GL_LIGHTING);
1464 glDisable (GL_DEPTH_TEST);
1466 glColor3fv (theEdgeColour->rgb);
1468 if (aSkipRatio != 0.0f)
1473 if (aSkipRatio < 1.0f)
1474 DrawDegeneratesPointsAsPoints();
1477 DrawDegeneratesLinesAsLines (aSkipRatio);
1481 DrawDegeneratesPolygonsAsLines (aSkipRatio);
1484 DrawDegeneratesTrianglesAsLines (aSkipRatio);
1487 DrawDegeneratesQuadranglesAsLines (aSkipRatio);
1489 case GL_TRIANGLE_FAN:
1490 case GL_TRIANGLE_STRIP:
1491 DrawDegeneratesTrianglestripsAsLines (aSkipRatio);
1494 DrawDegeneratesQuadranglestripsAsLines (aSkipRatio);
1503 glPushAttrib (GL_POLYGON_BIT);
1504 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
1506 GLboolean color_array_mode = glIsEnabled (GL_COLOR_ARRAY);
1507 GLboolean edge_flag_array_mode = glIsEnabled (GL_EDGE_FLAG_ARRAY);
1508 GLboolean index_array_mode = glIsEnabled (GL_INDEX_ARRAY);
1509 GLboolean normal_array_mode = glIsEnabled (GL_NORMAL_ARRAY);
1510 GLboolean texture_coord_array_mode = glIsEnabled (GL_TEXTURE_COORD_ARRAY);
1511 GLboolean vertex_array_mode = glIsEnabled (GL_VERTEX_ARRAY);
1513 glDisableClientState (GL_COLOR_ARRAY);
1514 glDisableClientState (GL_EDGE_FLAG_ARRAY);
1515 glDisableClientState (GL_INDEX_ARRAY);
1516 glDisableClientState (GL_NORMAL_ARRAY);
1517 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
1519 if (!vertex_array_mode)
1520 glEnableClientState (GL_VERTEX_ARRAY);
1522 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
1525 glGetIntegerv (GL_RENDER_MODE, &renderMode);
1527 if (myPArray->num_bounds > 0)
1529 if (myPArray->num_edges > 0)
1531 for (i = n = 0; i < myPArray->num_bounds; ++i)
1533 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1534 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
1535 n += myPArray->bounds[i];
1540 for (i = n = 0; i < myPArray->num_bounds; ++i)
1542 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1543 n, myPArray->bounds[i]);
1544 n += myPArray->bounds[i];
1548 else if (myPArray->num_edges > 0)
1550 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1551 myPArray->num_edges, (GLenum* )myPArray->edges);
1555 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1556 0, myPArray->num_vertexs);
1559 if (!vertex_array_mode) glDisableClientState (GL_VERTEX_ARRAY);
1561 if (color_array_mode) glEnableClientState (GL_COLOR_ARRAY);
1562 if (edge_flag_array_mode) glEnableClientState (GL_EDGE_FLAG_ARRAY);
1563 if (index_array_mode) glEnableClientState (GL_INDEX_ARRAY);
1564 if (normal_array_mode) glEnableClientState (GL_NORMAL_ARRAY);
1565 if (texture_coord_array_mode) glEnableClientState (GL_TEXTURE_COORD_ARRAY);
1571 glEnable(GL_DEPTH_TEST);
1574 // =======================================================================
1575 // function : DrawDegeneratesAsBBoxs
1577 // =======================================================================
1578 void OpenGl_PrimitiveArray::DrawDegeneratesAsBBoxs (const TEL_COLOUR* theEdgeColour) const
1580 GLfloat minp[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
1581 GLfloat maxp[3] = { FLT_MIN, FLT_MIN, FLT_MIN };
1582 tel_point pv = myPArray->vertices;
1584 glDisable (GL_LIGHTING);
1586 glColor3fv (theEdgeColour->rgb);
1588 for (Tint i = 0; i < myPArray->num_vertexs; ++i)
1590 if (pv[i].xyz[0] < minp[0])
1591 minp[0] = pv[i].xyz[0];
1592 if (pv[i].xyz[1] < minp[1])
1593 minp[1] = pv[i].xyz[1];
1594 if (pv[i].xyz[2] < minp[2])
1595 minp[2] = pv[i].xyz[2];
1597 if (pv[i].xyz[0] > maxp[0])
1598 maxp[0] = pv[i].xyz[0];
1599 if (pv[i].xyz[1] > maxp[1])
1600 maxp[1] = pv[i].xyz[1];
1601 if (pv[i].xyz[2] > maxp[2])
1602 maxp[2] = pv[i].xyz[2];
1605 glBegin (GL_LINE_STRIP);
1608 glVertex3f (minp[0], maxp[1], minp[2]);
1609 glVertex3f (minp[0], maxp[1], maxp[2]);
1610 glVertex3f (minp[0], minp[1], maxp[2]);
1611 glVertex3f (minp[0], minp[1], minp[2]);
1613 glVertex3f (maxp[0], minp[1], minp[2]);
1614 glVertex3f (maxp[0], maxp[1], minp[2]);
1615 glVertex3f (maxp[0], maxp[1], maxp[2]);
1616 glVertex3f (maxp[0], minp[1], maxp[2]);
1617 glVertex3f (maxp[0], minp[1], minp[2]);
1619 glVertex3f (maxp[0], minp[1], maxp[2]);
1620 glVertex3f (minp[0], minp[1], maxp[2]);
1621 glVertex3f (minp[0], maxp[1], maxp[2]);
1623 glVertex3f (maxp[0], maxp[1], minp[2]);
1624 glVertex3f (minp[0], maxp[1], minp[2]);
1629 // =======================================================================
1630 // function : OpenGl_PrimitiveArray
1632 // =======================================================================
1633 OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
1634 : myPArray (thePArray),
1635 myDrawMode (GL_NONE)
1637 switch (myPArray->type)
1639 case TelPointsArrayType:
1640 myDrawMode = GL_POINTS;
1642 case TelPolylinesArrayType:
1643 myDrawMode = GL_LINE_STRIP;
1645 case TelSegmentsArrayType:
1646 myDrawMode = GL_LINES;
1648 case TelPolygonsArrayType:
1649 myDrawMode = GL_POLYGON;
1651 case TelTrianglesArrayType:
1652 myDrawMode = GL_TRIANGLES;
1654 case TelQuadranglesArrayType:
1655 myDrawMode = GL_QUADS;
1657 case TelTriangleStripsArrayType:
1658 myDrawMode = GL_TRIANGLE_STRIP;
1660 case TelQuadrangleStripsArrayType:
1661 myDrawMode = GL_QUAD_STRIP;
1663 case TelTriangleFansArrayType:
1664 myDrawMode = GL_TRIANGLE_FAN;
1669 // =======================================================================
1670 // function : ~OpenGl_PrimitiveArray
1672 // =======================================================================
1673 OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray ()
1675 if (myPArray == NULL)
1678 if (myPArray->VBOEnabled == VBO_OK)
1680 OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
1681 if (myPArray->bufferVBO[VBOEdges] != 0)
1682 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1683 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOEdges]));
1684 if (myPArray->bufferVBO[VBOVertices] != 0)
1685 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1686 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVertices]));
1687 if (myPArray->bufferVBO[VBOVcolours] != 0)
1688 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1689 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVcolours]));
1690 if (myPArray->bufferVBO[VBOVnormals] != 0)
1691 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1692 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVnormals]));
1693 if (myPArray->bufferVBO[VBOVtexels] != 0)
1694 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1695 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVtexels]));
1699 // =======================================================================
1700 // function : Render
1702 // =======================================================================
1703 void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
1705 if (myPArray == NULL || myDrawMode == GL_NONE)
1708 // create VBOs on first render call
1709 if (myPArray->VBOEnabled == -1) // special value for uninitialized state
1711 myPArray->VBOEnabled = OpenGl_GraphicDriver::ToUseVBO() && (theWorkspace->GetGlContext()->arbVBO != NULL);
1712 if (myPArray->VBOEnabled != 0)
1713 BuildVBO (theWorkspace);
1716 switch (myPArray->type)
1718 case TelPointsArrayType:
1719 case TelPolylinesArrayType:
1720 case TelSegmentsArrayType:
1722 glDisable (GL_LIGHTING);
1724 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1725 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
1726 theWorkspace->DegenerateModel)
1728 glDisable (GL_DEPTH_TEST);
1729 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1731 theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
1735 case TelPolygonsArrayType:
1736 case TelTrianglesArrayType:
1737 case TelQuadranglesArrayType:
1738 case TelTriangleStripsArrayType:
1739 case TelTriangleFansArrayType:
1740 case TelQuadrangleStripsArrayType:
1742 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1743 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
1744 theWorkspace->DegenerateModel < 2)
1746 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1748 glEnable (GL_DEPTH_TEST);
1749 theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
1757 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
1758 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
1760 Tint aFrontLightingModel = anAspectFace->Context().IntFront.color_mask;
1761 const TEL_COLOUR* anInteriorColor = &anAspectFace->Context().IntFront.matcol;
1762 const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
1763 const TEL_COLOUR* aLineColor = &anAspectLine->Color();
1765 // Use highlight colors
1766 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
1768 anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor;
1769 aFrontLightingModel = 0;
1772 DrawArray (aFrontLightingModel,
1773 anAspectFace->Context().InteriorStyle,
1774 anAspectFace->Context().Edge,
1778 &anAspectFace->Context().IntFront,
1781 switch (myPArray->type)
1783 case TelPointsArrayType:
1784 case TelPolylinesArrayType:
1785 case TelSegmentsArrayType:
1787 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)