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();
283 // Following pointers have been provided for performance improvement
284 tel_colour pfc = myPArray->fcolours;
285 Tint* pvc = myPArray->vcolours;
288 for (i = 0; i < myPArray->num_vertexs; ++i)
290 transp = int(theFaceProp->trans * 255.0f);
291 #if defined (sparc) || defined (__sparc__) || defined (__sparc)
292 pvc[i] = (pvc[i] & 0xffffff00);
295 pvc[i] = (pvc[i] & 0x00ffffff);
296 pvc[i] += transp << 24;
301 switch (myPArray->type)
303 case TelPointsArrayType:
304 case TelPolylinesArrayType:
305 case TelSegmentsArrayType:
306 glColor3fv (theLineColour->rgb);
308 case TelPolygonsArrayType:
309 case TelTrianglesArrayType:
310 case TelQuadranglesArrayType:
311 case TelTriangleStripsArrayType:
312 case TelQuadrangleStripsArrayType:
313 case TelTriangleFansArrayType:
314 glColor3fv (theInteriorColour->rgb);
318 // Temporarily disable environment mapping
319 if (myDrawMode <= GL_LINE_STRIP)
321 glPushAttrib (GL_ENABLE_BIT);
322 glDisable (GL_TEXTURE_1D);
323 glDisable (GL_TEXTURE_2D);
326 if (theWorkspace->DegenerateModel < 2 &&
327 ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
328 (myDrawMode <= GL_LINE_STRIP)))
330 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
336 if (theInteriorStyle == Aspect_IS_HIDDENLINE)
343 // Sometimes the GL_LIGHTING mode is activated here
344 // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
345 // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
346 if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
347 glDisable (GL_LIGHTING);
349 glEnable (GL_LIGHTING);
351 if (myPArray->num_vertexs > 0
352 && myPArray->flagBufferVBO != VBO_OK
353 && !aGlContext->IsFeedback())
355 if (myPArray->vertices != NULL)
357 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
358 glEnableClientState (GL_VERTEX_ARRAY);
360 if (myPArray->vnormals != NULL)
362 glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
363 glEnableClientState (GL_NORMAL_ARRAY);
365 if (myPArray->vtexels != NULL)
367 glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
368 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
373 glColorPointer (4, GL_UNSIGNED_BYTE, 0, pvc); // array of colors
374 glEnableClientState (GL_COLOR_ARRAY);
375 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
376 glEnable (GL_COLOR_MATERIAL);
379 else if (myPArray->num_vertexs > 0
380 && myPArray->flagBufferVBO == VBO_OK)
382 // Bindings concrete pointer in accordance with VBO buffer
383 if (myPArray->bufferVBO[VBOVertices] != 0)
385 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
386 glVertexPointer (3, GL_FLOAT, 0, NULL); // array of vertices
387 glEnableClientState (GL_VERTEX_ARRAY);
389 if (myPArray->bufferVBO[VBOVnormals] != 0)
391 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
392 glNormalPointer (GL_FLOAT, 0, NULL); // array of normals
393 glEnableClientState (GL_NORMAL_ARRAY);
395 if (myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
397 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
398 glTexCoordPointer (2, GL_FLOAT, 0, NULL); // array of texture coordinates
399 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
401 if (myPArray->bufferVBO[VBOVcolours] != 0)
403 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
404 glColorPointer (4, GL_UNSIGNED_BYTE, 0, NULL); // array of colors
405 glEnableClientState (GL_COLOR_ARRAY);
406 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
407 glEnable (GL_COLOR_MATERIAL);
411 // OCC22236 NOTE: draw for all situations:
412 // 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
413 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
414 // 3) draw primitive by vertexes if no edges and bounds array is specified
415 if (myPArray->flagBufferVBO == VBO_OK)
417 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges] != 0)
419 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]); // for edge indices
420 if (myPArray->num_bounds > 0)
422 // draw primitives by vertex count with the indicies
423 Tint* anOffset = NULL;
424 for (i = 0; i < myPArray->num_bounds; ++i)
426 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, anOffset);
427 anOffset += myPArray->bounds[i];
432 // draw one (or sequential) primitive by the indicies
433 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
436 else if (myPArray->num_bounds > 0)
438 for (i = n = 0; i < myPArray->num_bounds; ++i)
440 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
441 n += myPArray->bounds[i];
446 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
450 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
451 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
455 if (myPArray->num_bounds > 0)
457 if (myPArray->num_edges > 0)
459 for (i = n = 0; i < myPArray->num_bounds; ++i)
461 if (pfc != NULL) glColor3fv (pfc[i].rgb);
462 DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
463 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
464 n += myPArray->bounds[i];
469 for (i = n = 0; i < myPArray->num_bounds; ++i)
473 glColor3fv (pfc[i].rgb);
475 DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
476 n, myPArray->bounds[i]);
477 n += myPArray->bounds[i];
481 else if (myPArray->num_edges > 0)
483 DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
484 myPArray->num_edges, (GLenum* )myPArray->edges);
488 DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
489 0, myPArray->num_vertexs);
493 if (myPArray->bufferVBO[VBOVcolours] != 0 || pvc != NULL)
495 glDisable (GL_COLOR_MATERIAL);
496 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
499 if (myPArray->bufferVBO[VBOVertices] != 0 || myPArray->vertices != NULL)
500 glDisableClientState (GL_VERTEX_ARRAY);
501 if (myPArray->bufferVBO[VBOVcolours] != 0 || myPArray->vcolours != NULL)
502 glDisableClientState (GL_COLOR_ARRAY);
503 if (myPArray->bufferVBO[VBOVnormals] != 0 || myPArray->vnormals != NULL)
504 glDisableClientState (GL_NORMAL_ARRAY);
505 if ((myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) || myPArray->vtexels != NULL)
506 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
508 if (theWorkspace->DegenerateModel)
510 if (myDrawMode <= GL_LINE_STRIP)
518 if (theEdgeFlag || theWorkspace->DegenerateModel)
520 switch (theWorkspace->DegenerateModel)
522 default: // XXX_TDM_NODE or TINY
523 // On some NVIDIA graphic cards, using glEdgeFlagPointer() in
524 // combination with VBO ( edge flag data put into a VBO buffer)
525 // leads to a crash in a driver. Therefore, edge flags are simply
526 // igonored when VBOs are enabled, so all the edges are drawn if
527 // edge visibility is turned on. In order to draw edges selectively,
528 // either disable VBO or turn off edge visibilty in the current
529 // primitive array and create a separate primitive array (segments)
530 // and put edges to be drawn into it.
531 if (myDrawMode > GL_LINE_STRIP)
533 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);
578 // OCC22236 NOTE: draw edges for all situations:
579 // 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
580 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
581 // 3) draw primitive's edges by vertexes if no edges and bounds array is specified
582 if (myPArray->flagBufferVBO == VBO_OK)
584 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
585 glEnableClientState (GL_VERTEX_ARRAY);
586 glColor3fv (theEdgeColour->rgb);
587 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges])
589 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
591 // draw primitives by vertex count with the indicies
592 if (myPArray->num_bounds > 0)
595 for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
597 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, offset);
598 offset += myPArray->bounds[i];
601 // draw one (or sequential) primitive by the indicies
604 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
607 else if (myPArray->num_bounds > 0)
609 for (i = n = 0; i < myPArray->num_bounds; ++i)
611 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
612 n += myPArray->bounds[i];
617 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
621 glDisableClientState (GL_VERTEX_ARRAY);
622 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
623 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
627 glEnableClientState (GL_VERTEX_ARRAY);
628 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
630 glColor3fv (theEdgeColour->rgb);
631 if (myPArray->num_bounds > 0)
633 if (myPArray->num_edges > 0)
635 for (i = n = 0; i < myPArray->num_bounds; ++i)
637 if (myPArray->edge_vis)
639 glBegin (myDrawMode);
640 for (j = 0; j < myPArray->bounds[i]; ++j)
642 glEdgeFlag (myPArray->edge_vis[n+j]);
643 glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
649 DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
650 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
652 n += myPArray->bounds[i];
657 for (i = n = 0 ; i < myPArray->num_bounds; ++i)
659 DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
660 n, myPArray->bounds[i]);
661 n += myPArray->bounds[i];
665 else if (myPArray->num_edges > 0)
667 if (myPArray->edge_vis)
669 glBegin (myDrawMode);
670 for (i = 0; i < myPArray->num_edges; ++i)
672 glEdgeFlag (myPArray->edge_vis[i]);
673 glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
679 DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
680 myPArray->num_edges, (GLenum* )myPArray->edges);
685 DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
686 0, myPArray->num_vertexs);
690 if (myDrawMode > GL_LINE_STRIP)
692 // Restore line context
693 theWorkspace->SetAspectLine (anAspectLineOld);
698 // =======================================================================
699 // function : DrawDegeneratesPointsAsPoints
701 // =======================================================================
702 void OpenGl_PrimitiveArray::DrawDegeneratesPointsAsPoints() const
704 tel_point pv = myPArray->vertices;
705 for (Tint aVertId = 0; aVertId < myPArray->num_vertexs; ++aVertId)
707 glVertex3fv (&pv[aVertId].xyz[0]);
711 // =======================================================================
712 // function : DrawDegeneratesLinesAsPoints
714 // =======================================================================
715 void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsPoints() const
718 tel_point pv = myPArray->vertices;
721 while (j < myPArray->num_vertexs)
723 pt[0] = pv[j].xyz[0];
724 pt[1] = pv[j].xyz[1];
725 pt[2] = pv[j].xyz[2]; ++j;
726 pt[0] += pv[j].xyz[0];
727 pt[1] += pv[j].xyz[1];
728 pt[2] += pv[j].xyz[2]; ++j;
736 // =======================================================================
737 // function : DrawDegeneratesTrianglesAsPoints
739 // =======================================================================
740 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsPoints() const
744 tel_point pv = myPArray->vertices;
746 if (myPArray->num_edges > 0)
748 for (j = 0; j < myPArray->num_edges; j += 3)
750 iv = myPArray->edges[j];
751 pt[0] = pv[iv].xyz[0];
752 pt[1] = pv[iv].xyz[1];
753 pt[2] = pv[iv].xyz[2];
754 for (i = 1; i < 3; ++i)
756 iv = myPArray->edges[j+i];
757 pt[0] += pv[iv].xyz[0];
758 pt[1] += pv[iv].xyz[1];
759 pt[2] += pv[iv].xyz[2];
769 for (j = 0; j < myPArray->num_vertexs; j += 3)
771 pt[0] = pv[j].xyz[0];
772 pt[1] = pv[j].xyz[1];
773 pt[2] = pv[j].xyz[2];
774 for (i = 1; i < 3; ++i)
776 pt[0] += pv[j+i].xyz[0];
777 pt[1] += pv[j+i].xyz[1];
778 pt[2] += pv[j+i].xyz[2];
788 // =======================================================================
789 // function : DrawDegeneratesTrianglesAsPoints
791 // =======================================================================
792 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsPoints() const
796 tel_point pv = myPArray->vertices;
798 if (myPArray->num_bounds > 0)
800 for (k = n = 0; k < myPArray->num_bounds; ++k)
802 for (j = 0; j < myPArray->bounds[k] - 2; ++j)
804 pt[0] = pv[n+j].xyz[0];
805 pt[1] = pv[n+j].xyz[1];
806 pt[2] = pv[n+j].xyz[2];
807 for (i = 1; i < 3; ++i)
809 pt[0] += pv[n+j+i].xyz[0];
810 pt[1] += pv[n+j+i].xyz[1];
811 pt[2] += pv[n+j+i].xyz[2];
818 n += myPArray->bounds[k];
823 for (j = 0; j < myPArray->num_vertexs - 2; ++j)
825 pt[0] = pv[j].xyz[0];
826 pt[1] = pv[j].xyz[1];
827 pt[2] = pv[j].xyz[2];
828 for (i = 1; i < 3; ++i)
830 pt[0] += pv[j+i].xyz[0];
831 pt[1] += pv[j+i].xyz[1];
832 pt[2] += pv[j+i].xyz[2];
842 // =======================================================================
843 // function : DrawDegeneratesPolygonsAsPoints
845 // =======================================================================
846 void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsPoints() const
850 tel_point pv = myPArray->vertices;
852 if (myPArray->num_bounds > 0)
854 if (myPArray->num_edges > 0)
856 for (k = n = 0; k < myPArray->num_bounds; ++k)
858 pt[0] = pt[1] = pt[2] = 0.0;
859 for (j = 0; j < myPArray->bounds[k]; ++j)
861 iv = myPArray->edges[n+j];
862 pt[0] += pv[iv].xyz[0];
863 pt[1] += pv[iv].xyz[1];
864 pt[2] += pv[iv].xyz[2];
866 pt[0] /= myPArray->bounds[k];
867 pt[1] /= myPArray->bounds[k];
868 pt[2] /= myPArray->bounds[k];
870 n += myPArray->bounds[k];
875 for (k = n = 0; k < myPArray->num_bounds; ++k)
877 pt[0] = pt[1] = pt[2] = 0.0;
878 for (j = 0; j < myPArray->bounds[k]; ++j)
880 pt[0] += pv[n+j].xyz[0];
881 pt[1] += pv[n+j].xyz[1];
882 pt[2] += pv[n+j].xyz[2];
884 pt[0] /= myPArray->bounds[k];
885 pt[1] /= myPArray->bounds[k];
886 pt[2] /= myPArray->bounds[k];
888 n += myPArray->bounds[k];
892 else if (myPArray->num_edges > 0)
894 pt[0] = pt[1] = pt[2] = 0.0;
895 for (j = 0; j < myPArray->num_edges; ++j)
897 iv = myPArray->edges[j];
898 pt[0] += pv[iv].xyz[0];
899 pt[1] += pv[iv].xyz[1];
900 pt[2] += pv[iv].xyz[2];
902 pt[0] /= myPArray->num_edges;
903 pt[1] /= myPArray->num_edges;
904 pt[2] /= myPArray->num_edges;
909 pt[0] = pt[1] = pt[2] = 0.0;
910 for (j = 0; j < myPArray->num_vertexs; ++j)
912 pt[0] += pv[j].xyz[0];
913 pt[1] += pv[j].xyz[1];
914 pt[2] += pv[j].xyz[2];
916 pt[0] /= myPArray->num_vertexs;
917 pt[1] /= myPArray->num_vertexs;
918 pt[2] /= myPArray->num_vertexs;
923 // =======================================================================
924 // function : DrawDegeneratesQuadranglesAsPoints
926 // =======================================================================
927 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsPoints() const
931 tel_point pv = myPArray->vertices;
933 if (myPArray->num_edges > 0)
935 for (j = 0; j < myPArray->num_edges; j += 4)
937 pt[0] = pt[1] = pt[2] = 0.0;
938 for (i = 0; i < 4; ++i)
940 iv = myPArray->edges[j+i];
941 pt[0] += pv[iv].xyz[0];
942 pt[1] += pv[iv].xyz[1];
943 pt[2] += pv[iv].xyz[2];
953 for (j = 0; j < myPArray->num_vertexs; j += 4)
955 pt[0] = pt[1] = pt[2] = 0.0;
956 for (i = 0; i < 4; ++i)
958 pt[0] += pv[j+i].xyz[0];
959 pt[1] += pv[j+i].xyz[1];
960 pt[2] += pv[j+i].xyz[2];
970 // =======================================================================
971 // function : DrawDegeneratesAsPoints
973 // =======================================================================
974 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsPoints() const
978 tel_point pv = myPArray->vertices;
980 if (myPArray->num_bounds > 0)
982 for (k = n = 0; k < myPArray->num_bounds; ++k)
984 for (j = 0; j < myPArray->bounds[k] - 2; j += 2)
986 pt[0] = pt[1] = pt[2] = 0.;
987 for (i = 0; i < 4; ++i)
989 pt[0] += pv[n+j+i].xyz[0];
990 pt[1] += pv[n+j+i].xyz[1];
991 pt[2] += pv[n+j+i].xyz[2];
998 n += myPArray->bounds[k];
1003 for (j = 0; j < myPArray->num_vertexs - 2; j += 2)
1005 pt[0] = pt[1] = pt[2] = 0.;
1006 for (i = 0; i < 4; ++i)
1008 pt[0] += pv[j+i].xyz[0];
1009 pt[1] += pv[j+i].xyz[1];
1010 pt[2] += pv[j+i].xyz[2];
1020 // =======================================================================
1021 // function : DrawDegeneratesAsPoints
1023 // =======================================================================
1024 void OpenGl_PrimitiveArray::DrawDegeneratesAsPoints (const TEL_COLOUR* theEdgeColour,
1025 const float theSkipRatio) const
1027 if (theSkipRatio >= 1.0f)
1030 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1031 glDisable (GL_LIGHTING);
1033 glDisable (GL_DEPTH_TEST);
1034 glColor3fv (theEdgeColour->rgb);
1036 glBegin (GL_POINTS);
1040 DrawDegeneratesPointsAsPoints();
1043 DrawDegeneratesLinesAsPoints();
1047 DrawDegeneratesPolygonsAsPoints();
1050 DrawDegeneratesTrianglesAsPoints();
1053 DrawDegeneratesQuadranglesAsPoints();
1055 case GL_TRIANGLE_FAN:
1056 case GL_TRIANGLE_STRIP:
1057 DrawDegeneratesTrianglestripsAsPoints();
1060 DrawDegeneratesQuadranglestripsAsPoints();
1067 glEnable (GL_DEPTH_TEST);
1070 // =======================================================================
1071 // function : DrawDegeneratesLinesAsLines
1073 // =======================================================================
1074 void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsLines (const float theSkipRatio) const
1077 tel_point pv = myPArray->vertices;
1079 Tint n = myPArray->num_vertexs;
1080 Tint j = int((1.0f - theSkipRatio) * n);
1084 myPArray->keys[i] = -myPArray->keys[i];
1087 if (myPArray->num_bounds > 0)
1089 if (myPArray->num_edges > 0)
1091 for (i = n = 0; i < myPArray->num_bounds; ++i)
1094 for (j = 0; j < myPArray->bounds[i]; ++j)
1096 iv = myPArray->edges[n + j];
1097 if (myPArray->keys[iv] < 0)
1099 myPArray->keys[iv] = -myPArray->keys[iv];
1100 glVertex3fv (pv[iv].xyz);
1104 n += myPArray->bounds[i];
1109 for (i = n = 0; i < myPArray->num_bounds; ++i)
1112 for (j = 0; j < myPArray->bounds[i]; ++j)
1114 if (myPArray->keys[n+j] < 0)
1116 myPArray->keys[n+j] = -myPArray->keys[n+j];
1117 glVertex3fv (pv[n+j].xyz);
1121 n += myPArray->bounds[i];
1125 else if (myPArray->num_edges > 0)
1128 for (j = 0; j < myPArray->num_edges; ++j)
1130 iv = myPArray->edges[j];
1131 if (myPArray->keys[iv] < 0)
1133 myPArray->keys[iv] = -myPArray->keys[iv];
1134 glVertex3fv (pv[iv].xyz);
1142 for (j = 0; j < myPArray->num_vertexs; ++j)
1144 if (myPArray->keys[j] < 0)
1146 myPArray->keys[j] = -myPArray->keys[j];
1147 glVertex3fv (pv[j].xyz);
1154 // =======================================================================
1155 // function : DrawDegeneratesTrianglesAsLines
1157 // =======================================================================
1158 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsLines (const float theSkipRatio) const
1161 tel_point pv = myPArray->vertices;
1163 Tint n = myPArray->num_vertexs / 3;
1164 Tint j = int((1.0f - theSkipRatio) * n);
1167 i = OGL_Rand() % n; i *= 3;
1168 myPArray->keys[i] = -myPArray->keys[i];
1171 if (myPArray->num_edges > 0)
1173 for (j = 0; j < myPArray->num_edges; j += 3)
1175 iv = myPArray->edges[j];
1176 if (myPArray->keys[iv] < 0)
1178 myPArray->keys[iv] = -myPArray->keys[iv];
1179 glBegin (GL_LINE_LOOP);
1180 for (i = 0; i < 3; ++i)
1182 iv = myPArray->edges[j+i];
1183 glVertex3fv (pv[iv].xyz);
1191 for (j = 0; j < myPArray->num_vertexs; j += 3)
1193 if (myPArray->keys[j] < 0)
1195 myPArray->keys[j] = -myPArray->keys[j];
1196 glBegin (GL_LINE_LOOP);
1197 for (i = 0; i < 3; ++i)
1199 glVertex3fv (pv[j+i].xyz);
1207 // =======================================================================
1208 // function : DrawDegeneratesTrianglesAsLines
1210 // =======================================================================
1211 void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsLines (const float theSkipRatio) const
1213 Tint i, j, k, n, ni;
1214 tel_point pv = myPArray->vertices;
1216 if (myPArray->num_bounds > 0)
1218 for (i = n = 0; i < myPArray->num_bounds; ++i)
1220 ni = myPArray->bounds[i] - 2;
1221 k = int((1.0f - theSkipRatio) * ni);
1224 j = OGL_Rand() % ni; j += 2;
1225 myPArray->keys[n+j] = -myPArray->keys[n+j];
1227 for (j = 2; j < myPArray->bounds[i]; ++j)
1229 if (myPArray->keys[n+j] < 0)
1231 myPArray->keys[n+j] = -myPArray->keys[n+j];
1232 glBegin (GL_LINE_LOOP);
1233 glVertex3fv (pv[n+j-2].xyz);
1234 glVertex3fv (pv[n+j-1].xyz);
1235 glVertex3fv (pv[n+j].xyz);
1239 n += myPArray->bounds[i];
1244 ni = myPArray->num_vertexs - 2;
1245 k = int((1.0f - theSkipRatio) * ni);
1248 j = OGL_Rand() % ni; j += 2;
1249 myPArray->keys[j] = -myPArray->keys[j];
1251 for (j = 2; j < myPArray->num_vertexs; ++j)
1253 if (myPArray->keys[j] < 0)
1255 myPArray->keys[j] = -myPArray->keys[j];
1256 glBegin (GL_LINE_LOOP);
1257 glVertex3fv (pv[j-2].xyz);
1258 glVertex3fv (pv[j-1].xyz);
1259 glVertex3fv (pv[j].xyz);
1266 // =======================================================================
1267 // function : DrawDegeneratesPolygonsAsLines
1269 // =======================================================================
1270 void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsLines (const float theSkipRatio) const
1273 tel_point pv = myPArray->vertices;
1275 Tint n = myPArray->num_vertexs;
1276 Tint j = int((1.0f - theSkipRatio) * n);
1280 myPArray->keys[i] = -myPArray->keys[i];
1283 if (myPArray->num_bounds > 0)
1285 if (myPArray->num_edges > 0)
1287 for (i = n = 0; i < myPArray->num_bounds; ++i)
1289 glBegin (GL_LINE_LOOP);
1290 for (j = 0; j < myPArray->bounds[i]; ++j)
1292 iv = myPArray->edges[n+j];
1293 if (myPArray->keys[iv] < 0)
1295 myPArray->keys[iv] = -myPArray->keys[iv];
1296 glVertex3fv (pv[iv].xyz);
1300 n += myPArray->bounds[i];
1305 for (i = n = 0; i < myPArray->num_bounds; ++i)
1307 glBegin (GL_LINE_LOOP);
1308 for (j = 0; j < myPArray->bounds[i]; ++j)
1310 if (myPArray->keys[n+j] < 0)
1312 myPArray->keys[n+j] = -myPArray->keys[n+j];
1313 glVertex3fv (pv[n+j].xyz);
1317 n += myPArray->bounds[i];
1321 else if (myPArray->num_edges > 0)
1323 glBegin (GL_LINE_LOOP);
1324 for (j = 0; j < myPArray->num_edges; ++j)
1326 iv = myPArray->edges[j];
1327 if (myPArray->keys[iv] < 0)
1329 myPArray->keys[iv] = -myPArray->keys[iv];
1330 glVertex3fv (pv[iv].xyz);
1337 glBegin (GL_LINE_LOOP);
1338 for (j = 0; j < myPArray->num_vertexs; ++j)
1340 if (myPArray->keys[j] < 0)
1342 myPArray->keys[j] = -myPArray->keys[j];
1343 glVertex3fv (pv[j].xyz);
1350 // =======================================================================
1351 // function : DrawDegeneratesQuadranglesAsLines
1353 // =======================================================================
1354 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsLines (const float theSkipRatio) const
1357 tel_point pv = myPArray->vertices;
1359 Tint n = myPArray->num_vertexs / 4;
1360 Tint j = int((1.0f - theSkipRatio) * n);
1363 i = OGL_Rand() % n; i *= 4;
1364 myPArray->keys[i] = -myPArray->keys[i];
1367 if (myPArray->num_edges > 0)
1369 for (j = 0; j < myPArray->num_edges; j += 4)
1371 iv = myPArray->edges[j];
1372 if (myPArray->keys[iv] < 0)
1374 myPArray->keys[iv] = -myPArray->keys[iv];
1375 glBegin (GL_LINE_LOOP);
1376 for (i = 0; i < 4; ++i)
1378 iv = myPArray->edges[j+i];
1379 glVertex3fv (pv[iv].xyz);
1387 for (j = 0; j < myPArray->num_vertexs; j += 4)
1389 if (myPArray->keys[j] < 0)
1391 myPArray->keys[j] = -myPArray->keys[j];
1392 glBegin (GL_LINE_LOOP);
1393 for (i = 0; i < 4; ++i)
1395 glVertex3fv (pv[j+i].xyz);
1403 // =======================================================================
1404 // function : DrawDegeneratesQuadranglesAsLines
1406 // =======================================================================
1407 void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsLines (const float theSkipRatio) const
1409 Tint i, j, k, n, ni;
1410 tel_point pv = myPArray->vertices;
1412 if (myPArray->num_bounds > 0)
1414 for (i = n = 0; i < myPArray->num_bounds; ++i)
1416 ni = myPArray->bounds[i] / 2 - 2;
1417 k = int((1.0f - theSkipRatio) * ni);
1420 j = OGL_Rand() % ni; j = j * 2 + 2;
1421 myPArray->keys[n+j] = -myPArray->keys[n+j];
1423 for (j = 3; j < myPArray->bounds[i]; j += 2)
1425 if (myPArray->keys[n+j] < 0)
1427 myPArray->keys[n+j] = -myPArray->keys[n+j];
1428 glBegin (GL_LINE_LOOP);
1429 glVertex3fv (pv[n+j-3].xyz);
1430 glVertex3fv (pv[n+j-2].xyz);
1431 glVertex3fv (pv[n+j-1].xyz);
1432 glVertex3fv (pv[n+j].xyz);
1436 n += myPArray->bounds[i];
1441 ni = myPArray->num_vertexs / 2 - 2;
1442 k = int((1.0f - theSkipRatio) * ni);
1445 j = OGL_Rand() % ni; j = j * 2 + 2;
1446 myPArray->keys[j] = -myPArray->keys[j];
1448 for (j = 3; j < myPArray->num_vertexs; j += 2)
1450 if (myPArray->keys[j] < 0)
1452 myPArray->keys[j] = -myPArray->keys[j];
1453 glBegin (GL_LINE_LOOP);
1454 glVertex3fv (pv[j-3].xyz);
1455 glVertex3fv (pv[j-2].xyz);
1456 glVertex3fv (pv[j-1].xyz);
1457 glVertex3fv (pv[j].xyz);
1464 // =======================================================================
1465 // function : DrawDegeneratesAsLines
1467 // =======================================================================
1468 void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR* theEdgeColour,
1469 const Handle(OpenGl_Workspace)& theWorkspace) const
1471 const float aSkipRatio = theWorkspace->SkipRatio;
1473 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1475 glDisable (GL_LIGHTING);
1478 glDisable (GL_DEPTH_TEST);
1480 glColor3fv (theEdgeColour->rgb);
1482 if (aSkipRatio != 0.0f)
1487 if (aSkipRatio < 1.0f)
1488 DrawDegeneratesPointsAsPoints();
1491 DrawDegeneratesLinesAsLines (aSkipRatio);
1495 DrawDegeneratesPolygonsAsLines (aSkipRatio);
1498 DrawDegeneratesTrianglesAsLines (aSkipRatio);
1501 DrawDegeneratesQuadranglesAsLines (aSkipRatio);
1503 case GL_TRIANGLE_FAN:
1504 case GL_TRIANGLE_STRIP:
1505 DrawDegeneratesTrianglestripsAsLines (aSkipRatio);
1508 DrawDegeneratesQuadranglestripsAsLines (aSkipRatio);
1517 Standard_Boolean isFeedback = theWorkspace->GetGlContext()->IsFeedback();
1518 glPushAttrib (GL_POLYGON_BIT);
1519 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
1521 GLboolean color_array_mode = glIsEnabled (GL_COLOR_ARRAY);
1522 GLboolean edge_flag_array_mode = glIsEnabled (GL_EDGE_FLAG_ARRAY);
1523 GLboolean index_array_mode = glIsEnabled (GL_INDEX_ARRAY);
1524 GLboolean normal_array_mode = glIsEnabled (GL_NORMAL_ARRAY);
1525 GLboolean texture_coord_array_mode = glIsEnabled (GL_TEXTURE_COORD_ARRAY);
1526 GLboolean vertex_array_mode = glIsEnabled (GL_VERTEX_ARRAY);
1528 glDisableClientState (GL_COLOR_ARRAY);
1529 glDisableClientState (GL_EDGE_FLAG_ARRAY);
1530 glDisableClientState (GL_INDEX_ARRAY);
1531 glDisableClientState (GL_NORMAL_ARRAY);
1532 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
1534 if (!vertex_array_mode)
1535 glEnableClientState (GL_VERTEX_ARRAY);
1537 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
1539 if (myPArray->num_bounds > 0)
1541 if (myPArray->num_edges > 0)
1543 for (i = n = 0; i < myPArray->num_bounds; ++i)
1545 DrawElements (theWorkspace, myPArray, isFeedback, myDrawMode,
1546 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
1547 n += myPArray->bounds[i];
1552 for (i = n = 0; i < myPArray->num_bounds; ++i)
1554 DrawArrays (theWorkspace, myPArray, isFeedback, myDrawMode,
1555 n, myPArray->bounds[i]);
1556 n += myPArray->bounds[i];
1560 else if (myPArray->num_edges > 0)
1562 DrawElements (theWorkspace, myPArray, isFeedback, myDrawMode,
1563 myPArray->num_edges, (GLenum* )myPArray->edges);
1567 DrawArrays (theWorkspace, myPArray, isFeedback, myDrawMode,
1568 0, myPArray->num_vertexs);
1571 if (!vertex_array_mode) glDisableClientState (GL_VERTEX_ARRAY);
1573 if (color_array_mode) glEnableClientState (GL_COLOR_ARRAY);
1574 if (edge_flag_array_mode) glEnableClientState (GL_EDGE_FLAG_ARRAY);
1575 if (index_array_mode) glEnableClientState (GL_INDEX_ARRAY);
1576 if (normal_array_mode) glEnableClientState (GL_NORMAL_ARRAY);
1577 if (texture_coord_array_mode) glEnableClientState (GL_TEXTURE_COORD_ARRAY);
1583 glEnable(GL_DEPTH_TEST);
1586 // =======================================================================
1587 // function : DrawDegeneratesAsBBoxs
1589 // =======================================================================
1590 void OpenGl_PrimitiveArray::DrawDegeneratesAsBBoxs (const TEL_COLOUR* theEdgeColour) const
1592 GLfloat minp[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
1593 GLfloat maxp[3] = { FLT_MIN, FLT_MIN, FLT_MIN };
1594 tel_point pv = myPArray->vertices;
1596 glDisable (GL_LIGHTING);
1598 glColor3fv (theEdgeColour->rgb);
1600 for (Tint i = 0; i < myPArray->num_vertexs; ++i)
1602 if (pv[i].xyz[0] < minp[0])
1603 minp[0] = pv[i].xyz[0];
1604 if (pv[i].xyz[1] < minp[1])
1605 minp[1] = pv[i].xyz[1];
1606 if (pv[i].xyz[2] < minp[2])
1607 minp[2] = pv[i].xyz[2];
1609 if (pv[i].xyz[0] > maxp[0])
1610 maxp[0] = pv[i].xyz[0];
1611 if (pv[i].xyz[1] > maxp[1])
1612 maxp[1] = pv[i].xyz[1];
1613 if (pv[i].xyz[2] > maxp[2])
1614 maxp[2] = pv[i].xyz[2];
1617 glBegin (GL_LINE_STRIP);
1620 glVertex3f (minp[0], maxp[1], minp[2]);
1621 glVertex3f (minp[0], maxp[1], maxp[2]);
1622 glVertex3f (minp[0], minp[1], maxp[2]);
1623 glVertex3f (minp[0], minp[1], minp[2]);
1625 glVertex3f (maxp[0], minp[1], minp[2]);
1626 glVertex3f (maxp[0], maxp[1], minp[2]);
1627 glVertex3f (maxp[0], maxp[1], maxp[2]);
1628 glVertex3f (maxp[0], minp[1], maxp[2]);
1629 glVertex3f (maxp[0], minp[1], minp[2]);
1631 glVertex3f (maxp[0], minp[1], maxp[2]);
1632 glVertex3f (minp[0], minp[1], maxp[2]);
1633 glVertex3f (minp[0], maxp[1], maxp[2]);
1635 glVertex3f (maxp[0], maxp[1], minp[2]);
1636 glVertex3f (minp[0], maxp[1], minp[2]);
1641 // =======================================================================
1642 // function : OpenGl_PrimitiveArray
1644 // =======================================================================
1645 OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
1646 : myPArray (thePArray),
1647 myDrawMode (DRAW_MODE_NONE)
1649 switch (myPArray->type)
1651 case TelPointsArrayType:
1652 myDrawMode = GL_POINTS;
1654 case TelPolylinesArrayType:
1655 myDrawMode = GL_LINE_STRIP;
1657 case TelSegmentsArrayType:
1658 myDrawMode = GL_LINES;
1660 case TelPolygonsArrayType:
1661 myDrawMode = GL_POLYGON;
1663 case TelTrianglesArrayType:
1664 myDrawMode = GL_TRIANGLES;
1666 case TelQuadranglesArrayType:
1667 myDrawMode = GL_QUADS;
1669 case TelTriangleStripsArrayType:
1670 myDrawMode = GL_TRIANGLE_STRIP;
1672 case TelQuadrangleStripsArrayType:
1673 myDrawMode = GL_QUAD_STRIP;
1675 case TelTriangleFansArrayType:
1676 myDrawMode = GL_TRIANGLE_FAN;
1681 // =======================================================================
1682 // function : ~OpenGl_PrimitiveArray
1684 // =======================================================================
1685 OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray ()
1687 if (myPArray == NULL)
1690 if (myPArray->VBOEnabled == VBO_OK)
1692 OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
1693 if (myPArray->bufferVBO[VBOEdges] != 0)
1694 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1695 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOEdges]));
1696 if (myPArray->bufferVBO[VBOVertices] != 0)
1697 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1698 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVertices]));
1699 if (myPArray->bufferVBO[VBOVcolours] != 0)
1700 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1701 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVcolours]));
1702 if (myPArray->bufferVBO[VBOVnormals] != 0)
1703 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1704 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVnormals]));
1705 if (myPArray->bufferVBO[VBOVtexels] != 0)
1706 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1707 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVtexels]));
1711 // =======================================================================
1712 // function : Render
1714 // =======================================================================
1715 void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
1717 if (myPArray == NULL || myDrawMode == DRAW_MODE_NONE)
1720 // create VBOs on first render call
1721 if (myPArray->VBOEnabled == -1) // special value for uninitialized state
1723 myPArray->VBOEnabled = OpenGl_GraphicDriver::ToUseVBO() && (theWorkspace->GetGlContext()->arbVBO != NULL);
1724 if (myPArray->VBOEnabled != 0)
1725 BuildVBO (theWorkspace);
1728 switch (myPArray->type)
1730 case TelPointsArrayType:
1731 case TelPolylinesArrayType:
1732 case TelSegmentsArrayType:
1734 glDisable (GL_LIGHTING);
1736 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1737 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
1738 theWorkspace->DegenerateModel)
1740 glDisable (GL_DEPTH_TEST);
1741 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1743 theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
1747 case TelPolygonsArrayType:
1748 case TelTrianglesArrayType:
1749 case TelQuadranglesArrayType:
1750 case TelTriangleStripsArrayType:
1751 case TelTriangleFansArrayType:
1752 case TelQuadrangleStripsArrayType:
1754 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1755 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
1756 theWorkspace->DegenerateModel < 2)
1758 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1760 glEnable (GL_DEPTH_TEST);
1761 theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
1769 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
1770 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
1772 Tint aFrontLightingModel = anAspectFace->Context().IntFront.color_mask;
1773 const TEL_COLOUR* anInteriorColor = &anAspectFace->Context().IntFront.matcol;
1774 const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
1775 const TEL_COLOUR* aLineColor = &anAspectLine->Color();
1777 // Use highlight colors
1778 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
1780 anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor;
1781 aFrontLightingModel = 0;
1784 DrawArray (aFrontLightingModel,
1785 anAspectFace->Context().InteriorStyle,
1786 anAspectFace->Context().Edge,
1790 &anAspectFace->Context().IntFront,
1793 switch (myPArray->type)
1795 case TelPointsArrayType:
1796 case TelPolylinesArrayType:
1797 case TelSegmentsArrayType:
1799 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)