1 // Created on: 2011-07-13
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #include <OpenGl_ArbVBO.hxx>
22 #include <OpenGl_Context.hxx>
24 #include <OpenGl_PrimitiveArray.hxx>
26 #include <OpenGl_AspectFace.hxx>
27 #include <OpenGl_GraphicDriver.hxx>
28 #include <OpenGl_ResourceCleaner.hxx>
29 #include <OpenGl_ResourceVBO.hxx>
30 #include <OpenGl_Structure.hxx>
31 #include <OpenGl_TextureBox.hxx>
33 #include <InterfaceGraphic_PrimitiveArray.hxx>
37 VBO_NOT_INITIALIZED = -1,
44 static unsigned long vRand = 1L;
45 #define OGL_Rand() (vRand = vRand * 214013L + 2531011L)
48 // =======================================================================
49 // function : clearMemoryOwn
51 // =======================================================================
52 void OpenGl_PrimitiveArray::clearMemoryOwn() const
54 if (myPArray->bufferVBO[VBOEdges] != 0)
56 Standard::Free ((Standard_Address& )myPArray->edges);
57 myPArray->edges = NULL;
59 if (myPArray->bufferVBO[VBOVertices] != 0)
61 Standard::Free ((Standard_Address& )myPArray->vertices);
62 myPArray->vertices = NULL;
64 if (myPArray->bufferVBO[VBOVcolours] != 0)
66 Standard::Free ((Standard_Address& )myPArray->vcolours);
67 myPArray->vcolours = NULL;
69 if (myPArray->bufferVBO[VBOVnormals] != 0)
71 Standard::Free ((Standard_Address& )myPArray->vnormals);
72 myPArray->vnormals = NULL;
74 if (myPArray->bufferVBO[VBOVtexels] != 0)
76 Standard::Free ((Standard_Address& )myPArray->vtexels);
77 myPArray->vtexels = NULL;
79 if (myPArray->edge_vis != NULL) /// ????
81 Standard::Free ((Standard_Address& )myPArray->edge_vis);
82 myPArray->edge_vis = NULL;
86 // =======================================================================
87 // function : clearMemoryGL
89 // =======================================================================
90 void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlContext) const
92 if (myPArray->bufferVBO[VBOEdges] != 0)
94 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
96 if (myPArray->bufferVBO[VBOVertices] != 0)
98 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
100 if (myPArray->bufferVBO[VBOVcolours] != 0)
102 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
104 if (myPArray->bufferVBO[VBOVnormals] != 0)
106 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
108 if (myPArray->bufferVBO[VBOVtexels] != 0)
110 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
112 theGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
113 theGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
116 // =======================================================================
117 // function : checkSizeForGraphicMemory
119 // =======================================================================
120 Standard_Boolean OpenGl_PrimitiveArray::checkSizeForGraphicMemory (const Handle(OpenGl_Context)& theGlContext) const
122 if (glGetError() == GL_OUT_OF_MEMORY)
124 myPArray->flagBufferVBO = VBO_ERROR;
125 clearMemoryGL (theGlContext);
129 myPArray->flagBufferVBO = VBO_OK;
131 return myPArray->flagBufferVBO == VBO_OK;
134 // =======================================================================
135 // function : BuildVBO
137 // =======================================================================
138 Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
141 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
142 if (myPArray->edges != NULL)
144 size_reqd = myPArray->num_edges * sizeof(Tint);
145 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
146 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
147 aGlContext->arbVBO->glBufferDataARB (GL_ELEMENT_ARRAY_BUFFER_ARB, size_reqd, myPArray->edges, GL_STATIC_DRAW_ARB);
148 if (!checkSizeForGraphicMemory (aGlContext))
149 return Standard_False;
152 if (myPArray->vertices != NULL)
154 size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
155 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
156 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
157 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vertices, GL_STATIC_DRAW_ARB);
158 if (!checkSizeForGraphicMemory (aGlContext))
159 return Standard_False;
162 if (myPArray->vcolours != NULL)
164 size_reqd = myPArray->num_vertexs * sizeof(Tint);
165 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
166 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
167 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vcolours, GL_STATIC_DRAW_ARB);
168 if (!checkSizeForGraphicMemory (aGlContext))
169 return Standard_False;
172 if (myPArray->vnormals != NULL)
174 size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
175 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
176 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
177 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vnormals, GL_STATIC_DRAW_ARB);
178 if (!checkSizeForGraphicMemory (aGlContext))
179 return Standard_False;
182 if (myPArray->vtexels)
184 size_reqd = myPArray->num_vertexs * sizeof(TEL_TEXTURE_COORD);
185 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
186 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
187 aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vtexels, GL_STATIC_DRAW_ARB);
188 if (!checkSizeForGraphicMemory (aGlContext))
189 return Standard_False;
192 if (myPArray->flagBufferVBO == VBO_OK)
195 // specify context for VBO resource
196 myPArray->contextId = (Standard_Address )theWorkspace->GetGContext();
197 return Standard_True;
200 // =======================================================================
201 // function : DrawArrays
202 // purpose : Auxiliary method to split Feedback/Normal rendering modes
203 // =======================================================================
204 inline void DrawArrays (const Handle(OpenGl_Workspace)& theWorkspace,
205 const CALL_DEF_PARRAY* thePArray,
206 const Standard_Boolean theIsFeedback,
213 glDrawArrays (theMode, theFirst, theCount);
218 for (int anIter = theFirst; anIter < (theFirst + theCount); ++anIter)
220 if (thePArray->vnormals != NULL)
221 glNormal3fv (thePArray->vnormals[anIter].xyz);
222 if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
223 glTexCoord3fv (thePArray->vtexels[anIter].xy);
224 if (thePArray->vertices != NULL)
225 glVertex3fv (thePArray->vertices[anIter].xyz);
226 if (thePArray->vcolours != NULL)
227 glColor4ubv((GLubyte* )thePArray->vcolours[anIter]);
232 // =======================================================================
233 // function : DrawElements
234 // purpose : Auxiliary method to split Feedback/Normal rendering modes
235 // =======================================================================
236 inline void DrawElements (const Handle(OpenGl_Workspace)& theWorkspace,
237 const CALL_DEF_PARRAY* thePArray,
238 const Standard_Boolean theIsFeedback,
245 glDrawElements (theMode, theCount, GL_UNSIGNED_INT, theIndices);
251 for (GLsizei anIter = 0; anIter < theCount; ++anIter)
253 anIndex = theIndices[anIter];
254 if (thePArray->vnormals != NULL)
255 glNormal3fv (thePArray->vnormals[anIndex].xyz);
256 if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
257 glTexCoord3fv (thePArray->vtexels[anIndex].xy);
258 if (thePArray->vertices != NULL)
259 glVertex3fv (thePArray->vertices[anIndex].xyz);
260 if (thePArray->vcolours != NULL)
261 glColor4ubv ((GLubyte* )thePArray->vcolours[anIndex]);
266 // =======================================================================
267 // function : DrawArray
269 // =======================================================================
270 void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
271 const Aspect_InteriorStyle theInteriorStyle,
273 const TEL_COLOUR* theInteriorColour,
274 const TEL_COLOUR* theLineColour,
275 const TEL_COLOUR* theEdgeColour,
276 const OPENGL_SURF_PROP* theFaceProp,
277 const Handle(OpenGl_Workspace)& theWorkspace) const
279 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
284 // Following pointers have been provided for performance improvement
285 tel_colour pfc = myPArray->fcolours;
286 Tint* pvc = myPArray->vcolours;
289 for (i = 0; i < myPArray->num_vertexs; ++i)
291 transp = int(theFaceProp->trans * 255.0f);
292 #if defined (sparc) || defined (__sparc__) || defined (__sparc)
293 pvc[i] = (pvc[i] & 0xffffff00);
296 pvc[i] = (pvc[i] & 0x00ffffff);
297 pvc[i] += transp << 24;
302 switch (myPArray->type)
304 case TelPointsArrayType:
305 case TelPolylinesArrayType:
306 case TelSegmentsArrayType:
307 glColor3fv (theLineColour->rgb);
309 case TelPolygonsArrayType:
310 case TelTrianglesArrayType:
311 case TelQuadranglesArrayType:
312 case TelTriangleStripsArrayType:
313 case TelQuadrangleStripsArrayType:
314 case TelTriangleFansArrayType:
315 glColor3fv (theInteriorColour->rgb);
319 // Temporarily disable environment mapping
320 if (myDrawMode <= GL_LINE_STRIP)
322 glPushAttrib (GL_ENABLE_BIT);
323 glDisable (GL_TEXTURE_1D);
324 glDisable (GL_TEXTURE_2D);
327 if (theWorkspace->DegenerateModel < 2 &&
328 ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
329 (myDrawMode <= GL_LINE_STRIP)))
331 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
337 if (theInteriorStyle == Aspect_IS_HIDDENLINE)
344 // Sometimes the GL_LIGHTING mode is activated here
345 // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
346 // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
347 if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
348 glDisable (GL_LIGHTING);
350 glEnable (GL_LIGHTING);
352 glGetIntegerv (GL_RENDER_MODE, &renderMode);
354 if (myPArray->num_vertexs > 0
355 && myPArray->flagBufferVBO != VBO_OK
356 && renderMode != GL_FEEDBACK)
358 if (myPArray->vertices != NULL)
360 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
361 glEnableClientState (GL_VERTEX_ARRAY);
363 if (myPArray->vnormals != NULL)
365 glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
366 glEnableClientState (GL_NORMAL_ARRAY);
368 if (myPArray->vtexels != NULL)
370 glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
371 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
376 glColorPointer (4, GL_UNSIGNED_BYTE, 0, pvc); // array of colors
377 glEnableClientState (GL_COLOR_ARRAY);
378 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
379 glEnable (GL_COLOR_MATERIAL);
382 else if (myPArray->num_vertexs > 0
383 && myPArray->flagBufferVBO == VBO_OK)
385 // Bindings concrete pointer in accordance with VBO buffer
386 if (myPArray->bufferVBO[VBOVertices] != 0)
388 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
389 glVertexPointer (3, GL_FLOAT, 0, NULL); // array of vertices
390 glEnableClientState (GL_VERTEX_ARRAY);
392 if (myPArray->bufferVBO[VBOVnormals] != 0)
394 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
395 glNormalPointer (GL_FLOAT, 0, NULL); // array of normals
396 glEnableClientState (GL_NORMAL_ARRAY);
398 if (myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
400 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
401 glTexCoordPointer (2, GL_FLOAT, 0, NULL); // array of texture coordinates
402 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
404 if (myPArray->bufferVBO[VBOVcolours] != 0)
406 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
407 glColorPointer (4, GL_UNSIGNED_BYTE, 0, NULL); // array of colors
408 glEnableClientState (GL_COLOR_ARRAY);
409 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
410 glEnable (GL_COLOR_MATERIAL);
414 // OCC22236 NOTE: draw for all situations:
415 // 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
416 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
417 // 3) draw primitive by vertexes if no edges and bounds array is specified
418 if (myPArray->flagBufferVBO == VBO_OK)
420 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges] != 0)
422 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]); // for edge indices
423 if (myPArray->num_bounds > 0)
425 // draw primitives by vertex count with the indicies
426 Tint* anOffset = NULL;
427 for (i = 0; i < myPArray->num_bounds; ++i)
429 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, anOffset);
430 anOffset += myPArray->bounds[i];
435 // draw one (or sequential) primitive by the indicies
436 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
439 else if (myPArray->num_bounds > 0)
441 for (i = n = 0; i < myPArray->num_bounds; ++i)
443 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
444 n += myPArray->bounds[i];
449 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
453 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
454 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
458 if (myPArray->num_bounds > 0)
460 if (myPArray->num_edges > 0)
462 for (i = n = 0; i < myPArray->num_bounds; ++i)
464 if (pfc != NULL) glColor3fv (pfc[i].rgb);
465 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
466 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
467 n += myPArray->bounds[i];
472 for (i = n = 0; i < myPArray->num_bounds; ++i)
476 glColor3fv (pfc[i].rgb);
478 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
479 n, myPArray->bounds[i]);
480 n += myPArray->bounds[i];
484 else if (myPArray->num_edges > 0)
486 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
487 myPArray->num_edges, (GLenum* )myPArray->edges);
491 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
492 0, myPArray->num_vertexs);
496 if (myPArray->bufferVBO[VBOVcolours] != 0 || pvc != NULL)
498 glDisable (GL_COLOR_MATERIAL);
499 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
502 if (myPArray->bufferVBO[VBOVertices] != 0 || myPArray->vertices != NULL)
503 glDisableClientState (GL_VERTEX_ARRAY);
504 if (myPArray->bufferVBO[VBOVcolours] != 0 || myPArray->vcolours != NULL)
505 glDisableClientState (GL_COLOR_ARRAY);
506 if (myPArray->bufferVBO[VBOVnormals] != 0 || myPArray->vnormals != NULL)
507 glDisableClientState (GL_NORMAL_ARRAY);
508 if ((myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) || myPArray->vtexels != NULL)
509 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
511 if (theWorkspace->DegenerateModel)
513 if (myDrawMode <= GL_LINE_STRIP)
521 if (theEdgeFlag || theWorkspace->DegenerateModel)
523 switch (theWorkspace->DegenerateModel)
525 default: // XXX_TDM_NODE or TINY
526 // On some NVIDIA graphic cards, using glEdgeFlagPointer() in
527 // combination with VBO ( edge flag data put into a VBO buffer)
528 // leads to a crash in a driver. Therefore, edge flags are simply
529 // igonored when VBOs are enabled, so all the edges are drawn if
530 // edge visibility is turned on. In order to draw edges selectively,
531 // either disable VBO or turn off edge visibilty in the current
532 // primitive array and create a separate primitive array (segments)
533 // and put edges to be drawn into it.
534 DrawEdges (theEdgeFlag ? theEdgeColour : theInteriorColour, theWorkspace);
536 // DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
537 case 2: // XXX_TDM_WIREFRAME
538 if (myPArray->VBOEnabled == 0)
539 DrawDegeneratesAsLines ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace);
541 case 3: // XXX_TDM_MARKER
542 if (myPArray->VBOEnabled == 0)
543 DrawDegeneratesAsPoints ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace->SkipRatio);
545 case 4: // XXX_TDM_BBOX
546 if (myPArray->VBOEnabled == 0)
547 DrawDegeneratesAsBBoxs (theEdgeFlag ? theEdgeColour : theInteriorColour);
552 if (myDrawMode <= GL_LINE_STRIP)
556 // =======================================================================
557 // function : DrawEdges
559 // =======================================================================
560 void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour,
561 const Handle(OpenGl_Workspace)& theWorkspace) const
563 glDisable (GL_LIGHTING);
565 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
566 const OpenGl_AspectLine* anAspectLineOld = NULL;
567 if (myDrawMode > GL_LINE_STRIP)
569 anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
570 theWorkspace->AspectLine (Standard_True);
572 glPushAttrib (GL_POLYGON_BIT);
573 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
579 // OCC22236 NOTE: draw edges for all situations:
580 // 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
581 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
582 // 3) draw primitive's edges by vertexes if no edges and bounds array is specified
583 if (myPArray->flagBufferVBO == VBO_OK)
585 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
586 glEnableClientState (GL_VERTEX_ARRAY);
587 glColor3fv (theEdgeColour->rgb);
588 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges])
590 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
592 // draw primitives by vertex count with the indicies
593 if (myPArray->num_bounds > 0)
596 for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
598 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, offset);
599 offset += myPArray->bounds[i];
602 // draw one (or sequential) primitive by the indicies
605 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
608 else if (myPArray->num_bounds > 0)
610 for (i = n = 0; i < myPArray->num_bounds; ++i)
612 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
613 n += myPArray->bounds[i];
618 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
622 glDisableClientState (GL_VERTEX_ARRAY);
623 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
624 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
628 glEnableClientState (GL_VERTEX_ARRAY);
629 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
630 glGetIntegerv (GL_RENDER_MODE, &renderMode);
632 glColor3fv (theEdgeColour->rgb);
633 if (myPArray->num_bounds > 0)
635 if (myPArray->num_edges > 0)
637 for (i = n = 0; i < myPArray->num_bounds; ++i)
639 if (myPArray->edge_vis)
641 glBegin (myDrawMode);
642 for (j = 0; j < myPArray->bounds[i]; ++j)
644 glEdgeFlag (myPArray->edge_vis[n+j]);
645 glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
651 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
652 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
654 n += myPArray->bounds[i];
659 for (i = n = 0 ; i < myPArray->num_bounds; ++i)
661 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
662 n, myPArray->bounds[i]);
663 n += myPArray->bounds[i];
667 else if (myPArray->num_edges > 0)
669 if (myPArray->edge_vis)
671 glBegin (myDrawMode);
672 for (i = 0; i < myPArray->num_edges; ++i)
674 glEdgeFlag (myPArray->edge_vis[i]);
675 glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
681 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
682 myPArray->num_edges, (GLenum* )myPArray->edges);
687 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
688 0, myPArray->num_vertexs);
692 if (myDrawMode > GL_LINE_STRIP)
694 // Restore line context
695 theWorkspace->SetAspectLine (anAspectLineOld);
700 // =======================================================================
701 // function : DrawDegeneratesPointsAsPoints
703 // =======================================================================
704 void OpenGl_PrimitiveArray::DrawDegeneratesPointsAsPoints() const
706 tel_point pv = myPArray->vertices;
707 for (Tint aVertId = 0; aVertId < myPArray->num_vertexs; ++aVertId)
709 glVertex3fv (&pv[aVertId].xyz[0]);
713 // =======================================================================
714 // function : DrawDegeneratesLinesAsPoints
716 // =======================================================================
717 void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsPoints() const
720 tel_point pv = myPArray->vertices;
723 while (j < myPArray->num_vertexs)
725 pt[0] = pv[j].xyz[0];
726 pt[1] = pv[j].xyz[1];
727 pt[2] = pv[j].xyz[2]; ++j;
728 pt[0] += pv[j].xyz[0];
729 pt[1] += pv[j].xyz[1];
730 pt[2] += pv[j].xyz[2]; ++j;
738 // =======================================================================
739 // function : DrawDegeneratesTrianglesAsPoints
741 // =======================================================================
742 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsPoints() const
746 tel_point pv = myPArray->vertices;
748 if (myPArray->num_edges > 0)
750 for (j = 0; j < myPArray->num_edges; j += 3)
752 iv = myPArray->edges[j];
753 pt[0] = pv[iv].xyz[0];
754 pt[1] = pv[iv].xyz[1];
755 pt[2] = pv[iv].xyz[2];
756 for (i = 1; i < 3; ++i)
758 iv = myPArray->edges[j+i];
759 pt[0] += pv[iv].xyz[0];
760 pt[1] += pv[iv].xyz[1];
761 pt[2] += pv[iv].xyz[2];
771 for (j = 0; j < myPArray->num_vertexs; j += 3)
773 pt[0] = pv[j].xyz[0];
774 pt[1] = pv[j].xyz[1];
775 pt[2] = pv[j].xyz[2];
776 for (i = 1; i < 3; ++i)
778 pt[0] += pv[j+i].xyz[0];
779 pt[1] += pv[j+i].xyz[1];
780 pt[2] += pv[j+i].xyz[2];
790 // =======================================================================
791 // function : DrawDegeneratesTrianglesAsPoints
793 // =======================================================================
794 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsPoints() const
798 tel_point pv = myPArray->vertices;
800 if (myPArray->num_bounds > 0)
802 for (k = n = 0; k < myPArray->num_bounds; ++k)
804 for (j = 0; j < myPArray->bounds[k] - 2; ++j)
806 pt[0] = pv[n+j].xyz[0];
807 pt[1] = pv[n+j].xyz[1];
808 pt[2] = pv[n+j].xyz[2];
809 for (i = 1; i < 3; ++i)
811 pt[0] += pv[n+j+i].xyz[0];
812 pt[1] += pv[n+j+i].xyz[1];
813 pt[2] += pv[n+j+i].xyz[2];
820 n += myPArray->bounds[k];
825 for (j = 0; j < myPArray->num_vertexs - 2; ++j)
827 pt[0] = pv[j].xyz[0];
828 pt[1] = pv[j].xyz[1];
829 pt[2] = pv[j].xyz[2];
830 for (i = 1; i < 3; ++i)
832 pt[0] += pv[j+i].xyz[0];
833 pt[1] += pv[j+i].xyz[1];
834 pt[2] += pv[j+i].xyz[2];
844 // =======================================================================
845 // function : DrawDegeneratesPolygonsAsPoints
847 // =======================================================================
848 void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsPoints() const
852 tel_point pv = myPArray->vertices;
854 if (myPArray->num_bounds > 0)
856 if (myPArray->num_edges > 0)
858 for (k = n = 0; k < myPArray->num_bounds; ++k)
860 pt[0] = pt[1] = pt[2] = 0.0;
861 for (j = 0; j < myPArray->bounds[k]; ++j)
863 iv = myPArray->edges[n+j];
864 pt[0] += pv[iv].xyz[0];
865 pt[1] += pv[iv].xyz[1];
866 pt[2] += pv[iv].xyz[2];
868 pt[0] /= myPArray->bounds[k];
869 pt[1] /= myPArray->bounds[k];
870 pt[2] /= myPArray->bounds[k];
872 n += myPArray->bounds[k];
877 for (k = n = 0; k < myPArray->num_bounds; ++k)
879 pt[0] = pt[1] = pt[2] = 0.0;
880 for (j = 0; j < myPArray->bounds[k]; ++j)
882 pt[0] += pv[n+j].xyz[0];
883 pt[1] += pv[n+j].xyz[1];
884 pt[2] += pv[n+j].xyz[2];
886 pt[0] /= myPArray->bounds[k];
887 pt[1] /= myPArray->bounds[k];
888 pt[2] /= myPArray->bounds[k];
890 n += myPArray->bounds[k];
894 else if (myPArray->num_edges > 0)
896 pt[0] = pt[1] = pt[2] = 0.0;
897 for (j = 0; j < myPArray->num_edges; ++j)
899 iv = myPArray->edges[j];
900 pt[0] += pv[iv].xyz[0];
901 pt[1] += pv[iv].xyz[1];
902 pt[2] += pv[iv].xyz[2];
904 pt[0] /= myPArray->num_edges;
905 pt[1] /= myPArray->num_edges;
906 pt[2] /= myPArray->num_edges;
911 pt[0] = pt[1] = pt[2] = 0.0;
912 for (j = 0; j < myPArray->num_vertexs; ++j)
914 pt[0] += pv[j].xyz[0];
915 pt[1] += pv[j].xyz[1];
916 pt[2] += pv[j].xyz[2];
918 pt[0] /= myPArray->num_vertexs;
919 pt[1] /= myPArray->num_vertexs;
920 pt[2] /= myPArray->num_vertexs;
925 // =======================================================================
926 // function : DrawDegeneratesQuadranglesAsPoints
928 // =======================================================================
929 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsPoints() const
933 tel_point pv = myPArray->vertices;
935 if (myPArray->num_edges > 0)
937 for (j = 0; j < myPArray->num_edges; j += 4)
939 pt[0] = pt[1] = pt[2] = 0.0;
940 for (i = 0; i < 4; ++i)
942 iv = myPArray->edges[j+i];
943 pt[0] += pv[iv].xyz[0];
944 pt[1] += pv[iv].xyz[1];
945 pt[2] += pv[iv].xyz[2];
955 for (j = 0; j < myPArray->num_vertexs; j += 4)
957 pt[0] = pt[1] = pt[2] = 0.0;
958 for (i = 0; i < 4; ++i)
960 pt[0] += pv[j+i].xyz[0];
961 pt[1] += pv[j+i].xyz[1];
962 pt[2] += pv[j+i].xyz[2];
972 // =======================================================================
973 // function : DrawDegeneratesAsPoints
975 // =======================================================================
976 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsPoints() const
980 tel_point pv = myPArray->vertices;
982 if (myPArray->num_bounds > 0)
984 for (k = n = 0; k < myPArray->num_bounds; ++k)
986 for (j = 0; j < myPArray->bounds[k] - 2; j += 2)
988 pt[0] = pt[1] = pt[2] = 0.;
989 for (i = 0; i < 4; ++i)
991 pt[0] += pv[n+j+i].xyz[0];
992 pt[1] += pv[n+j+i].xyz[1];
993 pt[2] += pv[n+j+i].xyz[2];
1000 n += myPArray->bounds[k];
1005 for (j = 0; j < myPArray->num_vertexs - 2; j += 2)
1007 pt[0] = pt[1] = pt[2] = 0.;
1008 for (i = 0; i < 4; ++i)
1010 pt[0] += pv[j+i].xyz[0];
1011 pt[1] += pv[j+i].xyz[1];
1012 pt[2] += pv[j+i].xyz[2];
1022 // =======================================================================
1023 // function : DrawDegeneratesAsPoints
1025 // =======================================================================
1026 void OpenGl_PrimitiveArray::DrawDegeneratesAsPoints (const TEL_COLOUR* theEdgeColour,
1027 const float theSkipRatio) const
1029 if (theSkipRatio >= 1.0f)
1032 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1033 glDisable (GL_LIGHTING);
1035 glDisable (GL_DEPTH_TEST);
1036 glColor3fv (theEdgeColour->rgb);
1038 glBegin (GL_POINTS);
1042 DrawDegeneratesPointsAsPoints();
1045 DrawDegeneratesLinesAsPoints();
1049 DrawDegeneratesPolygonsAsPoints();
1052 DrawDegeneratesTrianglesAsPoints();
1055 DrawDegeneratesQuadranglesAsPoints();
1057 case GL_TRIANGLE_FAN:
1058 case GL_TRIANGLE_STRIP:
1059 DrawDegeneratesTrianglestripsAsPoints();
1062 DrawDegeneratesQuadranglestripsAsPoints();
1069 glEnable (GL_DEPTH_TEST);
1072 // =======================================================================
1073 // function : DrawDegeneratesLinesAsLines
1075 // =======================================================================
1076 void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsLines (const float theSkipRatio) const
1079 tel_point pv = myPArray->vertices;
1081 Tint n = myPArray->num_vertexs;
1082 Tint j = int((1.0f - theSkipRatio) * n);
1086 myPArray->keys[i] = -myPArray->keys[i];
1089 if (myPArray->num_bounds > 0)
1091 if (myPArray->num_edges > 0)
1093 for (i = n = 0; i < myPArray->num_bounds; ++i)
1096 for (j = 0; j < myPArray->bounds[i]; ++j)
1098 iv = myPArray->edges[n + j];
1099 if (myPArray->keys[iv] < 0)
1101 myPArray->keys[iv] = -myPArray->keys[iv];
1102 glVertex3fv (pv[iv].xyz);
1106 n += myPArray->bounds[i];
1111 for (i = n = 0; i < myPArray->num_bounds; ++i)
1114 for (j = 0; j < myPArray->bounds[i]; ++j)
1116 if (myPArray->keys[n+j] < 0)
1118 myPArray->keys[n+j] = -myPArray->keys[n+j];
1119 glVertex3fv (pv[n+j].xyz);
1123 n += myPArray->bounds[i];
1127 else if (myPArray->num_edges > 0)
1130 for (j = 0; j < myPArray->num_edges; ++j)
1132 iv = myPArray->edges[j];
1133 if (myPArray->keys[iv] < 0)
1135 myPArray->keys[iv] = -myPArray->keys[iv];
1136 glVertex3fv (pv[iv].xyz);
1144 for (j = 0; j < myPArray->num_vertexs; ++j)
1146 if (myPArray->keys[j] < 0)
1148 myPArray->keys[j] = -myPArray->keys[j];
1149 glVertex3fv (pv[j].xyz);
1156 // =======================================================================
1157 // function : DrawDegeneratesTrianglesAsLines
1159 // =======================================================================
1160 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsLines (const float theSkipRatio) const
1163 tel_point pv = myPArray->vertices;
1165 Tint n = myPArray->num_vertexs / 3;
1166 Tint j = int((1.0f - theSkipRatio) * n);
1169 i = OGL_Rand() % n; i *= 3;
1170 myPArray->keys[i] = -myPArray->keys[i];
1173 if (myPArray->num_edges > 0)
1175 for (j = 0; j < myPArray->num_edges; j += 3)
1177 iv = myPArray->edges[j];
1178 if (myPArray->keys[iv] < 0)
1180 myPArray->keys[iv] = -myPArray->keys[iv];
1181 glBegin (GL_LINE_LOOP);
1182 for (i = 0; i < 3; ++i)
1184 iv = myPArray->edges[j+i];
1185 glVertex3fv (pv[iv].xyz);
1193 for (j = 0; j < myPArray->num_vertexs; j += 3)
1195 if (myPArray->keys[j] < 0)
1197 myPArray->keys[j] = -myPArray->keys[j];
1198 glBegin (GL_LINE_LOOP);
1199 for (i = 0; i < 3; ++i)
1201 glVertex3fv (pv[j+i].xyz);
1209 // =======================================================================
1210 // function : DrawDegeneratesTrianglesAsLines
1212 // =======================================================================
1213 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsLines (const float theSkipRatio) const
1215 Tint i, j, k, n, ni;
1216 tel_point pv = myPArray->vertices;
1218 if (myPArray->num_bounds > 0)
1220 for (i = n = 0; i < myPArray->num_bounds; ++i)
1222 ni = myPArray->bounds[i] - 2;
1223 k = int((1.0f - theSkipRatio) * ni);
1226 j = OGL_Rand() % ni; j += 2;
1227 myPArray->keys[n+j] = -myPArray->keys[n+j];
1229 for (j = 2; j < myPArray->bounds[i]; ++j)
1231 if (myPArray->keys[n+j] < 0)
1233 myPArray->keys[n+j] = -myPArray->keys[n+j];
1234 glBegin (GL_LINE_LOOP);
1235 glVertex3fv (pv[n+j-2].xyz);
1236 glVertex3fv (pv[n+j-1].xyz);
1237 glVertex3fv (pv[n+j].xyz);
1241 n += myPArray->bounds[i];
1246 ni = myPArray->num_vertexs - 2;
1247 k = int((1.0f - theSkipRatio) * ni);
1250 j = OGL_Rand() % ni; j += 2;
1251 myPArray->keys[j] = -myPArray->keys[j];
1253 for (j = 2; j < myPArray->num_vertexs; ++j)
1255 if (myPArray->keys[j] < 0)
1257 myPArray->keys[j] = -myPArray->keys[j];
1258 glBegin (GL_LINE_LOOP);
1259 glVertex3fv (pv[j-2].xyz);
1260 glVertex3fv (pv[j-1].xyz);
1261 glVertex3fv (pv[j].xyz);
1268 // =======================================================================
1269 // function : DrawDegeneratesPolygonsAsLines
1271 // =======================================================================
1272 void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsLines (const float theSkipRatio) const
1275 tel_point pv = myPArray->vertices;
1277 Tint n = myPArray->num_vertexs;
1278 Tint j = int((1.0f - theSkipRatio) * n);
1282 myPArray->keys[i] = -myPArray->keys[i];
1285 if (myPArray->num_bounds > 0)
1287 if (myPArray->num_edges > 0)
1289 for (i = n = 0; i < myPArray->num_bounds; ++i)
1291 glBegin (GL_LINE_LOOP);
1292 for (j = 0; j < myPArray->bounds[i]; ++j)
1294 iv = myPArray->edges[n+j];
1295 if (myPArray->keys[iv] < 0)
1297 myPArray->keys[iv] = -myPArray->keys[iv];
1298 glVertex3fv (pv[iv].xyz);
1302 n += myPArray->bounds[i];
1307 for (i = n = 0; i < myPArray->num_bounds; ++i)
1309 glBegin (GL_LINE_LOOP);
1310 for (j = 0; j < myPArray->bounds[i]; ++j)
1312 if (myPArray->keys[n+j] < 0)
1314 myPArray->keys[n+j] = -myPArray->keys[n+j];
1315 glVertex3fv (pv[n+j].xyz);
1319 n += myPArray->bounds[i];
1323 else if (myPArray->num_edges > 0)
1325 glBegin (GL_LINE_LOOP);
1326 for (j = 0; j < myPArray->num_edges; ++j)
1328 iv = myPArray->edges[j];
1329 if (myPArray->keys[iv] < 0)
1331 myPArray->keys[iv] = -myPArray->keys[iv];
1332 glVertex3fv (pv[iv].xyz);
1339 glBegin (GL_LINE_LOOP);
1340 for (j = 0; j < myPArray->num_vertexs; ++j)
1342 if (myPArray->keys[j] < 0)
1344 myPArray->keys[j] = -myPArray->keys[j];
1345 glVertex3fv (pv[j].xyz);
1352 // =======================================================================
1353 // function : DrawDegeneratesQuadranglesAsLines
1355 // =======================================================================
1356 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsLines (const float theSkipRatio) const
1359 tel_point pv = myPArray->vertices;
1361 Tint n = myPArray->num_vertexs / 4;
1362 Tint j = int((1.0f - theSkipRatio) * n);
1365 i = OGL_Rand() % n; i *= 4;
1366 myPArray->keys[i] = -myPArray->keys[i];
1369 if (myPArray->num_edges > 0)
1371 for (j = 0; j < myPArray->num_edges; j += 4)
1373 iv = myPArray->edges[j];
1374 if (myPArray->keys[iv] < 0)
1376 myPArray->keys[iv] = -myPArray->keys[iv];
1377 glBegin (GL_LINE_LOOP);
1378 for (i = 0; i < 4; ++i)
1380 iv = myPArray->edges[j+i];
1381 glVertex3fv (pv[iv].xyz);
1389 for (j = 0; j < myPArray->num_vertexs; j += 4)
1391 if (myPArray->keys[j] < 0)
1393 myPArray->keys[j] = -myPArray->keys[j];
1394 glBegin (GL_LINE_LOOP);
1395 for (i = 0; i < 4; ++i)
1397 glVertex3fv (pv[j+i].xyz);
1405 // =======================================================================
1406 // function : DrawDegeneratesQuadranglesAsLines
1408 // =======================================================================
1409 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsLines (const float theSkipRatio) const
1411 Tint i, j, k, n, ni;
1412 tel_point pv = myPArray->vertices;
1414 if (myPArray->num_bounds > 0)
1416 for (i = n = 0; i < myPArray->num_bounds; ++i)
1418 ni = myPArray->bounds[i] / 2 - 2;
1419 k = int((1.0f - theSkipRatio) * ni);
1422 j = OGL_Rand() % ni; j = j * 2 + 2;
1423 myPArray->keys[n+j] = -myPArray->keys[n+j];
1425 for (j = 3; j < myPArray->bounds[i]; j += 2)
1427 if (myPArray->keys[n+j] < 0)
1429 myPArray->keys[n+j] = -myPArray->keys[n+j];
1430 glBegin (GL_LINE_LOOP);
1431 glVertex3fv (pv[n+j-3].xyz);
1432 glVertex3fv (pv[n+j-2].xyz);
1433 glVertex3fv (pv[n+j-1].xyz);
1434 glVertex3fv (pv[n+j].xyz);
1438 n += myPArray->bounds[i];
1443 ni = myPArray->num_vertexs / 2 - 2;
1444 k = int((1.0f - theSkipRatio) * ni);
1447 j = OGL_Rand() % ni; j = j * 2 + 2;
1448 myPArray->keys[j] = -myPArray->keys[j];
1450 for (j = 3; j < myPArray->num_vertexs; j += 2)
1452 if (myPArray->keys[j] < 0)
1454 myPArray->keys[j] = -myPArray->keys[j];
1455 glBegin (GL_LINE_LOOP);
1456 glVertex3fv (pv[j-3].xyz);
1457 glVertex3fv (pv[j-2].xyz);
1458 glVertex3fv (pv[j-1].xyz);
1459 glVertex3fv (pv[j].xyz);
1466 // =======================================================================
1467 // function : DrawDegeneratesAsLines
1469 // =======================================================================
1470 void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR* theEdgeColour,
1471 const Handle(OpenGl_Workspace)& theWorkspace) const
1473 const float aSkipRatio = theWorkspace->SkipRatio;
1475 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1477 glDisable (GL_LIGHTING);
1480 glDisable (GL_DEPTH_TEST);
1482 glColor3fv (theEdgeColour->rgb);
1484 if (aSkipRatio != 0.0f)
1489 if (aSkipRatio < 1.0f)
1490 DrawDegeneratesPointsAsPoints();
1493 DrawDegeneratesLinesAsLines (aSkipRatio);
1497 DrawDegeneratesPolygonsAsLines (aSkipRatio);
1500 DrawDegeneratesTrianglesAsLines (aSkipRatio);
1503 DrawDegeneratesQuadranglesAsLines (aSkipRatio);
1505 case GL_TRIANGLE_FAN:
1506 case GL_TRIANGLE_STRIP:
1507 DrawDegeneratesTrianglestripsAsLines (aSkipRatio);
1510 DrawDegeneratesQuadranglestripsAsLines (aSkipRatio);
1519 glPushAttrib (GL_POLYGON_BIT);
1520 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
1522 GLboolean color_array_mode = glIsEnabled (GL_COLOR_ARRAY);
1523 GLboolean edge_flag_array_mode = glIsEnabled (GL_EDGE_FLAG_ARRAY);
1524 GLboolean index_array_mode = glIsEnabled (GL_INDEX_ARRAY);
1525 GLboolean normal_array_mode = glIsEnabled (GL_NORMAL_ARRAY);
1526 GLboolean texture_coord_array_mode = glIsEnabled (GL_TEXTURE_COORD_ARRAY);
1527 GLboolean vertex_array_mode = glIsEnabled (GL_VERTEX_ARRAY);
1529 glDisableClientState (GL_COLOR_ARRAY);
1530 glDisableClientState (GL_EDGE_FLAG_ARRAY);
1531 glDisableClientState (GL_INDEX_ARRAY);
1532 glDisableClientState (GL_NORMAL_ARRAY);
1533 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
1535 if (!vertex_array_mode)
1536 glEnableClientState (GL_VERTEX_ARRAY);
1538 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
1541 glGetIntegerv (GL_RENDER_MODE, &renderMode);
1543 if (myPArray->num_bounds > 0)
1545 if (myPArray->num_edges > 0)
1547 for (i = n = 0; i < myPArray->num_bounds; ++i)
1549 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1550 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
1551 n += myPArray->bounds[i];
1556 for (i = n = 0; i < myPArray->num_bounds; ++i)
1558 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1559 n, myPArray->bounds[i]);
1560 n += myPArray->bounds[i];
1564 else if (myPArray->num_edges > 0)
1566 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1567 myPArray->num_edges, (GLenum* )myPArray->edges);
1571 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1572 0, myPArray->num_vertexs);
1575 if (!vertex_array_mode) glDisableClientState (GL_VERTEX_ARRAY);
1577 if (color_array_mode) glEnableClientState (GL_COLOR_ARRAY);
1578 if (edge_flag_array_mode) glEnableClientState (GL_EDGE_FLAG_ARRAY);
1579 if (index_array_mode) glEnableClientState (GL_INDEX_ARRAY);
1580 if (normal_array_mode) glEnableClientState (GL_NORMAL_ARRAY);
1581 if (texture_coord_array_mode) glEnableClientState (GL_TEXTURE_COORD_ARRAY);
1587 glEnable(GL_DEPTH_TEST);
1590 // =======================================================================
1591 // function : DrawDegeneratesAsBBoxs
1593 // =======================================================================
1594 void OpenGl_PrimitiveArray::DrawDegeneratesAsBBoxs (const TEL_COLOUR* theEdgeColour) const
1596 GLfloat minp[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
1597 GLfloat maxp[3] = { FLT_MIN, FLT_MIN, FLT_MIN };
1598 tel_point pv = myPArray->vertices;
1600 glDisable (GL_LIGHTING);
1602 glColor3fv (theEdgeColour->rgb);
1604 for (Tint i = 0; i < myPArray->num_vertexs; ++i)
1606 if (pv[i].xyz[0] < minp[0])
1607 minp[0] = pv[i].xyz[0];
1608 if (pv[i].xyz[1] < minp[1])
1609 minp[1] = pv[i].xyz[1];
1610 if (pv[i].xyz[2] < minp[2])
1611 minp[2] = pv[i].xyz[2];
1613 if (pv[i].xyz[0] > maxp[0])
1614 maxp[0] = pv[i].xyz[0];
1615 if (pv[i].xyz[1] > maxp[1])
1616 maxp[1] = pv[i].xyz[1];
1617 if (pv[i].xyz[2] > maxp[2])
1618 maxp[2] = pv[i].xyz[2];
1621 glBegin (GL_LINE_STRIP);
1624 glVertex3f (minp[0], maxp[1], minp[2]);
1625 glVertex3f (minp[0], maxp[1], maxp[2]);
1626 glVertex3f (minp[0], minp[1], maxp[2]);
1627 glVertex3f (minp[0], minp[1], minp[2]);
1629 glVertex3f (maxp[0], minp[1], minp[2]);
1630 glVertex3f (maxp[0], maxp[1], minp[2]);
1631 glVertex3f (maxp[0], maxp[1], maxp[2]);
1632 glVertex3f (maxp[0], minp[1], maxp[2]);
1633 glVertex3f (maxp[0], minp[1], minp[2]);
1635 glVertex3f (maxp[0], minp[1], maxp[2]);
1636 glVertex3f (minp[0], minp[1], maxp[2]);
1637 glVertex3f (minp[0], maxp[1], maxp[2]);
1639 glVertex3f (maxp[0], maxp[1], minp[2]);
1640 glVertex3f (minp[0], maxp[1], minp[2]);
1645 // =======================================================================
1646 // function : OpenGl_PrimitiveArray
1648 // =======================================================================
1649 OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
1650 : myPArray (thePArray),
1651 myDrawMode (GL_NONE)
1653 switch (myPArray->type)
1655 case TelPointsArrayType:
1656 myDrawMode = GL_POINTS;
1658 case TelPolylinesArrayType:
1659 myDrawMode = GL_LINE_STRIP;
1661 case TelSegmentsArrayType:
1662 myDrawMode = GL_LINES;
1664 case TelPolygonsArrayType:
1665 myDrawMode = GL_POLYGON;
1667 case TelTrianglesArrayType:
1668 myDrawMode = GL_TRIANGLES;
1670 case TelQuadranglesArrayType:
1671 myDrawMode = GL_QUADS;
1673 case TelTriangleStripsArrayType:
1674 myDrawMode = GL_TRIANGLE_STRIP;
1676 case TelQuadrangleStripsArrayType:
1677 myDrawMode = GL_QUAD_STRIP;
1679 case TelTriangleFansArrayType:
1680 myDrawMode = GL_TRIANGLE_FAN;
1685 // =======================================================================
1686 // function : ~OpenGl_PrimitiveArray
1688 // =======================================================================
1689 OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray ()
1691 if (myPArray == NULL)
1694 if (myPArray->VBOEnabled == VBO_OK)
1696 OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
1697 if (myPArray->bufferVBO[VBOEdges] != 0)
1698 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1699 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOEdges]));
1700 if (myPArray->bufferVBO[VBOVertices] != 0)
1701 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1702 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVertices]));
1703 if (myPArray->bufferVBO[VBOVcolours] != 0)
1704 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1705 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVcolours]));
1706 if (myPArray->bufferVBO[VBOVnormals] != 0)
1707 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1708 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVnormals]));
1709 if (myPArray->bufferVBO[VBOVtexels] != 0)
1710 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1711 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVtexels]));
1715 // =======================================================================
1716 // function : Render
1718 // =======================================================================
1719 void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
1721 if (myPArray == NULL || myDrawMode == GL_NONE)
1724 // create VBOs on first render call
1725 if (myPArray->VBOEnabled == -1) // special value for uninitialized state
1727 myPArray->VBOEnabled = OpenGl_GraphicDriver::ToUseVBO() && (theWorkspace->GetGlContext()->arbVBO != NULL);
1728 if (myPArray->VBOEnabled != 0)
1729 BuildVBO (theWorkspace);
1732 switch (myPArray->type)
1734 case TelPointsArrayType:
1735 case TelPolylinesArrayType:
1736 case TelSegmentsArrayType:
1738 glDisable (GL_LIGHTING);
1740 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1741 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
1742 theWorkspace->DegenerateModel)
1744 glDisable (GL_DEPTH_TEST);
1745 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1747 theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
1751 case TelPolygonsArrayType:
1752 case TelTrianglesArrayType:
1753 case TelQuadranglesArrayType:
1754 case TelTriangleStripsArrayType:
1755 case TelTriangleFansArrayType:
1756 case TelQuadrangleStripsArrayType:
1758 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1759 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
1760 theWorkspace->DegenerateModel < 2)
1762 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1764 glEnable (GL_DEPTH_TEST);
1765 theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
1773 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
1774 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
1776 Tint aFrontLightingModel = anAspectFace->Context().IntFront.color_mask;
1777 const TEL_COLOUR* anInteriorColor = &anAspectFace->Context().IntFront.matcol;
1778 const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
1779 const TEL_COLOUR* aLineColor = &anAspectLine->Color();
1781 // Use highlight colors
1782 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
1784 anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor;
1785 aFrontLightingModel = 0;
1788 DrawArray (aFrontLightingModel,
1789 anAspectFace->Context().InteriorStyle,
1790 anAspectFace->Context().Edge,
1794 &anAspectFace->Context().IntFront,
1797 switch (myPArray->type)
1799 case TelPointsArrayType:
1800 case TelPolylinesArrayType:
1801 case TelSegmentsArrayType:
1803 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)