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