1 // File: OpenGl_PrimitiveArray.cxx
2 // Created: 13 July 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_ArbVBO.hxx>
7 #include <OpenGl_Context.hxx>
9 #include <OpenGl_PrimitiveArray.hxx>
11 #include <OpenGl_AspectFace.hxx>
12 #include <OpenGl_GraphicDriver.hxx>
13 #include <OpenGl_Memory.hxx>
14 #include <OpenGl_ResourceCleaner.hxx>
15 #include <OpenGl_ResourceVBO.hxx>
16 #include <OpenGl_Structure.hxx>
17 #include <OpenGl_TextureBox.hxx>
19 #include <InterfaceGraphic_PrimitiveArray.hxx>
23 VBO_NOT_INITIALIZED = -1,
30 static unsigned long vRand = 1L;
31 #define OGL_Rand() (vRand = vRand * 214013L + 2531011L)
34 // =======================================================================
35 // function : clearMemoryOwn
37 // =======================================================================
38 void OpenGl_PrimitiveArray::clearMemoryOwn() const
40 if (myPArray->bufferVBO[VBOEdges] != 0)
42 Standard::Free ((Standard_Address& )myPArray->edges);
43 myPArray->edges = NULL;
45 if (myPArray->bufferVBO[VBOVertices] != 0)
47 Standard::Free ((Standard_Address& )myPArray->vertices);
48 myPArray->vertices = NULL;
50 if (myPArray->bufferVBO[VBOVcolours] != 0)
52 Standard::Free ((Standard_Address& )myPArray->vcolours);
53 myPArray->vcolours = NULL;
55 if (myPArray->bufferVBO[VBOVnormals] != 0)
57 Standard::Free ((Standard_Address& )myPArray->vnormals);
58 myPArray->vnormals = NULL;
60 if (myPArray->bufferVBO[VBOVtexels] != 0)
62 Standard::Free ((Standard_Address& )myPArray->vtexels);
63 myPArray->vtexels = NULL;
65 if (myPArray->edge_vis != NULL) /// ????
67 Standard::Free ((Standard_Address& )myPArray->edge_vis);
68 myPArray->edge_vis = NULL;
72 // =======================================================================
73 // function : clearMemoryGL
75 // =======================================================================
76 void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlContext) const
78 if (myPArray->bufferVBO[VBOEdges] != 0)
80 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
82 if (myPArray->bufferVBO[VBOVertices] != 0)
84 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
86 if (myPArray->bufferVBO[VBOVcolours] != 0)
88 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
90 if (myPArray->bufferVBO[VBOVnormals] != 0)
92 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
94 if (myPArray->bufferVBO[VBOVtexels] != 0)
96 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
98 theGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
99 theGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
102 // =======================================================================
103 // function : checkSizeForGraphicMemory
105 // =======================================================================
106 Standard_Boolean OpenGl_PrimitiveArray::checkSizeForGraphicMemory (const Handle(OpenGl_Context)& theGlContext) const
108 if (glGetError() == GL_OUT_OF_MEMORY)
110 myPArray->flagBufferVBO = VBO_ERROR;
111 clearMemoryGL (theGlContext);
115 myPArray->flagBufferVBO = VBO_OK;
117 return myPArray->flagBufferVBO == VBO_OK;
120 // =======================================================================
121 // function : BuildVBO
123 // =======================================================================
124 Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
127 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
128 if (myPArray->edges != NULL)
130 size_reqd = myPArray->num_edges * sizeof(Tint);
131 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
132 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
133 aGlContext->arbVBO->glBufferDataARB (GL_ELEMENT_ARRAY_BUFFER_ARB, size_reqd, myPArray->edges, GL_STATIC_DRAW_ARB);
134 if (!checkSizeForGraphicMemory (aGlContext))
135 return Standard_False;
138 if (myPArray->vertices != NULL)
140 size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
141 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
142 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
143 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vertices, GL_STATIC_DRAW_ARB);
144 if (!checkSizeForGraphicMemory (aGlContext))
145 return Standard_False;
148 if (myPArray->vcolours != NULL)
150 size_reqd = myPArray->num_vertexs * sizeof(Tint);
151 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
152 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
153 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vcolours, GL_STATIC_DRAW_ARB);
154 if (!checkSizeForGraphicMemory (aGlContext))
155 return Standard_False;
158 if (myPArray->vnormals != NULL)
160 size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
161 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
162 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
163 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vnormals, GL_STATIC_DRAW_ARB);
164 if (!checkSizeForGraphicMemory (aGlContext))
165 return Standard_False;
168 if (myPArray->vtexels)
170 size_reqd = myPArray->num_vertexs * sizeof(TEL_TEXTURE_COORD);
171 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
172 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
173 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vtexels, GL_STATIC_DRAW_ARB);
174 if (!checkSizeForGraphicMemory (aGlContext))
175 return Standard_False;
178 if (myPArray->flagBufferVBO == VBO_OK)
181 // specify context for VBO resource
182 myPArray->contextId = (Standard_Address )theWorkspace->GetGContext();
183 return Standard_True;
186 // =======================================================================
187 // function : DrawArrays
188 // purpose : Auxiliary method to split Feedback/Normal rendering modes
189 // =======================================================================
190 inline void DrawArrays (const Handle(OpenGl_Workspace)& theWorkspace,
191 const CALL_DEF_PARRAY* thePArray,
192 const Standard_Boolean theIsFeedback,
199 glDrawArrays (theMode, theFirst, theCount);
204 for (int anIter = theFirst; anIter < (theFirst + theCount); ++anIter)
206 if (thePArray->vnormals != NULL)
207 glNormal3fv (thePArray->vnormals[anIter].xyz);
208 if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
209 glTexCoord3fv (thePArray->vtexels[anIter].xy);
210 if (thePArray->vertices != NULL)
211 glVertex3fv (thePArray->vertices[anIter].xyz);
212 if (thePArray->vcolours != NULL)
213 glColor4ubv((GLubyte* )thePArray->vcolours[anIter]);
218 // =======================================================================
219 // function : DrawElements
220 // purpose : Auxiliary method to split Feedback/Normal rendering modes
221 // =======================================================================
222 inline void DrawElements (const Handle(OpenGl_Workspace)& theWorkspace,
223 const CALL_DEF_PARRAY* thePArray,
224 const Standard_Boolean theIsFeedback,
231 glDrawElements (theMode, theCount, GL_UNSIGNED_INT, theIndices);
237 for (GLsizei anIter = 0; anIter < theCount; ++anIter)
239 anIndex = theIndices[anIter];
240 if (thePArray->vnormals != NULL)
241 glNormal3fv (thePArray->vnormals[anIndex].xyz);
242 if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
243 glTexCoord3fv (thePArray->vtexels[anIndex].xy);
244 if (thePArray->vertices != NULL)
245 glVertex3fv (thePArray->vertices[anIndex].xyz);
246 if (thePArray->vcolours != NULL)
247 glColor4ubv ((GLubyte* )thePArray->vcolours[anIndex]);
252 // =======================================================================
253 // function : DrawArray
255 // =======================================================================
256 void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
257 const Aspect_InteriorStyle theInteriorStyle,
259 const TEL_COLOUR* theInteriorColour,
260 const TEL_COLOUR* theLineColour,
261 const TEL_COLOUR* theEdgeColour,
262 const OPENGL_SURF_PROP* theFaceProp,
263 const Handle(OpenGl_Workspace)& theWorkspace) const
265 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
270 // Following pointers have been provided for performance improvement
271 tel_colour pfc = myPArray->fcolours;
272 Tint* pvc = myPArray->vcolours;
275 for (i = 0; i < myPArray->num_vertexs; ++i)
277 transp = int(theFaceProp->trans * 255.0f);
278 #if defined (sparc) || defined (__sparc__) || defined (__sparc)
279 pvc[i] = (pvc[i] & 0xffffff00);
282 pvc[i] = (pvc[i] & 0x00ffffff);
283 pvc[i] += transp << 24;
288 switch (myPArray->type)
290 case TelPointsArrayType:
291 case TelPolylinesArrayType:
292 case TelSegmentsArrayType:
293 glColor3fv (theLineColour->rgb);
295 case TelPolygonsArrayType:
296 case TelTrianglesArrayType:
297 case TelQuadranglesArrayType:
298 case TelTriangleStripsArrayType:
299 case TelQuadrangleStripsArrayType:
300 case TelTriangleFansArrayType:
301 glColor3fv (theInteriorColour->rgb);
305 // Temporarily disable environment mapping
306 if (myDrawMode <= GL_LINE_STRIP)
308 glPushAttrib (GL_ENABLE_BIT);
309 glDisable (GL_TEXTURE_1D);
310 glDisable (GL_TEXTURE_2D);
313 if (theWorkspace->DegenerateModel < 2 &&
314 ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
315 (myDrawMode <= GL_LINE_STRIP)))
317 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
323 if (theInteriorStyle == Aspect_IS_HIDDENLINE)
330 // Sometimes the GL_LIGHTING mode is activated here
331 // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
332 // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
333 if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
334 glDisable (GL_LIGHTING);
336 glEnable (GL_LIGHTING);
338 glGetIntegerv (GL_RENDER_MODE, &renderMode);
340 if (myPArray->num_vertexs > 0
341 && myPArray->flagBufferVBO != VBO_OK
342 && renderMode != GL_FEEDBACK)
344 if (myPArray->vertices != NULL)
346 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
347 glEnableClientState (GL_VERTEX_ARRAY);
349 if (myPArray->vnormals != NULL)
351 glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
352 glEnableClientState (GL_NORMAL_ARRAY);
354 if (myPArray->vtexels != NULL)
356 glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
357 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
362 glColorPointer (4, GL_UNSIGNED_BYTE, 0, pvc); // array of colors
363 glEnableClientState (GL_COLOR_ARRAY);
364 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
365 glEnable (GL_COLOR_MATERIAL);
368 else if (myPArray->num_vertexs > 0
369 && myPArray->flagBufferVBO == VBO_OK)
371 // Bindings concrete pointer in accordance with VBO buffer
372 if (myPArray->bufferVBO[VBOVertices] != 0)
374 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
375 glVertexPointer (3, GL_FLOAT, 0, NULL); // array of vertices
376 glEnableClientState (GL_VERTEX_ARRAY);
378 if (myPArray->bufferVBO[VBOVnormals] != 0)
380 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
381 glNormalPointer (GL_FLOAT, 0, NULL); // array of normals
382 glEnableClientState (GL_NORMAL_ARRAY);
384 if (myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
386 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
387 glTexCoordPointer (2, GL_FLOAT, 0, NULL); // array of texture coordinates
388 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
390 if (myPArray->bufferVBO[VBOVcolours] != 0)
392 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
393 glColorPointer (4, GL_UNSIGNED_BYTE, 0, NULL); // array of colors
394 glEnableClientState (GL_COLOR_ARRAY);
395 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
396 glEnable (GL_COLOR_MATERIAL);
400 // OCC22236 NOTE: draw for all situations:
401 // 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
402 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
403 // 3) draw primitive by vertexes if no edges and bounds array is specified
404 if (myPArray->flagBufferVBO == VBO_OK)
406 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges] != 0)
408 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]); // for edge indices
409 if (myPArray->num_bounds > 0)
411 // draw primitives by vertex count with the indicies
412 Tint* anOffset = NULL;
413 for (i = 0; i < myPArray->num_bounds; ++i)
415 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, anOffset);
416 anOffset += myPArray->bounds[i];
421 // draw one (or sequential) primitive by the indicies
422 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
425 else if (myPArray->num_bounds > 0)
427 for (i = n = 0; i < myPArray->num_bounds; ++i)
429 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
430 n += myPArray->bounds[i];
435 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
439 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
440 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
444 if (myPArray->num_bounds > 0)
446 if (myPArray->num_edges > 0)
448 for (i = n = 0; i < myPArray->num_bounds; ++i)
450 if (pfc != NULL) glColor3fv (pfc[i].rgb);
451 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
452 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
453 n += myPArray->bounds[i];
458 for (i = n = 0; i < myPArray->num_bounds; ++i)
462 glColor3fv (pfc[i].rgb);
464 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
465 n, myPArray->bounds[i]);
466 n += myPArray->bounds[i];
470 else if (myPArray->num_edges > 0)
472 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
473 myPArray->num_edges, (GLenum* )myPArray->edges);
477 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
478 0, myPArray->num_vertexs);
482 if (myPArray->bufferVBO[VBOVcolours] != 0 || pvc != NULL)
484 glDisable (GL_COLOR_MATERIAL);
485 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
488 if (myPArray->bufferVBO[VBOVertices] != 0 || myPArray->vertices != NULL)
489 glDisableClientState (GL_VERTEX_ARRAY);
490 if (myPArray->bufferVBO[VBOVcolours] != 0 || myPArray->vcolours != NULL)
491 glDisableClientState (GL_COLOR_ARRAY);
492 if (myPArray->bufferVBO[VBOVnormals] != 0 || myPArray->vnormals != NULL)
493 glDisableClientState (GL_NORMAL_ARRAY);
494 if ((myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) || myPArray->vtexels != NULL)
495 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
497 if (theWorkspace->DegenerateModel)
499 if (myDrawMode <= GL_LINE_STRIP)
507 if (theEdgeFlag || theWorkspace->DegenerateModel)
509 switch (theWorkspace->DegenerateModel)
511 default: // XXX_TDM_NODE or TINY
512 // On some NVIDIA graphic cards, using glEdgeFlagPointer() in
513 // combination with VBO ( edge flag data put into a VBO buffer)
514 // leads to a crash in a driver. Therefore, edge flags are simply
515 // igonored when VBOs are enabled, so all the edges are drawn if
516 // edge visibility is turned on. In order to draw edges selectively,
517 // either disable VBO or turn off edge visibilty in the current
518 // primitive array and create a separate primitive array (segments)
519 // and put edges to be drawn into it.
520 DrawEdges (theEdgeFlag ? theEdgeColour : theInteriorColour, theWorkspace);
522 // DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
523 case 2: // XXX_TDM_WIREFRAME
524 if (myPArray->VBOEnabled == 0)
525 DrawDegeneratesAsLines ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace);
527 case 3: // XXX_TDM_MARKER
528 if (myPArray->VBOEnabled == 0)
529 DrawDegeneratesAsPoints ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace->SkipRatio);
531 case 4: // XXX_TDM_BBOX
532 if (myPArray->VBOEnabled == 0)
533 DrawDegeneratesAsBBoxs (theEdgeFlag ? theEdgeColour : theInteriorColour);
538 if (myDrawMode <= GL_LINE_STRIP)
542 // =======================================================================
543 // function : DrawEdges
545 // =======================================================================
546 void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour,
547 const Handle(OpenGl_Workspace)& theWorkspace) const
549 glDisable (GL_LIGHTING);
551 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
552 const OpenGl_AspectLine* anAspectLineOld = NULL;
553 if (myDrawMode > GL_LINE_STRIP)
555 anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
556 theWorkspace->AspectLine (Standard_True);
558 glPushAttrib (GL_POLYGON_BIT);
559 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
565 // OCC22236 NOTE: draw edges for all situations:
566 // 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
567 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
568 // 3) draw primitive's edges by vertexes if no edges and bounds array is specified
569 if (myPArray->flagBufferVBO == VBO_OK)
571 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
572 glEnableClientState (GL_VERTEX_ARRAY);
573 glColor3fv (theEdgeColour->rgb);
574 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges])
576 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
578 // draw primitives by vertex count with the indicies
579 if (myPArray->num_bounds > 0)
582 for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
584 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, offset);
585 offset += myPArray->bounds[i];
588 // draw one (or sequential) primitive by the indicies
591 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
594 else if (myPArray->num_bounds > 0)
596 for (i = n = 0; i < myPArray->num_bounds; ++i)
598 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
599 n += myPArray->bounds[i];
604 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
608 glDisableClientState (GL_VERTEX_ARRAY);
609 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
610 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
614 glEnableClientState (GL_VERTEX_ARRAY);
615 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
616 glGetIntegerv (GL_RENDER_MODE, &renderMode);
618 glColor3fv (theEdgeColour->rgb);
619 if (myPArray->num_bounds > 0)
621 if (myPArray->num_edges > 0)
623 for (i = n = 0; i < myPArray->num_bounds; ++i)
625 if (myPArray->edge_vis)
627 glBegin (myDrawMode);
628 for (j = 0; j < myPArray->bounds[i]; ++j)
630 glEdgeFlag (myPArray->edge_vis[n+j]);
631 glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
637 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
638 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
640 n += myPArray->bounds[i];
645 for (i = n = 0 ; i < myPArray->num_bounds; ++i)
647 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
648 n, myPArray->bounds[i]);
649 n += myPArray->bounds[i];
653 else if (myPArray->num_edges > 0)
655 if (myPArray->edge_vis)
657 glBegin (myDrawMode);
658 for (i = 0; i < myPArray->num_edges; ++i)
660 glEdgeFlag (myPArray->edge_vis[i]);
661 glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
667 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
668 myPArray->num_edges, (GLenum* )myPArray->edges);
673 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
674 0, myPArray->num_vertexs);
678 if (myDrawMode > GL_LINE_STRIP)
680 // Restore line context
681 theWorkspace->SetAspectLine (anAspectLineOld);
686 // =======================================================================
687 // function : DrawDegeneratesPointsAsPoints
689 // =======================================================================
690 void OpenGl_PrimitiveArray::DrawDegeneratesPointsAsPoints() const
692 tel_point pv = myPArray->vertices;
693 for (Tint aVertId = 0; aVertId < myPArray->num_vertexs; ++aVertId)
695 glVertex3fv (&pv[aVertId].xyz[0]);
699 // =======================================================================
700 // function : DrawDegeneratesLinesAsPoints
702 // =======================================================================
703 void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsPoints() const
706 tel_point pv = myPArray->vertices;
709 while (j < myPArray->num_vertexs)
711 pt[0] = pv[j].xyz[0];
712 pt[1] = pv[j].xyz[1];
713 pt[2] = pv[j].xyz[2]; ++j;
714 pt[0] += pv[j].xyz[0];
715 pt[1] += pv[j].xyz[1];
716 pt[2] += pv[j].xyz[2]; ++j;
724 // =======================================================================
725 // function : DrawDegeneratesTrianglesAsPoints
727 // =======================================================================
728 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsPoints() const
732 tel_point pv = myPArray->vertices;
734 if (myPArray->num_edges > 0)
736 for (j = 0; j < myPArray->num_edges; j += 3)
738 iv = myPArray->edges[j];
739 pt[0] = pv[iv].xyz[0];
740 pt[1] = pv[iv].xyz[1];
741 pt[2] = pv[iv].xyz[2];
742 for (i = 1; i < 3; ++i)
744 iv = myPArray->edges[j+i];
745 pt[0] += pv[iv].xyz[0];
746 pt[1] += pv[iv].xyz[1];
747 pt[2] += pv[iv].xyz[2];
757 for (j = 0; j < myPArray->num_vertexs; j += 3)
759 pt[0] = pv[j].xyz[0];
760 pt[1] = pv[j].xyz[1];
761 pt[2] = pv[j].xyz[2];
762 for (i = 1; i < 3; ++i)
764 pt[0] += pv[j+i].xyz[0];
765 pt[1] += pv[j+i].xyz[1];
766 pt[2] += pv[j+i].xyz[2];
776 // =======================================================================
777 // function : DrawDegeneratesTrianglesAsPoints
779 // =======================================================================
780 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsPoints() const
784 tel_point pv = myPArray->vertices;
786 if (myPArray->num_bounds > 0)
788 for (k = n = 0; k < myPArray->num_bounds; ++k)
790 for (j = 0; j < myPArray->bounds[k] - 2; ++j)
792 pt[0] = pv[n+j].xyz[0];
793 pt[1] = pv[n+j].xyz[1];
794 pt[2] = pv[n+j].xyz[2];
795 for (i = 1; i < 3; ++i)
797 pt[0] += pv[n+j+i].xyz[0];
798 pt[1] += pv[n+j+i].xyz[1];
799 pt[2] += pv[n+j+i].xyz[2];
806 n += myPArray->bounds[k];
811 for (j = 0; j < myPArray->num_vertexs - 2; ++j)
813 pt[0] = pv[j].xyz[0];
814 pt[1] = pv[j].xyz[1];
815 pt[2] = pv[j].xyz[2];
816 for (i = 1; i < 3; ++i)
818 pt[0] += pv[j+i].xyz[0];
819 pt[1] += pv[j+i].xyz[1];
820 pt[2] += pv[j+i].xyz[2];
830 // =======================================================================
831 // function : DrawDegeneratesPolygonsAsPoints
833 // =======================================================================
834 void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsPoints() const
838 tel_point pv = myPArray->vertices;
840 if (myPArray->num_bounds > 0)
842 if (myPArray->num_edges > 0)
844 for (k = n = 0; k < myPArray->num_bounds; ++k)
846 pt[0] = pt[1] = pt[2] = 0.0;
847 for (j = 0; j < myPArray->bounds[k]; ++j)
849 iv = myPArray->edges[n+j];
850 pt[0] += pv[iv].xyz[0];
851 pt[1] += pv[iv].xyz[1];
852 pt[2] += pv[iv].xyz[2];
854 pt[0] /= myPArray->bounds[k];
855 pt[1] /= myPArray->bounds[k];
856 pt[2] /= myPArray->bounds[k];
858 n += myPArray->bounds[k];
863 for (k = n = 0; k < myPArray->num_bounds; ++k)
865 pt[0] = pt[1] = pt[2] = 0.0;
866 for (j = 0; j < myPArray->bounds[k]; ++j)
868 pt[0] += pv[n+j].xyz[0];
869 pt[1] += pv[n+j].xyz[1];
870 pt[2] += pv[n+j].xyz[2];
872 pt[0] /= myPArray->bounds[k];
873 pt[1] /= myPArray->bounds[k];
874 pt[2] /= myPArray->bounds[k];
876 n += myPArray->bounds[k];
880 else if (myPArray->num_edges > 0)
882 pt[0] = pt[1] = pt[2] = 0.0;
883 for (j = 0; j < myPArray->num_edges; ++j)
885 iv = myPArray->edges[j];
886 pt[0] += pv[iv].xyz[0];
887 pt[1] += pv[iv].xyz[1];
888 pt[2] += pv[iv].xyz[2];
890 pt[0] /= myPArray->num_edges;
891 pt[1] /= myPArray->num_edges;
892 pt[2] /= myPArray->num_edges;
897 pt[0] = pt[1] = pt[2] = 0.0;
898 for (j = 0; j < myPArray->num_vertexs; ++j)
900 pt[0] += pv[j].xyz[0];
901 pt[1] += pv[j].xyz[1];
902 pt[2] += pv[j].xyz[2];
904 pt[0] /= myPArray->num_vertexs;
905 pt[1] /= myPArray->num_vertexs;
906 pt[2] /= myPArray->num_vertexs;
911 // =======================================================================
912 // function : DrawDegeneratesQuadranglesAsPoints
914 // =======================================================================
915 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsPoints() const
919 tel_point pv = myPArray->vertices;
921 if (myPArray->num_edges > 0)
923 for (j = 0; j < myPArray->num_edges; j += 4)
925 pt[0] = pt[1] = pt[2] = 0.0;
926 for (i = 0; i < 4; ++i)
928 iv = myPArray->edges[j+i];
929 pt[0] += pv[iv].xyz[0];
930 pt[1] += pv[iv].xyz[1];
931 pt[2] += pv[iv].xyz[2];
941 for (j = 0; j < myPArray->num_vertexs; j += 4)
943 pt[0] = pt[1] = pt[2] = 0.0;
944 for (i = 0; i < 4; ++i)
946 pt[0] += pv[j+i].xyz[0];
947 pt[1] += pv[j+i].xyz[1];
948 pt[2] += pv[j+i].xyz[2];
958 // =======================================================================
959 // function : DrawDegeneratesAsPoints
961 // =======================================================================
962 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsPoints() const
966 tel_point pv = myPArray->vertices;
968 if (myPArray->num_bounds > 0)
970 for (k = n = 0; k < myPArray->num_bounds; ++k)
972 for (j = 0; j < myPArray->bounds[k] - 2; j += 2)
974 pt[0] = pt[1] = pt[2] = 0.;
975 for (i = 0; i < 4; ++i)
977 pt[0] += pv[n+j+i].xyz[0];
978 pt[1] += pv[n+j+i].xyz[1];
979 pt[2] += pv[n+j+i].xyz[2];
986 n += myPArray->bounds[k];
991 for (j = 0; j < myPArray->num_vertexs - 2; j += 2)
993 pt[0] = pt[1] = pt[2] = 0.;
994 for (i = 0; i < 4; ++i)
996 pt[0] += pv[j+i].xyz[0];
997 pt[1] += pv[j+i].xyz[1];
998 pt[2] += pv[j+i].xyz[2];
1008 // =======================================================================
1009 // function : DrawDegeneratesAsPoints
1011 // =======================================================================
1012 void OpenGl_PrimitiveArray::DrawDegeneratesAsPoints (const TEL_COLOUR* theEdgeColour,
1013 const float theSkipRatio) const
1015 if (theSkipRatio >= 1.0f)
1018 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1019 glDisable (GL_LIGHTING);
1021 glDisable (GL_DEPTH_TEST);
1022 glColor3fv (theEdgeColour->rgb);
1024 glBegin (GL_POINTS);
1028 DrawDegeneratesPointsAsPoints();
1031 DrawDegeneratesLinesAsPoints();
1035 DrawDegeneratesPolygonsAsPoints();
1038 DrawDegeneratesTrianglesAsPoints();
1041 DrawDegeneratesQuadranglesAsPoints();
1043 case GL_TRIANGLE_FAN:
1044 case GL_TRIANGLE_STRIP:
1045 DrawDegeneratesTrianglestripsAsPoints();
1048 DrawDegeneratesQuadranglestripsAsPoints();
1055 glEnable (GL_DEPTH_TEST);
1058 // =======================================================================
1059 // function : DrawDegeneratesLinesAsLines
1061 // =======================================================================
1062 void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsLines (const float theSkipRatio) const
1065 tel_point pv = myPArray->vertices;
1067 Tint n = myPArray->num_vertexs;
1068 Tint j = int((1.0f - theSkipRatio) * n);
1072 myPArray->keys[i] = -myPArray->keys[i];
1075 if (myPArray->num_bounds > 0)
1077 if (myPArray->num_edges > 0)
1079 for (i = n = 0; i < myPArray->num_bounds; ++i)
1082 for (j = 0; j < myPArray->bounds[i]; ++j)
1084 iv = myPArray->edges[n + j];
1085 if (myPArray->keys[iv] < 0)
1087 myPArray->keys[iv] = -myPArray->keys[iv];
1088 glVertex3fv (pv[iv].xyz);
1092 n += myPArray->bounds[i];
1097 for (i = n = 0; i < myPArray->num_bounds; ++i)
1100 for (j = 0; j < myPArray->bounds[i]; ++j)
1102 if (myPArray->keys[n+j] < 0)
1104 myPArray->keys[n+j] = -myPArray->keys[n+j];
1105 glVertex3fv (pv[n+j].xyz);
1109 n += myPArray->bounds[i];
1113 else if (myPArray->num_edges > 0)
1116 for (j = 0; j < myPArray->num_edges; ++j)
1118 iv = myPArray->edges[j];
1119 if (myPArray->keys[iv] < 0)
1121 myPArray->keys[iv] = -myPArray->keys[iv];
1122 glVertex3fv (pv[iv].xyz);
1130 for (j = 0; j < myPArray->num_vertexs; ++j)
1132 if (myPArray->keys[j] < 0)
1134 myPArray->keys[j] = -myPArray->keys[j];
1135 glVertex3fv (pv[j].xyz);
1142 // =======================================================================
1143 // function : DrawDegeneratesTrianglesAsLines
1145 // =======================================================================
1146 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsLines (const float theSkipRatio) const
1149 tel_point pv = myPArray->vertices;
1151 Tint n = myPArray->num_vertexs / 3;
1152 Tint j = int((1.0f - theSkipRatio) * n);
1155 i = OGL_Rand() % n; i *= 3;
1156 myPArray->keys[i] = -myPArray->keys[i];
1159 if (myPArray->num_edges > 0)
1161 for (j = 0; j < myPArray->num_edges; j += 3)
1163 iv = myPArray->edges[j];
1164 if (myPArray->keys[iv] < 0)
1166 myPArray->keys[iv] = -myPArray->keys[iv];
1167 glBegin (GL_LINE_LOOP);
1168 for (i = 0; i < 3; ++i)
1170 iv = myPArray->edges[j+i];
1171 glVertex3fv (pv[iv].xyz);
1179 for (j = 0; j < myPArray->num_vertexs; j += 3)
1181 if (myPArray->keys[j] < 0)
1183 myPArray->keys[j] = -myPArray->keys[j];
1184 glBegin (GL_LINE_LOOP);
1185 for (i = 0; i < 3; ++i)
1187 glVertex3fv (pv[j+i].xyz);
1195 // =======================================================================
1196 // function : DrawDegeneratesTrianglesAsLines
1198 // =======================================================================
1199 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsLines (const float theSkipRatio) const
1201 Tint i, j, k, n, ni;
1202 tel_point pv = myPArray->vertices;
1204 if (myPArray->num_bounds > 0)
1206 for (i = n = 0; i < myPArray->num_bounds; ++i)
1208 ni = myPArray->bounds[i] - 2;
1209 k = int((1.0f - theSkipRatio) * ni);
1212 j = OGL_Rand() % ni; j += 2;
1213 myPArray->keys[n+j] = -myPArray->keys[n+j];
1215 for (j = 2; j < myPArray->bounds[i]; ++j)
1217 if (myPArray->keys[n+j] < 0)
1219 myPArray->keys[n+j] = -myPArray->keys[n+j];
1220 glBegin (GL_LINE_LOOP);
1221 glVertex3fv (pv[n+j-2].xyz);
1222 glVertex3fv (pv[n+j-1].xyz);
1223 glVertex3fv (pv[n+j].xyz);
1227 n += myPArray->bounds[i];
1232 ni = myPArray->num_vertexs - 2;
1233 k = int((1.0f - theSkipRatio) * ni);
1236 j = OGL_Rand() % ni; j += 2;
1237 myPArray->keys[j] = -myPArray->keys[j];
1239 for (j = 2; j < myPArray->num_vertexs; ++j)
1241 if (myPArray->keys[j] < 0)
1243 myPArray->keys[j] = -myPArray->keys[j];
1244 glBegin (GL_LINE_LOOP);
1245 glVertex3fv (pv[j-2].xyz);
1246 glVertex3fv (pv[j-1].xyz);
1247 glVertex3fv (pv[j].xyz);
1254 // =======================================================================
1255 // function : DrawDegeneratesPolygonsAsLines
1257 // =======================================================================
1258 void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsLines (const float theSkipRatio) const
1261 tel_point pv = myPArray->vertices;
1263 Tint n = myPArray->num_vertexs;
1264 Tint j = int((1.0f - theSkipRatio) * n);
1268 myPArray->keys[i] = -myPArray->keys[i];
1271 if (myPArray->num_bounds > 0)
1273 if (myPArray->num_edges > 0)
1275 for (i = n = 0; i < myPArray->num_bounds; ++i)
1277 glBegin (GL_LINE_LOOP);
1278 for (j = 0; j < myPArray->bounds[i]; ++j)
1280 iv = myPArray->edges[n+j];
1281 if (myPArray->keys[iv] < 0)
1283 myPArray->keys[iv] = -myPArray->keys[iv];
1284 glVertex3fv (pv[iv].xyz);
1288 n += myPArray->bounds[i];
1293 for (i = n = 0; i < myPArray->num_bounds; ++i)
1295 glBegin (GL_LINE_LOOP);
1296 for (j = 0; j < myPArray->bounds[i]; ++j)
1298 if (myPArray->keys[n+j] < 0)
1300 myPArray->keys[n+j] = -myPArray->keys[n+j];
1301 glVertex3fv (pv[n+j].xyz);
1305 n += myPArray->bounds[i];
1309 else if (myPArray->num_edges > 0)
1311 glBegin (GL_LINE_LOOP);
1312 for (j = 0; j < myPArray->num_edges; ++j)
1314 iv = myPArray->edges[j];
1315 if (myPArray->keys[iv] < 0)
1317 myPArray->keys[iv] = -myPArray->keys[iv];
1318 glVertex3fv (pv[iv].xyz);
1325 glBegin (GL_LINE_LOOP);
1326 for (j = 0; j < myPArray->num_vertexs; ++j)
1328 if (myPArray->keys[j] < 0)
1330 myPArray->keys[j] = -myPArray->keys[j];
1331 glVertex3fv (pv[j].xyz);
1338 // =======================================================================
1339 // function : DrawDegeneratesQuadranglesAsLines
1341 // =======================================================================
1342 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsLines (const float theSkipRatio) const
1345 tel_point pv = myPArray->vertices;
1347 Tint n = myPArray->num_vertexs / 4;
1348 Tint j = int((1.0f - theSkipRatio) * n);
1351 i = OGL_Rand() % n; i *= 4;
1352 myPArray->keys[i] = -myPArray->keys[i];
1355 if (myPArray->num_edges > 0)
1357 for (j = 0; j < myPArray->num_edges; j += 4)
1359 iv = myPArray->edges[j];
1360 if (myPArray->keys[iv] < 0)
1362 myPArray->keys[iv] = -myPArray->keys[iv];
1363 glBegin (GL_LINE_LOOP);
1364 for (i = 0; i < 4; ++i)
1366 iv = myPArray->edges[j+i];
1367 glVertex3fv (pv[iv].xyz);
1375 for (j = 0; j < myPArray->num_vertexs; j += 4)
1377 if (myPArray->keys[j] < 0)
1379 myPArray->keys[j] = -myPArray->keys[j];
1380 glBegin (GL_LINE_LOOP);
1381 for (i = 0; i < 4; ++i)
1383 glVertex3fv (pv[j+i].xyz);
1391 // =======================================================================
1392 // function : DrawDegeneratesQuadranglesAsLines
1394 // =======================================================================
1395 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsLines (const float theSkipRatio) const
1397 Tint i, j, k, n, ni;
1398 tel_point pv = myPArray->vertices;
1400 if (myPArray->num_bounds > 0)
1402 for (i = n = 0; i < myPArray->num_bounds; ++i)
1404 ni = myPArray->bounds[i] / 2 - 2;
1405 k = int((1.0f - theSkipRatio) * ni);
1408 j = OGL_Rand() % ni; j = j * 2 + 2;
1409 myPArray->keys[n+j] = -myPArray->keys[n+j];
1411 for (j = 3; j < myPArray->bounds[i]; j += 2)
1413 if (myPArray->keys[n+j] < 0)
1415 myPArray->keys[n+j] = -myPArray->keys[n+j];
1416 glBegin (GL_LINE_LOOP);
1417 glVertex3fv (pv[n+j-3].xyz);
1418 glVertex3fv (pv[n+j-2].xyz);
1419 glVertex3fv (pv[n+j-1].xyz);
1420 glVertex3fv (pv[n+j].xyz);
1424 n += myPArray->bounds[i];
1429 ni = myPArray->num_vertexs / 2 - 2;
1430 k = int((1.0f - theSkipRatio) * ni);
1433 j = OGL_Rand() % ni; j = j * 2 + 2;
1434 myPArray->keys[j] = -myPArray->keys[j];
1436 for (j = 3; j < myPArray->num_vertexs; j += 2)
1438 if (myPArray->keys[j] < 0)
1440 myPArray->keys[j] = -myPArray->keys[j];
1441 glBegin (GL_LINE_LOOP);
1442 glVertex3fv (pv[j-3].xyz);
1443 glVertex3fv (pv[j-2].xyz);
1444 glVertex3fv (pv[j-1].xyz);
1445 glVertex3fv (pv[j].xyz);
1452 // =======================================================================
1453 // function : DrawDegeneratesAsLines
1455 // =======================================================================
1456 void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR* theEdgeColour,
1457 const Handle(OpenGl_Workspace)& theWorkspace) const
1459 const float aSkipRatio = theWorkspace->SkipRatio;
1461 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1463 glDisable (GL_LIGHTING);
1466 glDisable (GL_DEPTH_TEST);
1468 glColor3fv (theEdgeColour->rgb);
1470 if (aSkipRatio != 0.0f)
1475 if (aSkipRatio < 1.0f)
1476 DrawDegeneratesPointsAsPoints();
1479 DrawDegeneratesLinesAsLines (aSkipRatio);
1483 DrawDegeneratesPolygonsAsLines (aSkipRatio);
1486 DrawDegeneratesTrianglesAsLines (aSkipRatio);
1489 DrawDegeneratesQuadranglesAsLines (aSkipRatio);
1491 case GL_TRIANGLE_FAN:
1492 case GL_TRIANGLE_STRIP:
1493 DrawDegeneratesTrianglestripsAsLines (aSkipRatio);
1496 DrawDegeneratesQuadranglestripsAsLines (aSkipRatio);
1505 glPushAttrib (GL_POLYGON_BIT);
1506 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
1508 GLboolean color_array_mode = glIsEnabled (GL_COLOR_ARRAY);
1509 GLboolean edge_flag_array_mode = glIsEnabled (GL_EDGE_FLAG_ARRAY);
1510 GLboolean index_array_mode = glIsEnabled (GL_INDEX_ARRAY);
1511 GLboolean normal_array_mode = glIsEnabled (GL_NORMAL_ARRAY);
1512 GLboolean texture_coord_array_mode = glIsEnabled (GL_TEXTURE_COORD_ARRAY);
1513 GLboolean vertex_array_mode = glIsEnabled (GL_VERTEX_ARRAY);
1515 glDisableClientState (GL_COLOR_ARRAY);
1516 glDisableClientState (GL_EDGE_FLAG_ARRAY);
1517 glDisableClientState (GL_INDEX_ARRAY);
1518 glDisableClientState (GL_NORMAL_ARRAY);
1519 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
1521 if (!vertex_array_mode)
1522 glEnableClientState (GL_VERTEX_ARRAY);
1524 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
1527 glGetIntegerv (GL_RENDER_MODE, &renderMode);
1529 if (myPArray->num_bounds > 0)
1531 if (myPArray->num_edges > 0)
1533 for (i = n = 0; i < myPArray->num_bounds; ++i)
1535 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1536 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
1537 n += myPArray->bounds[i];
1542 for (i = n = 0; i < myPArray->num_bounds; ++i)
1544 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1545 n, myPArray->bounds[i]);
1546 n += myPArray->bounds[i];
1550 else if (myPArray->num_edges > 0)
1552 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1553 myPArray->num_edges, (GLenum* )myPArray->edges);
1557 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1558 0, myPArray->num_vertexs);
1561 if (!vertex_array_mode) glDisableClientState (GL_VERTEX_ARRAY);
1563 if (color_array_mode) glEnableClientState (GL_COLOR_ARRAY);
1564 if (edge_flag_array_mode) glEnableClientState (GL_EDGE_FLAG_ARRAY);
1565 if (index_array_mode) glEnableClientState (GL_INDEX_ARRAY);
1566 if (normal_array_mode) glEnableClientState (GL_NORMAL_ARRAY);
1567 if (texture_coord_array_mode) glEnableClientState (GL_TEXTURE_COORD_ARRAY);
1573 glEnable(GL_DEPTH_TEST);
1576 // =======================================================================
1577 // function : DrawDegeneratesAsBBoxs
1579 // =======================================================================
1580 void OpenGl_PrimitiveArray::DrawDegeneratesAsBBoxs (const TEL_COLOUR* theEdgeColour) const
1582 GLfloat minp[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
1583 GLfloat maxp[3] = { FLT_MIN, FLT_MIN, FLT_MIN };
1584 tel_point pv = myPArray->vertices;
1586 glDisable (GL_LIGHTING);
1588 glColor3fv (theEdgeColour->rgb);
1590 for (Tint i = 0; i < myPArray->num_vertexs; ++i)
1592 if (pv[i].xyz[0] < minp[0])
1593 minp[0] = pv[i].xyz[0];
1594 if (pv[i].xyz[1] < minp[1])
1595 minp[1] = pv[i].xyz[1];
1596 if (pv[i].xyz[2] < minp[2])
1597 minp[2] = pv[i].xyz[2];
1599 if (pv[i].xyz[0] > maxp[0])
1600 maxp[0] = pv[i].xyz[0];
1601 if (pv[i].xyz[1] > maxp[1])
1602 maxp[1] = pv[i].xyz[1];
1603 if (pv[i].xyz[2] > maxp[2])
1604 maxp[2] = pv[i].xyz[2];
1607 glBegin (GL_LINE_STRIP);
1610 glVertex3f (minp[0], maxp[1], minp[2]);
1611 glVertex3f (minp[0], maxp[1], maxp[2]);
1612 glVertex3f (minp[0], minp[1], maxp[2]);
1613 glVertex3f (minp[0], minp[1], minp[2]);
1615 glVertex3f (maxp[0], minp[1], minp[2]);
1616 glVertex3f (maxp[0], maxp[1], minp[2]);
1617 glVertex3f (maxp[0], maxp[1], maxp[2]);
1618 glVertex3f (maxp[0], minp[1], maxp[2]);
1619 glVertex3f (maxp[0], minp[1], minp[2]);
1621 glVertex3f (maxp[0], minp[1], maxp[2]);
1622 glVertex3f (minp[0], minp[1], maxp[2]);
1623 glVertex3f (minp[0], maxp[1], maxp[2]);
1625 glVertex3f (maxp[0], maxp[1], minp[2]);
1626 glVertex3f (minp[0], maxp[1], minp[2]);
1631 // =======================================================================
1632 // function : OpenGl_PrimitiveArray
1634 // =======================================================================
1635 OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
1636 : myPArray (thePArray),
1637 myDrawMode (GL_NONE)
1639 switch (myPArray->type)
1641 case TelPointsArrayType:
1642 myDrawMode = GL_POINTS;
1644 case TelPolylinesArrayType:
1645 myDrawMode = GL_LINE_STRIP;
1647 case TelSegmentsArrayType:
1648 myDrawMode = GL_LINES;
1650 case TelPolygonsArrayType:
1651 myDrawMode = GL_POLYGON;
1653 case TelTrianglesArrayType:
1654 myDrawMode = GL_TRIANGLES;
1656 case TelQuadranglesArrayType:
1657 myDrawMode = GL_QUADS;
1659 case TelTriangleStripsArrayType:
1660 myDrawMode = GL_TRIANGLE_STRIP;
1662 case TelQuadrangleStripsArrayType:
1663 myDrawMode = GL_QUAD_STRIP;
1665 case TelTriangleFansArrayType:
1666 myDrawMode = GL_TRIANGLE_FAN;
1671 // =======================================================================
1672 // function : ~OpenGl_PrimitiveArray
1674 // =======================================================================
1675 OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray ()
1677 if (myPArray == NULL)
1680 if (myPArray->VBOEnabled == VBO_OK)
1682 OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
1683 if (myPArray->bufferVBO[VBOEdges] != 0)
1684 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1685 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOEdges]));
1686 if (myPArray->bufferVBO[VBOVertices] != 0)
1687 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1688 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVertices]));
1689 if (myPArray->bufferVBO[VBOVcolours] != 0)
1690 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1691 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVcolours]));
1692 if (myPArray->bufferVBO[VBOVnormals] != 0)
1693 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1694 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVnormals]));
1695 if (myPArray->bufferVBO[VBOVtexels] != 0)
1696 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1697 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVtexels]));
1701 // =======================================================================
1702 // function : Render
1704 // =======================================================================
1705 void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
1707 if (myPArray == NULL || myDrawMode == GL_NONE)
1710 // create VBOs on first render call
1711 if (myPArray->VBOEnabled == -1) // special value for uninitialized state
1713 myPArray->VBOEnabled = OpenGl_GraphicDriver::ToUseVBO() && (theWorkspace->GetGlContext()->arbVBO != NULL);
1714 if (myPArray->VBOEnabled != 0)
1715 BuildVBO (theWorkspace);
1718 switch (myPArray->type)
1720 case TelPointsArrayType:
1721 case TelPolylinesArrayType:
1722 case TelSegmentsArrayType:
1724 glDisable (GL_LIGHTING);
1726 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1727 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
1728 theWorkspace->DegenerateModel)
1730 glDisable (GL_DEPTH_TEST);
1731 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1733 theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
1737 case TelPolygonsArrayType:
1738 case TelTrianglesArrayType:
1739 case TelQuadranglesArrayType:
1740 case TelTriangleStripsArrayType:
1741 case TelTriangleFansArrayType:
1742 case TelQuadrangleStripsArrayType:
1744 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1745 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
1746 theWorkspace->DegenerateModel < 2)
1748 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1750 glEnable (GL_DEPTH_TEST);
1751 theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
1759 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
1760 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
1762 Tint aFrontLightingModel = anAspectFace->Context().IntFront.color_mask;
1763 const TEL_COLOUR* anInteriorColor = &anAspectFace->Context().IntFront.matcol;
1764 const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
1765 const TEL_COLOUR* aLineColor = &anAspectLine->Color();
1767 // Use highlight colors
1768 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
1770 anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor;
1771 aFrontLightingModel = 0;
1774 DrawArray (aFrontLightingModel,
1775 anAspectFace->Context().InteriorStyle,
1776 anAspectFace->Context().Edge,
1780 &anAspectFace->Context().IntFront,
1783 switch (myPArray->type)
1785 case TelPointsArrayType:
1786 case TelPolylinesArrayType:
1787 case TelSegmentsArrayType:
1789 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)