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