0023000: Improve the way the gradient and textured background is managed in 3d viewer
[occt.git] / src / OpenGl / OpenGl_PrimitiveArray.cxx
CommitLineData
b311480e 1// Created on: 2011-07-13
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
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.
9//
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.
12//
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.
19
7fd59977 20
5f8b738e 21#include <OpenGl_ArbVBO.hxx>
22#include <OpenGl_Context.hxx>
23
2166f0fa 24#include <OpenGl_PrimitiveArray.hxx>
7fd59977 25
2166f0fa
SK
26#include <OpenGl_AspectFace.hxx>
27#include <OpenGl_GraphicDriver.hxx>
d4c2114a 28#include <OpenGl_ResourceCleaner.hxx>
29#include <OpenGl_ResourceVBO.hxx>
2166f0fa
SK
30#include <OpenGl_Structure.hxx>
31#include <OpenGl_TextureBox.hxx>
32
7fd59977 33#include <InterfaceGraphic_PrimitiveArray.hxx>
2166f0fa
SK
34
35enum
7fd59977 36{
2166f0fa
SK
37 VBO_NOT_INITIALIZED = -1,
38 VBO_ERROR = 0,
39 VBO_OK = 1
40};
41
42namespace
43{
44 static unsigned long vRand = 1L;
45 #define OGL_Rand() (vRand = vRand * 214013L + 2531011L)
46};
7fd59977 47
2166f0fa
SK
48// =======================================================================
49// function : clearMemoryOwn
50// purpose :
51// =======================================================================
52void OpenGl_PrimitiveArray::clearMemoryOwn() const
7fd59977 53{
2166f0fa
SK
54 if (myPArray->bufferVBO[VBOEdges] != 0)
55 {
56 Standard::Free ((Standard_Address& )myPArray->edges);
57 myPArray->edges = NULL;
7fd59977 58 }
2166f0fa
SK
59 if (myPArray->bufferVBO[VBOVertices] != 0)
60 {
61 Standard::Free ((Standard_Address& )myPArray->vertices);
62 myPArray->vertices = NULL;
7fd59977 63 }
2166f0fa
SK
64 if (myPArray->bufferVBO[VBOVcolours] != 0)
65 {
66 Standard::Free ((Standard_Address& )myPArray->vcolours);
67 myPArray->vcolours = NULL;
7fd59977 68 }
2166f0fa
SK
69 if (myPArray->bufferVBO[VBOVnormals] != 0)
70 {
71 Standard::Free ((Standard_Address& )myPArray->vnormals);
72 myPArray->vnormals = NULL;
73 }
74 if (myPArray->bufferVBO[VBOVtexels] != 0)
75 {
76 Standard::Free ((Standard_Address& )myPArray->vtexels);
77 myPArray->vtexels = NULL;
78 }
79 if (myPArray->edge_vis != NULL) /// ????
80 {
81 Standard::Free ((Standard_Address& )myPArray->edge_vis);
82 myPArray->edge_vis = NULL;
7fd59977 83 }
7fd59977 84}
85
2166f0fa
SK
86// =======================================================================
87// function : clearMemoryGL
88// purpose :
89// =======================================================================
90void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlContext) const
7fd59977 91{
2166f0fa
SK
92 if (myPArray->bufferVBO[VBOEdges] != 0)
93 {
94 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
95 }
96 if (myPArray->bufferVBO[VBOVertices] != 0)
97 {
98 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
99 }
100 if (myPArray->bufferVBO[VBOVcolours] != 0)
101 {
102 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
7fd59977 103 }
2166f0fa
SK
104 if (myPArray->bufferVBO[VBOVnormals] != 0)
105 {
106 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
107 }
108 if (myPArray->bufferVBO[VBOVtexels] != 0)
109 {
110 theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
111 }
5f8b738e 112 theGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
113 theGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
7fd59977 114}
115
2166f0fa
SK
116// =======================================================================
117// function : checkSizeForGraphicMemory
118// purpose :
119// =======================================================================
120Standard_Boolean OpenGl_PrimitiveArray::checkSizeForGraphicMemory (const Handle(OpenGl_Context)& theGlContext) const
7fd59977 121{
2166f0fa
SK
122 if (glGetError() == GL_OUT_OF_MEMORY)
123 {
124 myPArray->flagBufferVBO = VBO_ERROR;
125 clearMemoryGL (theGlContext);
126 }
127 else
128 {
129 myPArray->flagBufferVBO = VBO_OK;
130 }
131 return myPArray->flagBufferVBO == VBO_OK;
7fd59977 132}
133
2166f0fa
SK
134// =======================================================================
135// function : BuildVBO
136// purpose :
137// =======================================================================
138Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
7fd59977 139{
140 int size_reqd = 0;
2166f0fa
SK
141 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
142 if (myPArray->edges != NULL)
143 {
144 size_reqd = myPArray->num_edges * sizeof(Tint);
145 aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
5f8b738e 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);
2166f0fa
SK
148 if (!checkSizeForGraphicMemory (aGlContext))
149 return Standard_False;
7fd59977 150 }
151
2166f0fa
SK
152 if (myPArray->vertices != NULL)
153 {
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;
7fd59977 160 }
161
2166f0fa
SK
162 if (myPArray->vcolours != NULL)
163 {
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;
7fd59977 170 }
171
2166f0fa
SK
172 if (myPArray->vnormals != NULL)
173 {
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;
7fd59977 180 }
181
2166f0fa
SK
182 if (myPArray->vtexels)
183 {
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;
190 }
7fd59977 191
2166f0fa
SK
192 if (myPArray->flagBufferVBO == VBO_OK)
193 clearMemoryOwn();
7fd59977 194
2166f0fa
SK
195 // specify context for VBO resource
196 myPArray->contextId = (Standard_Address )theWorkspace->GetGContext();
197 return Standard_True;
7fd59977 198}
199
2166f0fa
SK
200// =======================================================================
201// function : DrawArrays
202// purpose : Auxiliary method to split Feedback/Normal rendering modes
203// =======================================================================
204inline void DrawArrays (const Handle(OpenGl_Workspace)& theWorkspace,
205 const CALL_DEF_PARRAY* thePArray,
206 const Standard_Boolean theIsFeedback,
207 GLenum theMode,
208 GLint theFirst,
209 GLsizei theCount)
7fd59977 210{
2166f0fa
SK
211 if (!theIsFeedback)
212 {
213 glDrawArrays (theMode, theFirst, theCount);
214 return;
215 }
7fd59977 216
2166f0fa
SK
217 glBegin (theMode);
218 for (int anIter = theFirst; anIter < (theFirst + theCount); ++anIter)
219 {
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]);
228 }
229 glEnd();
7fd59977 230}
231
2166f0fa
SK
232// =======================================================================
233// function : DrawElements
234// purpose : Auxiliary method to split Feedback/Normal rendering modes
235// =======================================================================
236inline void DrawElements (const Handle(OpenGl_Workspace)& theWorkspace,
237 const CALL_DEF_PARRAY* thePArray,
238 const Standard_Boolean theIsFeedback,
239 GLenum theMode,
240 GLsizei theCount,
241 GLenum* theIndices)
7fd59977 242{
2166f0fa
SK
243 if (!theIsFeedback)
244 {
245 glDrawElements (theMode, theCount, GL_UNSIGNED_INT, theIndices);
246 return;
7fd59977 247 }
248
2166f0fa
SK
249 GLenum anIndex;
250 glBegin (theMode);
251 for (GLsizei anIter = 0; anIter < theCount; ++anIter)
252 {
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]);
7fd59977 262 }
263 glEnd();
264}
265
2166f0fa
SK
266// =======================================================================
267// function : DrawArray
268// purpose :
269// =======================================================================
270void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
271 const Aspect_InteriorStyle theInteriorStyle,
272 Tint theEdgeFlag,
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
7fd59977 278{
2166f0fa
SK
279 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
280
7fd59977 281 Tint i,n;
282 Tint transp = 0;
283 GLint renderMode;
2166f0fa
SK
284 // Following pointers have been provided for performance improvement
285 tel_colour pfc = myPArray->fcolours;
286 Tint* pvc = myPArray->vcolours;
287 if (pvc != NULL)
288 {
289 for (i = 0; i < myPArray->num_vertexs; ++i)
290 {
291 transp = int(theFaceProp->trans * 255.0f);
292 #if defined (sparc) || defined (__sparc__) || defined (__sparc)
293 pvc[i] = (pvc[i] & 0xffffff00);
294 pvc[i] += transp;
295 #else
296 pvc[i] = (pvc[i] & 0x00ffffff);
7fd59977 297 pvc[i] += transp << 24;
2166f0fa 298 #endif
7fd59977 299 }
300 }
7fd59977 301
2166f0fa
SK
302 switch (myPArray->type)
303 {
7fd59977 304 case TelPointsArrayType:
7fd59977 305 case TelPolylinesArrayType:
7fd59977 306 case TelSegmentsArrayType:
2166f0fa 307 glColor3fv (theLineColour->rgb);
7fd59977 308 break;
309 case TelPolygonsArrayType:
7fd59977 310 case TelTrianglesArrayType:
7fd59977 311 case TelQuadranglesArrayType:
7fd59977 312 case TelTriangleStripsArrayType:
7fd59977 313 case TelQuadrangleStripsArrayType:
7fd59977 314 case TelTriangleFansArrayType:
2166f0fa 315 glColor3fv (theInteriorColour->rgb);
7fd59977 316 break;
7fd59977 317 }
318
2166f0fa
SK
319 // Temporarily disable environment mapping
320 if (myDrawMode <= GL_LINE_STRIP)
321 {
322 glPushAttrib (GL_ENABLE_BIT);
323 glDisable (GL_TEXTURE_1D);
324 glDisable (GL_TEXTURE_2D);
7fd59977 325 }
326
2166f0fa
SK
327 if (theWorkspace->DegenerateModel < 2 &&
328 ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
329 (myDrawMode <= GL_LINE_STRIP)))
330 {
331 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
332 {
7fd59977 333 pfc = NULL;
334 pvc = NULL;
335 }
336
2166f0fa
SK
337 if (theInteriorStyle == Aspect_IS_HIDDENLINE)
338 {
339 theEdgeFlag = 1;
7fd59977 340 pfc = NULL;
341 pvc = NULL;
342 }
343
2166f0fa
SK
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);
349 else
350 glEnable (GL_LIGHTING);
351
352 glGetIntegerv (GL_RENDER_MODE, &renderMode);
353
354 if (myPArray->num_vertexs > 0
355 && myPArray->flagBufferVBO != VBO_OK
356 && renderMode != GL_FEEDBACK)
357 {
358 if (myPArray->vertices != NULL)
359 {
360 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
361 glEnableClientState (GL_VERTEX_ARRAY);
362 }
363 if (myPArray->vnormals != NULL)
364 {
365 glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
366 glEnableClientState (GL_NORMAL_ARRAY);
367 }
368 if (myPArray->vtexels != NULL)
369 {
370 glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
371 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
372 }
7fd59977 373
2166f0fa
SK
374 if (pvc != NULL)
375 {
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);
7fd59977 380 }
381 }
2166f0fa
SK
382 else if (myPArray->num_vertexs > 0
383 && myPArray->flagBufferVBO == VBO_OK)
384 {
385 // Bindings concrete pointer in accordance with VBO buffer
386 if (myPArray->bufferVBO[VBOVertices] != 0)
387 {
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);
7fd59977 391 }
2166f0fa
SK
392 if (myPArray->bufferVBO[VBOVnormals] != 0)
393 {
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);
7fd59977 397 }
2166f0fa
SK
398 if (myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
399 {
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);
7fd59977 403 }
2166f0fa
SK
404 if (myPArray->bufferVBO[VBOVcolours] != 0)
405 {
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);
7fd59977 411 }
412 }
2166f0fa 413
7fd59977 414 // OCC22236 NOTE: draw for all situations:
2166f0fa 415 // 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
7fd59977 416 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
762aacae 417 // 3) draw primitive by vertexes if no edges and bounds array is specified
2166f0fa
SK
418 if (myPArray->flagBufferVBO == VBO_OK)
419 {
420 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges] != 0)
421 {
5f8b738e 422 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]); // for edge indices
2166f0fa
SK
423 if (myPArray->num_bounds > 0)
424 {
425 // draw primitives by vertex count with the indicies
426 Tint* anOffset = NULL;
427 for (i = 0; i < myPArray->num_bounds; ++i)
428 {
429 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, anOffset);
430 anOffset += myPArray->bounds[i];
762aacae
A
431 }
432 }
2166f0fa
SK
433 else
434 {
435 // draw one (or sequential) primitive by the indicies
436 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
762aacae 437 }
7fd59977 438 }
2166f0fa
SK
439 else if (myPArray->num_bounds > 0)
440 {
441 for (i = n = 0; i < myPArray->num_bounds; ++i)
442 {
443 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
444 n += myPArray->bounds[i];
7fd59977 445 }
446 }
2166f0fa
SK
447 else
448 {
449 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
762aacae
A
450 }
451
2166f0fa
SK
452 // bind with 0
453 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
5f8b738e 454 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
7fd59977 455 }
2166f0fa
SK
456 else
457 {
458 if (myPArray->num_bounds > 0)
459 {
460 if (myPArray->num_edges > 0)
461 {
462 for (i = n = 0; i < myPArray->num_bounds; ++i)
463 {
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];
468 }
469 }
470 else
471 {
472 for (i = n = 0; i < myPArray->num_bounds; ++i)
473 {
474 if (pfc != NULL)
475 {
476 glColor3fv (pfc[i].rgb);
7fd59977 477 }
2166f0fa
SK
478 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
479 n, myPArray->bounds[i]);
480 n += myPArray->bounds[i];
481 }
7fd59977 482 }
2166f0fa
SK
483 }
484 else if (myPArray->num_edges > 0)
485 {
486 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
487 myPArray->num_edges, (GLenum* )myPArray->edges);
488 }
489 else
490 {
491 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
492 0, myPArray->num_vertexs);
493 }
7fd59977 494 }
495
2166f0fa
SK
496 if (myPArray->bufferVBO[VBOVcolours] != 0 || pvc != NULL)
497 {
498 glDisable (GL_COLOR_MATERIAL);
499 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
7fd59977 500 }
2166f0fa
SK
501
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);
510
511 if (theWorkspace->DegenerateModel)
512 {
513 if (myDrawMode <= GL_LINE_STRIP)
514 {
7fd59977 515 glPopAttrib();
2166f0fa 516 }
7fd59977 517 return;
518 }
519 }
520
2166f0fa
SK
521 if (theEdgeFlag || theWorkspace->DegenerateModel)
522 {
523 switch (theWorkspace->DegenerateModel)
524 {
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.
2bd4c032 534 if (myDrawMode > GL_LINE_STRIP)
535 {
536 DrawEdges (theEdgeFlag ? theEdgeColour : theInteriorColour, theWorkspace);
537 }
2166f0fa
SK
538 break;
539 // DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
540 case 2: // XXX_TDM_WIREFRAME
541 if (myPArray->VBOEnabled == 0)
542 DrawDegeneratesAsLines ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace);
543 break;
544 case 3: // XXX_TDM_MARKER
545 if (myPArray->VBOEnabled == 0)
546 DrawDegeneratesAsPoints ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace->SkipRatio);
7fd59977 547 break;
2166f0fa
SK
548 case 4: // XXX_TDM_BBOX
549 if (myPArray->VBOEnabled == 0)
550 DrawDegeneratesAsBBoxs (theEdgeFlag ? theEdgeColour : theInteriorColour);
551 break;
552 }
553 }
554
555 if (myDrawMode <= GL_LINE_STRIP)
7fd59977 556 glPopAttrib();
557}
558
2166f0fa
SK
559// =======================================================================
560// function : DrawEdges
561// purpose :
562// =======================================================================
563void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour,
564 const Handle(OpenGl_Workspace)& theWorkspace) const
7fd59977 565{
2166f0fa 566 glDisable (GL_LIGHTING);
7fd59977 567
2166f0fa
SK
568 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
569 const OpenGl_AspectLine* anAspectLineOld = NULL;
570 if (myDrawMode > GL_LINE_STRIP)
571 {
572 anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
573 theWorkspace->AspectLine (Standard_True);
7fd59977 574
2166f0fa
SK
575 glPushAttrib (GL_POLYGON_BIT);
576 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
577 }
7fd59977 578
2166f0fa 579 Tint i, j, n;
7fd59977 580 GLint renderMode;
7fd59977 581
582 // OCC22236 NOTE: draw edges for all situations:
2166f0fa 583 // 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
762aacae
A
584 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
585 // 3) draw primitive's edges by vertexes if no edges and bounds array is specified
2166f0fa 586 if (myPArray->flagBufferVBO == VBO_OK)
7fd59977 587 {
2166f0fa
SK
588 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
589 glEnableClientState (GL_VERTEX_ARRAY);
590 glColor3fv (theEdgeColour->rgb);
591 if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges])
592 {
5f8b738e 593 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
2166f0fa 594
762aacae 595 // draw primitives by vertex count with the indicies
2166f0fa
SK
596 if (myPArray->num_bounds > 0)
597 {
762aacae 598 Tint* offset = 0;
2166f0fa
SK
599 for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
600 {
601 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, offset);
602 offset += myPArray->bounds[i];
762aacae
A
603 }
604 }
605 // draw one (or sequential) primitive by the indicies
2166f0fa
SK
606 else
607 {
608 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
762aacae 609 }
7fd59977 610 }
2166f0fa
SK
611 else if (myPArray->num_bounds > 0)
612 {
613 for (i = n = 0; i < myPArray->num_bounds; ++i)
614 {
615 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
616 n += myPArray->bounds[i];
7fd59977 617 }
618 }
2166f0fa
SK
619 else
620 {
621 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
762aacae
A
622 }
623
624 // unbind buffers
2166f0fa
SK
625 glDisableClientState (GL_VERTEX_ARRAY);
626 aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
5f8b738e 627 aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
2166f0fa
SK
628 }
629 else
630 {
631 glEnableClientState (GL_VERTEX_ARRAY);
632 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
633 glGetIntegerv (GL_RENDER_MODE, &renderMode);
634
635 glColor3fv (theEdgeColour->rgb);
636 if (myPArray->num_bounds > 0)
637 {
638 if (myPArray->num_edges > 0)
639 {
640 for (i = n = 0; i < myPArray->num_bounds; ++i)
641 {
642 if (myPArray->edge_vis)
643 {
644 glBegin (myDrawMode);
645 for (j = 0; j < myPArray->bounds[i]; ++j)
646 {
647 glEdgeFlag (myPArray->edge_vis[n+j]);
648 glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
649 }
650 glEnd();
7fd59977 651 }
2166f0fa
SK
652 else
653 {
654 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
655 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
7fd59977 656 }
2166f0fa 657 n += myPArray->bounds[i];
7fd59977 658 }
2166f0fa 659 }
7fd59977 660 else
2166f0fa
SK
661 {
662 for (i = n = 0 ; i < myPArray->num_bounds; ++i)
663 {
664 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
665 n, myPArray->bounds[i]);
666 n += myPArray->bounds[i];
667 }
668 }
669 }
670 else if (myPArray->num_edges > 0)
671 {
672 if (myPArray->edge_vis)
673 {
674 glBegin (myDrawMode);
675 for (i = 0; i < myPArray->num_edges; ++i)
676 {
677 glEdgeFlag (myPArray->edge_vis[i]);
678 glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
679 }
680 glEnd();
681 }
7fd59977 682 else
2166f0fa
SK
683 {
684 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
685 myPArray->num_edges, (GLenum* )myPArray->edges);
7fd59977 686 }
687 }
2166f0fa
SK
688 else
689 {
690 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
691 0, myPArray->num_vertexs);
7fd59977 692 }
2166f0fa
SK
693 }
694
695 if (myDrawMode > GL_LINE_STRIP)
696 {
697 // Restore line context
698 theWorkspace->SetAspectLine (anAspectLineOld);
7fd59977 699 glPopAttrib();
700 }
701}
702
2166f0fa
SK
703// =======================================================================
704// function : DrawDegeneratesPointsAsPoints
705// purpose :
706// =======================================================================
707void OpenGl_PrimitiveArray::DrawDegeneratesPointsAsPoints() const
708{
709 tel_point pv = myPArray->vertices;
710 for (Tint aVertId = 0; aVertId < myPArray->num_vertexs; ++aVertId)
711 {
712 glVertex3fv (&pv[aVertId].xyz[0]);
7fd59977 713 }
2166f0fa 714}
7fd59977 715
2166f0fa
SK
716// =======================================================================
717// function : DrawDegeneratesLinesAsPoints
718// purpose :
719// =======================================================================
720void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsPoints() const
721{
722 GLfloat pt[3];
723 tel_point pv = myPArray->vertices;
724
725 Tint j = 0;
726 while (j < myPArray->num_vertexs)
727 {
728 pt[0] = pv[j].xyz[0];
729 pt[1] = pv[j].xyz[1];
730 pt[2] = pv[j].xyz[2]; ++j;
731 pt[0] += pv[j].xyz[0];
732 pt[1] += pv[j].xyz[1];
733 pt[2] += pv[j].xyz[2]; ++j;
734 pt[0] *= 0.5f;
735 pt[1] *= 0.5f;
736 pt[2] *= 0.5f;
737 glVertex3fv (pt);
7fd59977 738 }
739}
740
2166f0fa
SK
741// =======================================================================
742// function : DrawDegeneratesTrianglesAsPoints
743// purpose :
744// =======================================================================
745void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsPoints() const
746{
747 Tint i, j, iv;
748 GLfloat pt[ 3 ];
749 tel_point pv = myPArray->vertices;
750
751 if (myPArray->num_edges > 0)
752 {
753 for (j = 0; j < myPArray->num_edges; j += 3)
754 {
755 iv = myPArray->edges[j];
756 pt[0] = pv[iv].xyz[0];
757 pt[1] = pv[iv].xyz[1];
758 pt[2] = pv[iv].xyz[2];
759 for (i = 1; i < 3; ++i)
760 {
761 iv = myPArray->edges[j+i];
762 pt[0] += pv[iv].xyz[0];
763 pt[1] += pv[iv].xyz[1];
764 pt[2] += pv[iv].xyz[2];
7fd59977 765 }
2166f0fa
SK
766 pt[0] /= 3.f;
767 pt[1] /= 3.f;
768 pt[2] /= 3.f;
769 glVertex3fv (pt);
7fd59977 770 }
2166f0fa
SK
771 }
772 else
773 {
774 for (j = 0; j < myPArray->num_vertexs; j += 3)
775 {
776 pt[0] = pv[j].xyz[0];
777 pt[1] = pv[j].xyz[1];
778 pt[2] = pv[j].xyz[2];
779 for (i = 1; i < 3; ++i)
780 {
781 pt[0] += pv[j+i].xyz[0];
782 pt[1] += pv[j+i].xyz[1];
783 pt[2] += pv[j+i].xyz[2];
7fd59977 784 }
2166f0fa
SK
785 pt[0] /= 3.f;
786 pt[1] /= 3.f;
787 pt[2] /= 3.f;
788 glVertex3fv (pt);
7fd59977 789 }
790 }
2166f0fa 791}
7fd59977 792
2166f0fa
SK
793// =======================================================================
794// function : DrawDegeneratesTrianglesAsPoints
795// purpose :
796// =======================================================================
797void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsPoints() const
798{
799 Tint i, j, k, n;
800 GLfloat pt[ 3 ];
801 tel_point pv = myPArray->vertices;
802
803 if (myPArray->num_bounds > 0)
804 {
805 for (k = n = 0; k < myPArray->num_bounds; ++k)
806 {
807 for (j = 0; j < myPArray->bounds[k] - 2; ++j)
808 {
809 pt[0] = pv[n+j].xyz[0];
810 pt[1] = pv[n+j].xyz[1];
811 pt[2] = pv[n+j].xyz[2];
812 for (i = 1; i < 3; ++i)
813 {
814 pt[0] += pv[n+j+i].xyz[0];
815 pt[1] += pv[n+j+i].xyz[1];
816 pt[2] += pv[n+j+i].xyz[2];
7fd59977 817 }
2166f0fa
SK
818 pt[0] /= 3.f;
819 pt[1] /= 3.f;
820 pt[2] /= 3.f;
821 glVertex3fv (pt);
7fd59977 822 }
2166f0fa 823 n += myPArray->bounds[k];
7fd59977 824 }
2166f0fa
SK
825 }
826 else
827 {
828 for (j = 0; j < myPArray->num_vertexs - 2; ++j)
829 {
830 pt[0] = pv[j].xyz[0];
831 pt[1] = pv[j].xyz[1];
832 pt[2] = pv[j].xyz[2];
833 for (i = 1; i < 3; ++i)
834 {
835 pt[0] += pv[j+i].xyz[0];
836 pt[1] += pv[j+i].xyz[1];
837 pt[2] += pv[j+i].xyz[2];
7fd59977 838 }
2166f0fa
SK
839 pt[0] /= 3.f;
840 pt[1] /= 3.f;
841 pt[2] /= 3.f;
842 glVertex3fv (pt);
7fd59977 843 }
844 }
2166f0fa 845}
7fd59977 846
2166f0fa
SK
847// =======================================================================
848// function : DrawDegeneratesPolygonsAsPoints
849// purpose :
850// =======================================================================
851void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsPoints() const
852{
853 Tint j, k, n, iv;
854 GLfloat pt[3];
855 tel_point pv = myPArray->vertices;
856
857 if (myPArray->num_bounds > 0)
858 {
859 if (myPArray->num_edges > 0)
860 {
861 for (k = n = 0; k < myPArray->num_bounds; ++k)
862 {
863 pt[0] = pt[1] = pt[2] = 0.0;
864 for (j = 0; j < myPArray->bounds[k]; ++j)
865 {
866 iv = myPArray->edges[n+j];
867 pt[0] += pv[iv].xyz[0];
868 pt[1] += pv[iv].xyz[1];
869 pt[2] += pv[iv].xyz[2];
7fd59977 870 }
2166f0fa
SK
871 pt[0] /= myPArray->bounds[k];
872 pt[1] /= myPArray->bounds[k];
873 pt[2] /= myPArray->bounds[k];
874 glVertex3fv (pt);
875 n += myPArray->bounds[k];
7fd59977 876 }
2166f0fa
SK
877 }
878 else
879 {
880 for (k = n = 0; k < myPArray->num_bounds; ++k)
881 {
882 pt[0] = pt[1] = pt[2] = 0.0;
883 for (j = 0; j < myPArray->bounds[k]; ++j)
884 {
885 pt[0] += pv[n+j].xyz[0];
886 pt[1] += pv[n+j].xyz[1];
887 pt[2] += pv[n+j].xyz[2];
7fd59977 888 }
2166f0fa
SK
889 pt[0] /= myPArray->bounds[k];
890 pt[1] /= myPArray->bounds[k];
891 pt[2] /= myPArray->bounds[k];
892 glVertex3fv (pt);
893 n += myPArray->bounds[k];
7fd59977 894 }
895 }
2166f0fa
SK
896 }
897 else if (myPArray->num_edges > 0)
898 {
899 pt[0] = pt[1] = pt[2] = 0.0;
900 for (j = 0; j < myPArray->num_edges; ++j)
901 {
902 iv = myPArray->edges[j];
903 pt[0] += pv[iv].xyz[0];
904 pt[1] += pv[iv].xyz[1];
905 pt[2] += pv[iv].xyz[2];
7fd59977 906 }
2166f0fa
SK
907 pt[0] /= myPArray->num_edges;
908 pt[1] /= myPArray->num_edges;
909 pt[2] /= myPArray->num_edges;
910 glVertex3fv (pt);
911 }
912 else
913 {
914 pt[0] = pt[1] = pt[2] = 0.0;
915 for (j = 0; j < myPArray->num_vertexs; ++j)
916 {
917 pt[0] += pv[j].xyz[0];
918 pt[1] += pv[j].xyz[1];
919 pt[2] += pv[j].xyz[2];
7fd59977 920 }
2166f0fa
SK
921 pt[0] /= myPArray->num_vertexs;
922 pt[1] /= myPArray->num_vertexs;
923 pt[2] /= myPArray->num_vertexs;
924 glVertex3fv (pt);
7fd59977 925 }
2166f0fa 926}
7fd59977 927
2166f0fa
SK
928// =======================================================================
929// function : DrawDegeneratesQuadranglesAsPoints
930// purpose :
931// =======================================================================
932void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsPoints() const
933{
934 Tint i, j, iv;
935 GLfloat pt[ 3 ];
936 tel_point pv = myPArray->vertices;
937
938 if (myPArray->num_edges > 0)
939 {
940 for (j = 0; j < myPArray->num_edges; j += 4)
941 {
942 pt[0] = pt[1] = pt[2] = 0.0;
943 for (i = 0; i < 4; ++i)
944 {
945 iv = myPArray->edges[j+i];
946 pt[0] += pv[iv].xyz[0];
947 pt[1] += pv[iv].xyz[1];
948 pt[2] += pv[iv].xyz[2];
7fd59977 949 }
2166f0fa
SK
950 pt[0] /= 4;
951 pt[1] /= 4;
952 pt[2] /= 4;
7fd59977 953 glVertex3fv ( pt );
954 }
2166f0fa
SK
955 }
956 else
957 {
958 for (j = 0; j < myPArray->num_vertexs; j += 4)
959 {
960 pt[0] = pt[1] = pt[2] = 0.0;
961 for (i = 0; i < 4; ++i)
962 {
963 pt[0] += pv[j+i].xyz[0];
964 pt[1] += pv[j+i].xyz[1];
965 pt[2] += pv[j+i].xyz[2];
7fd59977 966 }
2166f0fa
SK
967 pt[0] /= 4;
968 pt[1] /= 4;
969 pt[2] /= 4;
970 glVertex3fv (pt);
7fd59977 971 }
972 }
973}
974
2166f0fa
SK
975// =======================================================================
976// function : DrawDegeneratesAsPoints
977// purpose :
978// =======================================================================
979void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsPoints() const
980{
981 Tint i, j, k, n;
982 GLfloat pt[3];
983 tel_point pv = myPArray->vertices;
984
985 if (myPArray->num_bounds > 0)
986 {
987 for (k = n = 0; k < myPArray->num_bounds; ++k)
988 {
989 for (j = 0; j < myPArray->bounds[k] - 2; j += 2)
990 {
7fd59977 991 pt[0] = pt[1] = pt[2] = 0.;
2166f0fa
SK
992 for (i = 0; i < 4; ++i)
993 {
994 pt[0] += pv[n+j+i].xyz[0];
995 pt[1] += pv[n+j+i].xyz[1];
996 pt[2] += pv[n+j+i].xyz[2];
7fd59977 997 }
2166f0fa
SK
998 pt[0] /= 4;
999 pt[1] /= 4;
1000 pt[2] /= 4;
1001 glVertex3fv (pt);
7fd59977 1002 }
2166f0fa 1003 n += myPArray->bounds[k];
7fd59977 1004 }
2166f0fa
SK
1005 }
1006 else
1007 {
1008 for (j = 0; j < myPArray->num_vertexs - 2; j += 2)
1009 {
7fd59977 1010 pt[0] = pt[1] = pt[2] = 0.;
2166f0fa
SK
1011 for (i = 0; i < 4; ++i)
1012 {
1013 pt[0] += pv[j+i].xyz[0];
1014 pt[1] += pv[j+i].xyz[1];
1015 pt[2] += pv[j+i].xyz[2];
7fd59977 1016 }
2166f0fa
SK
1017 pt[0] /= 4;
1018 pt[1] /= 4;
1019 pt[2] /= 4;
1020 glVertex3fv (pt);
7fd59977 1021 }
1022 }
2166f0fa 1023}
7fd59977 1024
2166f0fa
SK
1025// =======================================================================
1026// function : DrawDegeneratesAsPoints
1027// purpose :
1028// =======================================================================
1029void OpenGl_PrimitiveArray::DrawDegeneratesAsPoints (const TEL_COLOUR* theEdgeColour,
1030 const float theSkipRatio) const
7fd59977 1031{
2166f0fa
SK
1032 if (theSkipRatio >= 1.0f)
1033 return;
7fd59977 1034
2166f0fa
SK
1035 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
1036 glDisable (GL_LIGHTING);
1037 if (zbuff_state)
1038 glDisable (GL_DEPTH_TEST);
1039 glColor3fv (theEdgeColour->rgb);
1040
1041 glBegin (GL_POINTS);
1042 switch (myDrawMode)
1043 {
1044 case GL_POINTS:
1045 DrawDegeneratesPointsAsPoints();
1046 break;
1047 case GL_LINES:
1048 DrawDegeneratesLinesAsPoints();
1049 break;
1050 case GL_LINE_STRIP:
1051 case GL_POLYGON:
1052 DrawDegeneratesPolygonsAsPoints();
1053 break;
1054 case GL_TRIANGLES:
1055 DrawDegeneratesTrianglesAsPoints();
1056 break;
1057 case GL_QUADS:
1058 DrawDegeneratesQuadranglesAsPoints();
1059 break;
1060 case GL_TRIANGLE_FAN:
1061 case GL_TRIANGLE_STRIP:
1062 DrawDegeneratesTrianglestripsAsPoints();
1063 break;
1064 case GL_QUAD_STRIP:
1065 DrawDegeneratesQuadranglestripsAsPoints();
1066 break;
1067 default:
1068 break;
7fd59977 1069 }
2166f0fa
SK
1070 glEnd();
1071 if (zbuff_state)
1072 glEnable (GL_DEPTH_TEST);
7fd59977 1073}
1074
2166f0fa
SK
1075// =======================================================================
1076// function : DrawDegeneratesLinesAsLines
1077// purpose :
1078// =======================================================================
1079void OpenGl_PrimitiveArray::DrawDegeneratesLinesAsLines (const float theSkipRatio) const
1080{
1081 Tint i, iv;
1082 tel_point pv = myPArray->vertices;
7fd59977 1083
2166f0fa
SK
1084 Tint n = myPArray->num_vertexs;
1085 Tint j = int((1.0f - theSkipRatio) * n);
1086 for (; j > 0; --j)
1087 {
7fd59977 1088 i = OGL_Rand() % n;
2166f0fa
SK
1089 myPArray->keys[i] = -myPArray->keys[i];
1090 }
1091
1092 if (myPArray->num_bounds > 0)
1093 {
1094 if (myPArray->num_edges > 0)
1095 {
1096 for (i = n = 0; i < myPArray->num_bounds; ++i)
1097 {
1098 glBegin (GL_LINES);
1099 for (j = 0; j < myPArray->bounds[i]; ++j)
1100 {
1101 iv = myPArray->edges[n + j];
1102 if (myPArray->keys[iv] < 0)
1103 {
1104 myPArray->keys[iv] = -myPArray->keys[iv];
1105 glVertex3fv (pv[iv].xyz);
7fd59977 1106 }
1107 }
1108 glEnd();
2166f0fa 1109 n += myPArray->bounds[i];
7fd59977 1110 }
2166f0fa
SK
1111 }
1112 else
1113 {
1114 for (i = n = 0; i < myPArray->num_bounds; ++i)
1115 {
1116 glBegin (GL_LINES);
1117 for (j = 0; j < myPArray->bounds[i]; ++j)
1118 {
1119 if (myPArray->keys[n+j] < 0)
1120 {
1121 myPArray->keys[n+j] = -myPArray->keys[n+j];
1122 glVertex3fv (pv[n+j].xyz);
7fd59977 1123 }
1124 }
1125 glEnd();
2166f0fa 1126 n += myPArray->bounds[i];
7fd59977 1127 }
1128 }
2166f0fa
SK
1129 }
1130 else if (myPArray->num_edges > 0)
1131 {
1132 glBegin (GL_LINES);
1133 for (j = 0; j < myPArray->num_edges; ++j)
1134 {
1135 iv = myPArray->edges[j];
1136 if (myPArray->keys[iv] < 0)
1137 {
1138 myPArray->keys[iv] = -myPArray->keys[iv];
1139 glVertex3fv (pv[iv].xyz);
7fd59977 1140 }
1141 }
1142 glEnd();
2166f0fa
SK
1143 }
1144 else
1145 {
1146 glBegin (GL_LINES);
1147 for (j = 0; j < myPArray->num_vertexs; ++j)
1148 {
1149 if (myPArray->keys[j] < 0)
1150 {
1151 myPArray->keys[j] = -myPArray->keys[j];
1152 glVertex3fv (pv[j].xyz);
7fd59977 1153 }
1154 }
1155 glEnd();
1156 }
2166f0fa 1157}
7fd59977 1158
2166f0fa
SK
1159// =======================================================================
1160// function : DrawDegeneratesTrianglesAsLines
1161// purpose :
1162// =======================================================================
1163void OpenGl_PrimitiveArray::DrawDegeneratesTrianglesAsLines (const float theSkipRatio) const
7fd59977 1164{
2166f0fa
SK
1165 Tint i, iv;
1166 tel_point pv = myPArray->vertices;
7fd59977 1167
2166f0fa
SK
1168 Tint n = myPArray->num_vertexs / 3;
1169 Tint j = int((1.0f - theSkipRatio) * n);
1170 for (; j > 0; --j)
1171 {
7fd59977 1172 i = OGL_Rand() % n; i *= 3;
2166f0fa
SK
1173 myPArray->keys[i] = -myPArray->keys[i];
1174 }
1175
1176 if (myPArray->num_edges > 0)
1177 {
1178 for (j = 0; j < myPArray->num_edges; j += 3)
1179 {
1180 iv = myPArray->edges[j];
1181 if (myPArray->keys[iv] < 0)
1182 {
1183 myPArray->keys[iv] = -myPArray->keys[iv];
1184 glBegin (GL_LINE_LOOP);
1185 for (i = 0; i < 3; ++i)
1186 {
1187 iv = myPArray->edges[j+i];
1188 glVertex3fv (pv[iv].xyz);
7fd59977 1189 }
1190 glEnd();
1191 }
1192 }
2166f0fa
SK
1193 }
1194 else
1195 {
1196 for (j = 0; j < myPArray->num_vertexs; j += 3)
1197 {
1198 if (myPArray->keys[j] < 0)
1199 {
1200 myPArray->keys[j] = -myPArray->keys[j];
1201 glBegin (GL_LINE_LOOP);
1202 for (i = 0; i < 3; ++i)
1203 {
1204 glVertex3fv (pv[j+i].xyz);
7fd59977 1205 }
1206 glEnd();
1207 }
1208 }
1209 }
2166f0fa 1210}
7fd59977 1211
2166f0fa
SK
1212// =======================================================================
1213// function : DrawDegeneratesTrianglesAsLines
1214// purpose :
1215// =======================================================================
1216void OpenGl_PrimitiveArray::DrawDegeneratesTrianglestripsAsLines (const float theSkipRatio) const
7fd59977 1217{
2166f0fa
SK
1218 Tint i, j, k, n, ni;
1219 tel_point pv = myPArray->vertices;
1220
1221 if (myPArray->num_bounds > 0)
1222 {
1223 for (i = n = 0; i < myPArray->num_bounds; ++i)
1224 {
1225 ni = myPArray->bounds[i] - 2;
1226 k = int((1.0f - theSkipRatio) * ni);
1227 for (; k > 0; --k)
1228 {
7fd59977 1229 j = OGL_Rand() % ni; j += 2;
2166f0fa
SK
1230 myPArray->keys[n+j] = -myPArray->keys[n+j];
1231 }
1232 for (j = 2; j < myPArray->bounds[i]; ++j)
1233 {
1234 if (myPArray->keys[n+j] < 0)
1235 {
1236 myPArray->keys[n+j] = -myPArray->keys[n+j];
1237 glBegin (GL_LINE_LOOP);
1238 glVertex3fv (pv[n+j-2].xyz);
1239 glVertex3fv (pv[n+j-1].xyz);
1240 glVertex3fv (pv[n+j].xyz);
7fd59977 1241 glEnd();
1242 }
1243 }
2166f0fa 1244 n += myPArray->bounds[i];
7fd59977 1245 }
2166f0fa
SK
1246 }
1247 else
1248 {
1249 ni = myPArray->num_vertexs - 2;
1250 k = int((1.0f - theSkipRatio) * ni);
1251 for (; k > 0; --k)
1252 {
7fd59977 1253 j = OGL_Rand() % ni; j += 2;
2166f0fa
SK
1254 myPArray->keys[j] = -myPArray->keys[j];
1255 }
1256 for (j = 2; j < myPArray->num_vertexs; ++j)
1257 {
1258 if (myPArray->keys[j] < 0)
1259 {
1260 myPArray->keys[j] = -myPArray->keys[j];
1261 glBegin (GL_LINE_LOOP);
1262 glVertex3fv (pv[j-2].xyz);
1263 glVertex3fv (pv[j-1].xyz);
1264 glVertex3fv (pv[j].xyz);
7fd59977 1265 glEnd();
1266 }
1267 }
1268 }
2166f0fa 1269}
7fd59977 1270
2166f0fa
SK
1271// =======================================================================
1272// function : DrawDegeneratesPolygonsAsLines
1273// purpose :
1274// =======================================================================
1275void OpenGl_PrimitiveArray::DrawDegeneratesPolygonsAsLines (const float theSkipRatio) const
7fd59977 1276{
2166f0fa
SK
1277 Tint i, iv;
1278 tel_point pv = myPArray->vertices;
7fd59977 1279
2166f0fa
SK
1280 Tint n = myPArray->num_vertexs;
1281 Tint j = int((1.0f - theSkipRatio) * n);
1282 for (; j > 0; --j)
1283 {
7fd59977 1284 i = OGL_Rand() % n;
2166f0fa
SK
1285 myPArray->keys[i] = -myPArray->keys[i];
1286 }
1287
1288 if (myPArray->num_bounds > 0)
1289 {
1290 if (myPArray->num_edges > 0)
1291 {
1292 for (i = n = 0; i < myPArray->num_bounds; ++i)
1293 {
1294 glBegin (GL_LINE_LOOP);
1295 for (j = 0; j < myPArray->bounds[i]; ++j)
1296 {
1297 iv = myPArray->edges[n+j];
1298 if (myPArray->keys[iv] < 0)
1299 {
1300 myPArray->keys[iv] = -myPArray->keys[iv];
1301 glVertex3fv (pv[iv].xyz);
7fd59977 1302 }
1303 }
1304 glEnd();
2166f0fa 1305 n += myPArray->bounds[i];
7fd59977 1306 }
2166f0fa
SK
1307 }
1308 else
1309 {
1310 for (i = n = 0; i < myPArray->num_bounds; ++i)
1311 {
1312 glBegin (GL_LINE_LOOP);
1313 for (j = 0; j < myPArray->bounds[i]; ++j)
1314 {
1315 if (myPArray->keys[n+j] < 0)
1316 {
1317 myPArray->keys[n+j] = -myPArray->keys[n+j];
1318 glVertex3fv (pv[n+j].xyz);
7fd59977 1319 }
1320 }
1321 glEnd();
2166f0fa 1322 n += myPArray->bounds[i];
7fd59977 1323 }
1324 }
2166f0fa
SK
1325 }
1326 else if (myPArray->num_edges > 0)
1327 {
1328 glBegin (GL_LINE_LOOP);
1329 for (j = 0; j < myPArray->num_edges; ++j)
1330 {
1331 iv = myPArray->edges[j];
1332 if (myPArray->keys[iv] < 0)
1333 {
1334 myPArray->keys[iv] = -myPArray->keys[iv];
1335 glVertex3fv (pv[iv].xyz);
7fd59977 1336 }
1337 }
1338 glEnd();
2166f0fa
SK
1339 }
1340 else
1341 {
1342 glBegin (GL_LINE_LOOP);
1343 for (j = 0; j < myPArray->num_vertexs; ++j)
1344 {
1345 if (myPArray->keys[j] < 0)
1346 {
1347 myPArray->keys[j] = -myPArray->keys[j];
1348 glVertex3fv (pv[j].xyz);
7fd59977 1349 }
1350 }
1351 glEnd();
1352 }
7fd59977 1353}
1354
2166f0fa
SK
1355// =======================================================================
1356// function : DrawDegeneratesQuadranglesAsLines
1357// purpose :
1358// =======================================================================
1359void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglesAsLines (const float theSkipRatio) const
1360{
1361 Tint i, iv;
1362 tel_point pv = myPArray->vertices;
7fd59977 1363
2166f0fa
SK
1364 Tint n = myPArray->num_vertexs / 4;
1365 Tint j = int((1.0f - theSkipRatio) * n);
1366 for (; j > 0; --j)
1367 {
7fd59977 1368 i = OGL_Rand() % n; i *= 4;
2166f0fa
SK
1369 myPArray->keys[i] = -myPArray->keys[i];
1370 }
1371
1372 if (myPArray->num_edges > 0)
1373 {
1374 for (j = 0; j < myPArray->num_edges; j += 4)
1375 {
1376 iv = myPArray->edges[j];
1377 if (myPArray->keys[iv] < 0)
1378 {
1379 myPArray->keys[iv] = -myPArray->keys[iv];
1380 glBegin (GL_LINE_LOOP);
1381 for (i = 0; i < 4; ++i)
1382 {
1383 iv = myPArray->edges[j+i];
1384 glVertex3fv (pv[iv].xyz);
7fd59977 1385 }
1386 glEnd();
1387 }
1388 }
2166f0fa
SK
1389 }
1390 else
1391 {
1392 for (j = 0; j < myPArray->num_vertexs; j += 4)
1393 {
1394 if (myPArray->keys[j] < 0)
1395 {
1396 myPArray->keys[j] = -myPArray->keys[j];
1397 glBegin (GL_LINE_LOOP);
1398 for (i = 0; i < 4; ++i)
1399 {
1400 glVertex3fv (pv[j+i].xyz);
7fd59977 1401 }
1402 glEnd();
1403 }
1404 }
1405 }
2166f0fa 1406}
7fd59977 1407
2166f0fa
SK
1408// =======================================================================
1409// function : DrawDegeneratesQuadranglesAsLines
1410// purpose :
1411// =======================================================================
1412void OpenGl_PrimitiveArray::DrawDegeneratesQuadranglestripsAsLines (const float theSkipRatio) const
7fd59977 1413{
2166f0fa
SK
1414 Tint i, j, k, n, ni;
1415 tel_point pv = myPArray->vertices;
1416
1417 if (myPArray->num_bounds > 0)
1418 {
1419 for (i = n = 0; i < myPArray->num_bounds; ++i)
1420 {
1421 ni = myPArray->bounds[i] / 2 - 2;
1422 k = int((1.0f - theSkipRatio) * ni);
1423 for (; k > 0; --k)
1424 {
1425 j = OGL_Rand() % ni; j = j * 2 + 2;
1426 myPArray->keys[n+j] = -myPArray->keys[n+j];
1427 }
1428 for (j = 3; j < myPArray->bounds[i]; j += 2)
1429 {
1430 if (myPArray->keys[n+j] < 0)
1431 {
1432 myPArray->keys[n+j] = -myPArray->keys[n+j];
1433 glBegin (GL_LINE_LOOP);
1434 glVertex3fv (pv[n+j-3].xyz);
1435 glVertex3fv (pv[n+j-2].xyz);
1436 glVertex3fv (pv[n+j-1].xyz);
1437 glVertex3fv (pv[n+j].xyz);
7fd59977 1438 glEnd();
1439 }
1440 }
2166f0fa
SK
1441 n += myPArray->bounds[i];
1442 }
1443 }
1444 else
1445 {
1446 ni = myPArray->num_vertexs / 2 - 2;
1447 k = int((1.0f - theSkipRatio) * ni);
1448 for (; k > 0; --k)
1449 {
1450 j = OGL_Rand() % ni; j = j * 2 + 2;
1451 myPArray->keys[j] = -myPArray->keys[j];
7fd59977 1452 }
2166f0fa
SK
1453 for (j = 3; j < myPArray->num_vertexs; j += 2)
1454 {
1455 if (myPArray->keys[j] < 0)
1456 {
1457 myPArray->keys[j] = -myPArray->keys[j];
1458 glBegin (GL_LINE_LOOP);
1459 glVertex3fv (pv[j-3].xyz);
1460 glVertex3fv (pv[j-2].xyz);
1461 glVertex3fv (pv[j-1].xyz);
1462 glVertex3fv (pv[j].xyz);
7fd59977 1463 glEnd();
1464 }
1465 }
1466 }
2166f0fa 1467}
7fd59977 1468
2166f0fa
SK
1469// =======================================================================
1470// function : DrawDegeneratesAsLines
1471// purpose :
1472// =======================================================================
1473void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR* theEdgeColour,
1474 const Handle(OpenGl_Workspace)& theWorkspace) const
7fd59977 1475{
2166f0fa 1476 const float aSkipRatio = theWorkspace->SkipRatio;
7fd59977 1477
2166f0fa 1478 GLboolean zbuff_state = glIsEnabled (GL_DEPTH_TEST);
7fd59977 1479
2166f0fa 1480 glDisable (GL_LIGHTING);
7fd59977 1481
2166f0fa
SK
1482 if (zbuff_state)
1483 glDisable (GL_DEPTH_TEST);
7fd59977 1484
2166f0fa 1485 glColor3fv (theEdgeColour->rgb);
7fd59977 1486
2166f0fa
SK
1487 if (aSkipRatio != 0.0f)
1488 {
1489 switch (myDrawMode)
1490 {
7fd59977 1491 case GL_POINTS:
2166f0fa
SK
1492 if (aSkipRatio < 1.0f)
1493 DrawDegeneratesPointsAsPoints();
7fd59977 1494 break;
1495 case GL_LINES:
2166f0fa 1496 DrawDegeneratesLinesAsLines (aSkipRatio);
7fd59977 1497 break;
1498 case GL_LINE_STRIP:
1499 case GL_POLYGON:
2166f0fa 1500 DrawDegeneratesPolygonsAsLines (aSkipRatio);
7fd59977 1501 break;
1502 case GL_TRIANGLES:
2166f0fa 1503 DrawDegeneratesTrianglesAsLines (aSkipRatio);
7fd59977 1504 break;
1505 case GL_QUADS:
2166f0fa 1506 DrawDegeneratesQuadranglesAsLines (aSkipRatio);
7fd59977 1507 break;
1508 case GL_TRIANGLE_FAN:
1509 case GL_TRIANGLE_STRIP:
2166f0fa 1510 DrawDegeneratesTrianglestripsAsLines (aSkipRatio);
7fd59977 1511 break;
1512 case GL_QUAD_STRIP:
2166f0fa 1513 DrawDegeneratesQuadranglestripsAsLines (aSkipRatio);
7fd59977 1514 break;
1515 default:
1516 break;
2166f0fa 1517 }
7fd59977 1518 }
2166f0fa
SK
1519 else
1520 {
7fd59977 1521 int i,n;
2166f0fa
SK
1522 glPushAttrib (GL_POLYGON_BIT);
1523 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
1524
1525 GLboolean color_array_mode = glIsEnabled (GL_COLOR_ARRAY);
1526 GLboolean edge_flag_array_mode = glIsEnabled (GL_EDGE_FLAG_ARRAY);
1527 GLboolean index_array_mode = glIsEnabled (GL_INDEX_ARRAY);
1528 GLboolean normal_array_mode = glIsEnabled (GL_NORMAL_ARRAY);
1529 GLboolean texture_coord_array_mode = glIsEnabled (GL_TEXTURE_COORD_ARRAY);
1530 GLboolean vertex_array_mode = glIsEnabled (GL_VERTEX_ARRAY);
1531
1532 glDisableClientState (GL_COLOR_ARRAY);
1533 glDisableClientState (GL_EDGE_FLAG_ARRAY);
1534 glDisableClientState (GL_INDEX_ARRAY);
1535 glDisableClientState (GL_NORMAL_ARRAY);
1536 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
1537
1538 if (!vertex_array_mode)
1539 glEnableClientState (GL_VERTEX_ARRAY);
1540
1541 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
1542
1543 GLint renderMode;
1544 glGetIntegerv (GL_RENDER_MODE, &renderMode);
1545
1546 if (myPArray->num_bounds > 0)
1547 {
1548 if (myPArray->num_edges > 0)
1549 {
1550 for (i = n = 0; i < myPArray->num_bounds; ++i)
1551 {
1552 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1553 myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
1554 n += myPArray->bounds[i];
7fd59977 1555 }
1556 }
7fd59977 1557 else
2166f0fa
SK
1558 {
1559 for (i = n = 0; i < myPArray->num_bounds; ++i)
1560 {
1561 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1562 n, myPArray->bounds[i]);
1563 n += myPArray->bounds[i];
1564 }
1565 }
1566 }
1567 else if (myPArray->num_edges > 0)
1568 {
1569 DrawElements (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1570 myPArray->num_edges, (GLenum* )myPArray->edges);
1571 }
1572 else
1573 {
1574 DrawArrays (theWorkspace, myPArray, (renderMode == GL_FEEDBACK), myDrawMode,
1575 0, myPArray->num_vertexs);
7fd59977 1576 }
1577
2166f0fa
SK
1578 if (!vertex_array_mode) glDisableClientState (GL_VERTEX_ARRAY);
1579
1580 if (color_array_mode) glEnableClientState (GL_COLOR_ARRAY);
1581 if (edge_flag_array_mode) glEnableClientState (GL_EDGE_FLAG_ARRAY);
1582 if (index_array_mode) glEnableClientState (GL_INDEX_ARRAY);
1583 if (normal_array_mode) glEnableClientState (GL_NORMAL_ARRAY);
1584 if (texture_coord_array_mode) glEnableClientState (GL_TEXTURE_COORD_ARRAY);
7fd59977 1585
7fd59977 1586 glPopAttrib();
1587 }
1588
2166f0fa
SK
1589 if (zbuff_state)
1590 glEnable(GL_DEPTH_TEST);
7fd59977 1591}
1592
2166f0fa
SK
1593// =======================================================================
1594// function : DrawDegeneratesAsBBoxs
1595// purpose :
1596// =======================================================================
1597void OpenGl_PrimitiveArray::DrawDegeneratesAsBBoxs (const TEL_COLOUR* theEdgeColour) const
7fd59977 1598{
2166f0fa
SK
1599 GLfloat minp[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
1600 GLfloat maxp[3] = { FLT_MIN, FLT_MIN, FLT_MIN };
1601 tel_point pv = myPArray->vertices;
1602
1603 glDisable (GL_LIGHTING);
1604
1605 glColor3fv (theEdgeColour->rgb);
1606
1607 for (Tint i = 0; i < myPArray->num_vertexs; ++i)
1608 {
1609 if (pv[i].xyz[0] < minp[0])
1610 minp[0] = pv[i].xyz[0];
1611 if (pv[i].xyz[1] < minp[1])
1612 minp[1] = pv[i].xyz[1];
1613 if (pv[i].xyz[2] < minp[2])
1614 minp[2] = pv[i].xyz[2];
1615
1616 if (pv[i].xyz[0] > maxp[0])
1617 maxp[0] = pv[i].xyz[0];
1618 if (pv[i].xyz[1] > maxp[1])
1619 maxp[1] = pv[i].xyz[1];
1620 if (pv[i].xyz[2] > maxp[2])
1621 maxp[2] = pv[i].xyz[2];
1622 }
1623
1624 glBegin (GL_LINE_STRIP);
1625
1626 glVertex3fv (minp);
1627 glVertex3f (minp[0], maxp[1], minp[2]);
1628 glVertex3f (minp[0], maxp[1], maxp[2]);
1629 glVertex3f (minp[0], minp[1], maxp[2]);
1630 glVertex3f (minp[0], minp[1], minp[2]);
1631
1632 glVertex3f (maxp[0], minp[1], minp[2]);
1633 glVertex3f (maxp[0], maxp[1], minp[2]);
1634 glVertex3f (maxp[0], maxp[1], maxp[2]);
1635 glVertex3f (maxp[0], minp[1], maxp[2]);
1636 glVertex3f (maxp[0], minp[1], minp[2]);
7fd59977 1637
2166f0fa
SK
1638 glVertex3f (maxp[0], minp[1], maxp[2]);
1639 glVertex3f (minp[0], minp[1], maxp[2]);
1640 glVertex3f (minp[0], maxp[1], maxp[2]);
1641 glVertex3fv (maxp);
1642 glVertex3f (maxp[0], maxp[1], minp[2]);
1643 glVertex3f (minp[0], maxp[1], minp[2]);
7fd59977 1644
1645 glEnd();
2166f0fa 1646}
7fd59977 1647
2166f0fa
SK
1648// =======================================================================
1649// function : OpenGl_PrimitiveArray
1650// purpose :
1651// =======================================================================
1652OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
1653: myPArray (thePArray),
1654 myDrawMode (GL_NONE)
1655{
1656 switch (myPArray->type)
1657 {
1658 case TelPointsArrayType:
1659 myDrawMode = GL_POINTS;
1660 break;
1661 case TelPolylinesArrayType:
1662 myDrawMode = GL_LINE_STRIP;
1663 break;
1664 case TelSegmentsArrayType:
1665 myDrawMode = GL_LINES;
1666 break;
1667 case TelPolygonsArrayType:
1668 myDrawMode = GL_POLYGON;
1669 break;
1670 case TelTrianglesArrayType:
1671 myDrawMode = GL_TRIANGLES;
1672 break;
1673 case TelQuadranglesArrayType:
1674 myDrawMode = GL_QUADS;
1675 break;
1676 case TelTriangleStripsArrayType:
1677 myDrawMode = GL_TRIANGLE_STRIP;
1678 break;
1679 case TelQuadrangleStripsArrayType:
1680 myDrawMode = GL_QUAD_STRIP;
1681 break;
1682 case TelTriangleFansArrayType:
1683 myDrawMode = GL_TRIANGLE_FAN;
1684 break;
1685 }
1686}
1687
1688// =======================================================================
1689// function : ~OpenGl_PrimitiveArray
1690// purpose :
1691// =======================================================================
1692OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray ()
1693{
1694 if (myPArray == NULL)
1695 return;
1696
1697 if (myPArray->VBOEnabled == VBO_OK)
1698 {
1699 OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
1700 if (myPArray->bufferVBO[VBOEdges] != 0)
1701 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1702 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOEdges]));
1703 if (myPArray->bufferVBO[VBOVertices] != 0)
1704 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1705 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVertices]));
1706 if (myPArray->bufferVBO[VBOVcolours] != 0)
1707 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1708 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVcolours]));
1709 if (myPArray->bufferVBO[VBOVnormals] != 0)
1710 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1711 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVnormals]));
1712 if (myPArray->bufferVBO[VBOVtexels] != 0)
1713 aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
1714 new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVtexels]));
1715 }
1716}
1717
1718// =======================================================================
1719// function : Render
1720// purpose :
1721// =======================================================================
1722void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
1723{
1724 if (myPArray == NULL || myDrawMode == GL_NONE)
1725 return;
1726
1727 // create VBOs on first render call
1728 if (myPArray->VBOEnabled == -1) // special value for uninitialized state
1729 {
1730 myPArray->VBOEnabled = OpenGl_GraphicDriver::ToUseVBO() && (theWorkspace->GetGlContext()->arbVBO != NULL);
1731 if (myPArray->VBOEnabled != 0)
1732 BuildVBO (theWorkspace);
1733 }
1734
1735 switch (myPArray->type)
1736 {
1737 case TelPointsArrayType:
1738 case TelPolylinesArrayType:
1739 case TelSegmentsArrayType:
1740 {
1741 glDisable (GL_LIGHTING);
1742
1743 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1744 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
1745 theWorkspace->DegenerateModel)
1746 {
1747 glDisable (GL_DEPTH_TEST);
1748 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1749 DisableTexture();
1750 theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
1751 }
1752 break;
1753 }
1754 case TelPolygonsArrayType:
1755 case TelTrianglesArrayType:
1756 case TelQuadranglesArrayType:
1757 case TelTriangleStripsArrayType:
1758 case TelTriangleFansArrayType:
1759 case TelQuadrangleStripsArrayType:
1760 {
1761 if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
1762 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
1763 theWorkspace->DegenerateModel < 2)
1764 {
1765 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1766 EnableTexture();
1767 glEnable (GL_DEPTH_TEST);
1768 theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
1769 }
1770 break;
1771 }
1772 default:
1773 break;
1774 }
1775
1776 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
1777 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
1778
1779 Tint aFrontLightingModel = anAspectFace->Context().IntFront.color_mask;
1780 const TEL_COLOUR* anInteriorColor = &anAspectFace->Context().IntFront.matcol;
1781 const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
1782 const TEL_COLOUR* aLineColor = &anAspectLine->Color();
1783
1784 // Use highlight colors
1785 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
1786 {
1787 anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor;
1788 aFrontLightingModel = 0;
1789 }
1790
1791 DrawArray (aFrontLightingModel,
1792 anAspectFace->Context().InteriorStyle,
1793 anAspectFace->Context().Edge,
1794 anInteriorColor,
1795 aLineColor,
1796 anEdgeColor,
1797 &anAspectFace->Context().IntFront,
1798 theWorkspace);
1799
1800 switch (myPArray->type)
1801 {
1802 case TelPointsArrayType:
1803 case TelPolylinesArrayType:
1804 case TelSegmentsArrayType:
1805 {
1806 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
1807 EnableTexture();
1808 }
1809 }
1810}