0024123: Create debug OpenGL context when requested (GL_ARB_debug_output)
[occt.git] / src / OpenGl / OpenGl_PrimitiveArray.cxx
CommitLineData
b311480e 1// Created on: 2011-07-13
2// Created by: Sergey ZERCHANINOV
de75ed09 3// Copyright (c) 2011-2013 OPEN CASCADE SAS
b311480e 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 27#include <OpenGl_Structure.hxx>
bf75be98 28#include <OpenGl_Workspace.hxx>
2166f0fa 29
7fd59977 30#include <InterfaceGraphic_PrimitiveArray.hxx>
2166f0fa 31
2166f0fa
SK
32// =======================================================================
33// function : clearMemoryOwn
34// purpose :
35// =======================================================================
36void OpenGl_PrimitiveArray::clearMemoryOwn() const
7fd59977 37{
5e27df78 38 Standard::Free ((Standard_Address& )myPArray->edges);
39 Standard::Free ((Standard_Address& )myPArray->vertices);
40 Standard::Free ((Standard_Address& )myPArray->vcolours);
41 Standard::Free ((Standard_Address& )myPArray->vnormals);
42 Standard::Free ((Standard_Address& )myPArray->vtexels);
43 Standard::Free ((Standard_Address& )myPArray->edge_vis); /// ???
44
45 myPArray->edges = NULL;
46 myPArray->vertices = NULL;
47 myPArray->vcolours = NULL;
48 myPArray->vnormals = NULL;
49 myPArray->vtexels = NULL;
50 myPArray->edge_vis = NULL;
7fd59977 51}
52
2166f0fa
SK
53// =======================================================================
54// function : clearMemoryGL
55// purpose :
56// =======================================================================
5e27df78 57void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const
7fd59977 58{
5e27df78 59 for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
2166f0fa 60 {
5e27df78 61 if (!myVbos[anIter].IsNull())
62 {
63 myVbos[anIter]->Release (theGlCtx.operator->());
64 myVbos[anIter].Nullify();
65 }
2166f0fa 66 }
7fd59977 67}
68
2166f0fa 69// =======================================================================
5e27df78 70// function : BuildVBO
2166f0fa
SK
71// purpose :
72// =======================================================================
5e27df78 73Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
7fd59977 74{
5e27df78 75 const Handle(OpenGl_Context)& aGlCtx = theWorkspace->GetGlContext();
76 if (myPArray->vertices == NULL)
2166f0fa 77 {
5e27df78 78 // vertices should be always defined - others are optional
79 return Standard_False;
2166f0fa 80 }
5e27df78 81 myVbos[VBOVertices] = new OpenGl_VertexBuffer();
82 if (!myVbos[VBOVertices]->Init (aGlCtx, 3, myPArray->num_vertexs, &myPArray->vertices[0].xyz[0]))
2166f0fa 83 {
5e27df78 84 clearMemoryGL (aGlCtx);
85 return Standard_False;
2166f0fa 86 }
7fd59977 87
ee1e83b9 88 if (myPArray->edges != NULL
89 && myPArray->num_edges > 0)
2166f0fa 90 {
5e27df78 91 myVbos[VBOEdges] = new OpenGl_IndexBuffer();
92 if (!myVbos[VBOEdges]->Init (aGlCtx, 1, myPArray->num_edges, (GLuint* )myPArray->edges))
93 {
94 clearMemoryGL (aGlCtx);
2166f0fa 95 return Standard_False;
5e27df78 96 }
7fd59977 97 }
2166f0fa
SK
98 if (myPArray->vcolours != NULL)
99 {
5e27df78 100 myVbos[VBOVcolours] = new OpenGl_VertexBuffer();
101 if (!myVbos[VBOVcolours]->Init (aGlCtx, 4, myPArray->num_vertexs, (GLubyte* )myPArray->vcolours))
102 {
103 clearMemoryGL (aGlCtx);
2166f0fa 104 return Standard_False;
5e27df78 105 }
7fd59977 106 }
2166f0fa
SK
107 if (myPArray->vnormals != NULL)
108 {
5e27df78 109 myVbos[VBOVnormals] = new OpenGl_VertexBuffer();
110 if (!myVbos[VBOVnormals]->Init (aGlCtx, 3, myPArray->num_vertexs, &myPArray->vnormals[0].xyz[0]))
111 {
112 clearMemoryGL (aGlCtx);
2166f0fa 113 return Standard_False;
5e27df78 114 }
7fd59977 115 }
2166f0fa
SK
116 if (myPArray->vtexels)
117 {
5e27df78 118 myVbos[VBOVtexels] = new OpenGl_VertexBuffer();
119 if (!myVbos[VBOVtexels]->Init (aGlCtx, 2, myPArray->num_vertexs, &myPArray->vtexels[0].xy[0]))
120 {
121 clearMemoryGL (aGlCtx);
2166f0fa 122 return Standard_False;
5e27df78 123 }
2166f0fa 124 }
7fd59977 125
5e27df78 126 clearMemoryOwn();
2166f0fa 127 return Standard_True;
7fd59977 128}
129
2166f0fa
SK
130// =======================================================================
131// function : DrawArray
132// purpose :
133// =======================================================================
134void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
135 const Aspect_InteriorStyle theInteriorStyle,
136 Tint theEdgeFlag,
137 const TEL_COLOUR* theInteriorColour,
138 const TEL_COLOUR* theLineColour,
139 const TEL_COLOUR* theEdgeColour,
140 const OPENGL_SURF_PROP* theFaceProp,
141 const Handle(OpenGl_Workspace)& theWorkspace) const
7fd59977 142{
2166f0fa
SK
143 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
144
7fd59977 145 Tint i,n;
146 Tint transp = 0;
2166f0fa
SK
147 // Following pointers have been provided for performance improvement
148 tel_colour pfc = myPArray->fcolours;
149 Tint* pvc = myPArray->vcolours;
150 if (pvc != NULL)
151 {
152 for (i = 0; i < myPArray->num_vertexs; ++i)
153 {
154 transp = int(theFaceProp->trans * 255.0f);
bf75be98 155 #if defined (sparc) || defined (__sparc__) || defined (__sparc)
2166f0fa
SK
156 pvc[i] = (pvc[i] & 0xffffff00);
157 pvc[i] += transp;
bf75be98 158 #else
2166f0fa 159 pvc[i] = (pvc[i] & 0x00ffffff);
7fd59977 160 pvc[i] += transp << 24;
2166f0fa 161 #endif
7fd59977 162 }
163 }
7fd59977 164
2166f0fa
SK
165 switch (myPArray->type)
166 {
7fd59977 167 case TelPointsArrayType:
7fd59977 168 case TelPolylinesArrayType:
7fd59977 169 case TelSegmentsArrayType:
2166f0fa 170 glColor3fv (theLineColour->rgb);
7fd59977 171 break;
172 case TelPolygonsArrayType:
7fd59977 173 case TelTrianglesArrayType:
7fd59977 174 case TelQuadranglesArrayType:
7fd59977 175 case TelTriangleStripsArrayType:
7fd59977 176 case TelQuadrangleStripsArrayType:
7fd59977 177 case TelTriangleFansArrayType:
2166f0fa 178 glColor3fv (theInteriorColour->rgb);
7fd59977 179 break;
7fd59977 180 }
181
2166f0fa
SK
182 // Temporarily disable environment mapping
183 if (myDrawMode <= GL_LINE_STRIP)
184 {
185 glPushAttrib (GL_ENABLE_BIT);
186 glDisable (GL_TEXTURE_1D);
187 glDisable (GL_TEXTURE_2D);
7fd59977 188 }
189
de75ed09 190 if ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
191 (myDrawMode <= GL_LINE_STRIP))
2166f0fa
SK
192 {
193 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
194 {
7fd59977 195 pfc = NULL;
196 pvc = NULL;
197 }
198
2166f0fa
SK
199 if (theInteriorStyle == Aspect_IS_HIDDENLINE)
200 {
201 theEdgeFlag = 1;
7fd59977 202 pfc = NULL;
203 pvc = NULL;
204 }
205
2166f0fa 206 // Sometimes the GL_LIGHTING mode is activated here
bf75be98 207 // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
2166f0fa
SK
208 // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
209 if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
210 glDisable (GL_LIGHTING);
211 else
212 glEnable (GL_LIGHTING);
213
5e27df78 214 if (!toDrawVbo())
2166f0fa
SK
215 {
216 if (myPArray->vertices != NULL)
217 {
218 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
219 glEnableClientState (GL_VERTEX_ARRAY);
220 }
221 if (myPArray->vnormals != NULL)
222 {
223 glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
224 glEnableClientState (GL_NORMAL_ARRAY);
225 }
226 if (myPArray->vtexels != NULL)
227 {
228 glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
229 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
230 }
7fd59977 231
2166f0fa
SK
232 if (pvc != NULL)
233 {
234 glColorPointer (4, GL_UNSIGNED_BYTE, 0, pvc); // array of colors
235 glEnableClientState (GL_COLOR_ARRAY);
236 glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
237 glEnable (GL_COLOR_MATERIAL);
7fd59977 238 }
239 }
5e27df78 240 else
2166f0fa
SK
241 {
242 // Bindings concrete pointer in accordance with VBO buffer
5e27df78 243 myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
244 if (!myVbos[VBOVnormals].IsNull())
2166f0fa 245 {
5e27df78 246 myVbos[VBOVnormals]->BindFixed (aGlContext, GL_NORMAL_ARRAY);
7fd59977 247 }
5e27df78 248 if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
2166f0fa 249 {
5e27df78 250 myVbos[VBOVtexels]->BindFixed (aGlContext, GL_TEXTURE_COORD_ARRAY);
7fd59977 251 }
5e27df78 252 if (!myVbos[VBOVcolours].IsNull())
2166f0fa 253 {
5e27df78 254 myVbos[VBOVcolours]->BindFixed (aGlContext, GL_COLOR_ARRAY);
255 glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
2166f0fa 256 glEnable (GL_COLOR_MATERIAL);
7fd59977 257 }
258 }
2166f0fa 259
5e27df78 260 /// OCC22236 NOTE: draw for all situations:
261 /// 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
262 /// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
263 /// 3) draw primitive by vertexes if no edges and bounds array is specified
264 if (toDrawVbo())
2166f0fa 265 {
5e27df78 266 if (!myVbos[VBOEdges].IsNull())
2166f0fa 267 {
5e27df78 268 myVbos[VBOEdges]->Bind (aGlContext);
2166f0fa
SK
269 if (myPArray->num_bounds > 0)
270 {
271 // draw primitives by vertex count with the indicies
272 Tint* anOffset = NULL;
273 for (i = 0; i < myPArray->num_bounds; ++i)
274 {
7cc2d520 275 if (pfc != NULL) glColor3fv (pfc[i].rgb);
5e27df78 276 glDrawElements (myDrawMode, myPArray->bounds[i], myVbos[VBOEdges]->GetDataType(), anOffset);
bf75be98 277 anOffset += myPArray->bounds[i];
762aacae
A
278 }
279 }
2166f0fa
SK
280 else
281 {
282 // draw one (or sequential) primitive by the indicies
5e27df78 283 glDrawElements (myDrawMode, myPArray->num_edges, myVbos[VBOEdges]->GetDataType(), NULL);
762aacae 284 }
5e27df78 285 myVbos[VBOEdges]->Unbind (aGlContext);
7fd59977 286 }
2166f0fa
SK
287 else if (myPArray->num_bounds > 0)
288 {
289 for (i = n = 0; i < myPArray->num_bounds; ++i)
290 {
7cc2d520 291 if (pfc != NULL) glColor3fv (pfc[i].rgb);
2166f0fa
SK
292 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
293 n += myPArray->bounds[i];
7fd59977 294 }
295 }
2166f0fa
SK
296 else
297 {
5e27df78 298 glDrawArrays (myDrawMode, 0, myVbos[VBOVertices]->GetElemsNb());
762aacae
A
299 }
300
2166f0fa 301 // bind with 0
5e27df78 302 myVbos[VBOVertices]->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
303 if (!myVbos[VBOVnormals].IsNull())
304 {
305 myVbos[VBOVnormals]->UnbindFixed (aGlContext, GL_NORMAL_ARRAY);
306 }
307 if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
308 {
309 myVbos[VBOVtexels]->UnbindFixed (aGlContext, GL_TEXTURE_COORD_ARRAY);
310 }
311 if (!myVbos[VBOVcolours].IsNull())
312 {
313 myVbos[VBOVcolours]->UnbindFixed (aGlContext, GL_COLOR_ARRAY);
314 glDisable (GL_COLOR_MATERIAL);
315 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
316 }
bf75be98 317 }
2166f0fa
SK
318 else
319 {
320 if (myPArray->num_bounds > 0)
321 {
322 if (myPArray->num_edges > 0)
323 {
324 for (i = n = 0; i < myPArray->num_bounds; ++i)
325 {
326 if (pfc != NULL) glColor3fv (pfc[i].rgb);
5e27df78 327 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
2166f0fa
SK
328 n += myPArray->bounds[i];
329 }
330 }
331 else
332 {
333 for (i = n = 0; i < myPArray->num_bounds; ++i)
334 {
7cc2d520 335 if (pfc != NULL) glColor3fv (pfc[i].rgb);
5e27df78 336 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
2166f0fa
SK
337 n += myPArray->bounds[i];
338 }
7fd59977 339 }
2166f0fa
SK
340 }
341 else if (myPArray->num_edges > 0)
342 {
5e27df78 343 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
2166f0fa
SK
344 }
345 else
346 {
5e27df78 347 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
2166f0fa 348 }
7fd59977 349
5e27df78 350 if (pvc != NULL)
351 {
352 glDisable (GL_COLOR_MATERIAL);
353 theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
354 }
2166f0fa 355
2166f0fa 356 glDisableClientState (GL_VERTEX_ARRAY);
5e27df78 357 if (myPArray->vcolours != NULL)
358 glDisableClientState (GL_COLOR_ARRAY);
359 if (myPArray->vnormals != NULL)
360 glDisableClientState (GL_NORMAL_ARRAY);
361 if (myPArray->vtexels != NULL)
362 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
363 }
7fd59977 364 }
365
de75ed09 366 // On some NVIDIA graphic cards, using glEdgeFlagPointer() in
367 // combination with VBO (edge flag data put into a VBO buffer)
368 // leads to a crash in a driver. Therefore, edge flags are simply
369 // igonored when VBOs are enabled, so all the edges are drawn if
370 // edge visibility is turned on. In order to draw edges selectively,
371 // either disable VBO or turn off edge visibilty in the current
372 // primitive array and create a separate primitive array (segments)
373 // and put edges to be drawn into it.
374 if (theEdgeFlag && myDrawMode > GL_LINE_STRIP)
2166f0fa 375 {
de75ed09 376 DrawEdges (theEdgeColour, theWorkspace);
2166f0fa
SK
377 }
378
379 if (myDrawMode <= GL_LINE_STRIP)
7fd59977 380 glPopAttrib();
381}
382
2166f0fa
SK
383// =======================================================================
384// function : DrawEdges
385// purpose :
386// =======================================================================
387void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour,
388 const Handle(OpenGl_Workspace)& theWorkspace) const
7fd59977 389{
2166f0fa 390 glDisable (GL_LIGHTING);
7fd59977 391
2166f0fa
SK
392 const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
393 const OpenGl_AspectLine* anAspectLineOld = NULL;
394 if (myDrawMode > GL_LINE_STRIP)
395 {
396 anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
397 theWorkspace->AspectLine (Standard_True);
7fd59977 398
2166f0fa
SK
399 glPushAttrib (GL_POLYGON_BIT);
400 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
401 }
7fd59977 402
2166f0fa 403 Tint i, j, n;
7fd59977 404
5e27df78 405 /// OCC22236 NOTE: draw edges for all situations:
406 /// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
407 /// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
408 /// 3) draw primitive's edges by vertexes if no edges and bounds array is specified
409 if (toDrawVbo())
bf75be98 410 {
5e27df78 411 myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
2166f0fa 412 glColor3fv (theEdgeColour->rgb);
5e27df78 413 if (!myVbos[VBOEdges].IsNull())
2166f0fa 414 {
5e27df78 415 myVbos[VBOEdges]->Bind (aGlContext);
2166f0fa 416
762aacae 417 // draw primitives by vertex count with the indicies
2166f0fa
SK
418 if (myPArray->num_bounds > 0)
419 {
762aacae 420 Tint* offset = 0;
2166f0fa
SK
421 for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
422 {
5e27df78 423 glDrawElements (myDrawMode, myPArray->bounds[i], myVbos[VBOEdges]->GetDataType(), offset);
2166f0fa 424 offset += myPArray->bounds[i];
762aacae
A
425 }
426 }
427 // draw one (or sequential) primitive by the indicies
2166f0fa
SK
428 else
429 {
5e27df78 430 glDrawElements (myDrawMode, myVbos[VBOEdges]->GetElemsNb(), myVbos[VBOEdges]->GetDataType(), NULL);
762aacae 431 }
5e27df78 432 myVbos[VBOEdges]->Unbind (aGlContext);
7fd59977 433 }
2166f0fa
SK
434 else if (myPArray->num_bounds > 0)
435 {
436 for (i = n = 0; i < myPArray->num_bounds; ++i)
437 {
438 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
439 n += myPArray->bounds[i];
7fd59977 440 }
441 }
2166f0fa
SK
442 else
443 {
444 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
762aacae
A
445 }
446
447 // unbind buffers
5e27df78 448 myVbos[VBOVertices]->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
2166f0fa
SK
449 }
450 else
451 {
452 glEnableClientState (GL_VERTEX_ARRAY);
453 glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
2166f0fa
SK
454
455 glColor3fv (theEdgeColour->rgb);
456 if (myPArray->num_bounds > 0)
457 {
458 if (myPArray->num_edges > 0)
459 {
460 for (i = n = 0; i < myPArray->num_bounds; ++i)
461 {
462 if (myPArray->edge_vis)
463 {
464 glBegin (myDrawMode);
465 for (j = 0; j < myPArray->bounds[i]; ++j)
466 {
467 glEdgeFlag (myPArray->edge_vis[n+j]);
468 glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
469 }
470 glEnd();
7fd59977 471 }
2166f0fa
SK
472 else
473 {
5e27df78 474 glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
7fd59977 475 }
2166f0fa 476 n += myPArray->bounds[i];
7fd59977 477 }
2166f0fa 478 }
7fd59977 479 else
2166f0fa
SK
480 {
481 for (i = n = 0 ; i < myPArray->num_bounds; ++i)
482 {
5e27df78 483 glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
2166f0fa
SK
484 n += myPArray->bounds[i];
485 }
486 }
bf75be98 487 }
2166f0fa
SK
488 else if (myPArray->num_edges > 0)
489 {
490 if (myPArray->edge_vis)
491 {
492 glBegin (myDrawMode);
493 for (i = 0; i < myPArray->num_edges; ++i)
494 {
495 glEdgeFlag (myPArray->edge_vis[i]);
496 glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
497 }
498 glEnd();
499 }
7fd59977 500 else
2166f0fa 501 {
5e27df78 502 glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
7fd59977 503 }
504 }
2166f0fa
SK
505 else
506 {
5e27df78 507 glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
7fd59977 508 }
2166f0fa
SK
509 }
510
511 if (myDrawMode > GL_LINE_STRIP)
512 {
513 // Restore line context
514 theWorkspace->SetAspectLine (anAspectLineOld);
7fd59977 515 glPopAttrib();
516 }
517}
518
2166f0fa
SK
519// =======================================================================
520// function : OpenGl_PrimitiveArray
521// purpose :
522// =======================================================================
523OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
524: myPArray (thePArray),
5e27df78 525 myDrawMode (DRAW_MODE_NONE),
526 myIsVboInit (Standard_False)
2166f0fa
SK
527{
528 switch (myPArray->type)
529 {
530 case TelPointsArrayType:
531 myDrawMode = GL_POINTS;
532 break;
533 case TelPolylinesArrayType:
534 myDrawMode = GL_LINE_STRIP;
535 break;
536 case TelSegmentsArrayType:
537 myDrawMode = GL_LINES;
538 break;
539 case TelPolygonsArrayType:
540 myDrawMode = GL_POLYGON;
541 break;
542 case TelTrianglesArrayType:
543 myDrawMode = GL_TRIANGLES;
544 break;
545 case TelQuadranglesArrayType:
546 myDrawMode = GL_QUADS;
547 break;
548 case TelTriangleStripsArrayType:
549 myDrawMode = GL_TRIANGLE_STRIP;
550 break;
551 case TelQuadrangleStripsArrayType:
552 myDrawMode = GL_QUAD_STRIP;
553 break;
554 case TelTriangleFansArrayType:
555 myDrawMode = GL_TRIANGLE_FAN;
556 break;
557 }
558}
559
560// =======================================================================
561// function : ~OpenGl_PrimitiveArray
562// purpose :
563// =======================================================================
5e27df78 564OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray()
2166f0fa 565{
5e27df78 566 //
567}
2166f0fa 568
5e27df78 569// =======================================================================
570// function : Release
571// purpose :
572// =======================================================================
573void OpenGl_PrimitiveArray::Release (const Handle(OpenGl_Context)& theContext)
574{
575 for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
2166f0fa 576 {
5e27df78 577 if (!myVbos[anIter].IsNull())
578 {
dd8a4ce9 579 if (!theContext.IsNull())
580 {
581 theContext->DelayedRelease (myVbos[anIter]);
582 }
5e27df78 583 myVbos[anIter].Nullify();
584 }
2166f0fa
SK
585 }
586}
587
588// =======================================================================
589// function : Render
590// purpose :
591// =======================================================================
592void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
593{
5e27df78 594 if (myPArray == NULL || myDrawMode == DRAW_MODE_NONE || myPArray->num_vertexs <= 0)
bf75be98 595 {
2166f0fa 596 return;
bf75be98 597 }
2166f0fa
SK
598
599 // create VBOs on first render call
58655684 600 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
601 if (!myIsVboInit && !aCtx->caps->vboDisable && aCtx->core15 != NULL)
2166f0fa 602 {
5e27df78 603 BuildVBO (theWorkspace);
604 myIsVboInit = Standard_True;
2166f0fa
SK
605 }
606
607 switch (myPArray->type)
608 {
609 case TelPointsArrayType:
610 case TelPolylinesArrayType:
611 case TelSegmentsArrayType:
612 {
613 glDisable (GL_LIGHTING);
2166f0fa
SK
614 break;
615 }
616 default:
617 break;
618 }
619
17f65eb2 620 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
621 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
622 const OpenGl_AspectMarker* anAspectMarker = theWorkspace->AspectMarker (myPArray->type == TelPointsArrayType);
2166f0fa 623
bf75be98 624 Tint aFrontLightingModel = anAspectFace->IntFront.color_mask;
625 const TEL_COLOUR* anInteriorColor = &anAspectFace->IntFront.matcol;
2166f0fa 626 const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
17f65eb2 627 const TEL_COLOUR* aLineColor = (myPArray->type == TelPointsArrayType) ? &anAspectMarker->Color() : &anAspectLine->Color();
2166f0fa
SK
628
629 // Use highlight colors
630 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
bf75be98 631 {
2166f0fa
SK
632 anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor;
633 aFrontLightingModel = 0;
634 }
635
636 DrawArray (aFrontLightingModel,
bf75be98 637 anAspectFace->InteriorStyle,
638 anAspectFace->Edge,
2166f0fa
SK
639 anInteriorColor,
640 aLineColor,
641 anEdgeColor,
bf75be98 642 &anAspectFace->IntFront,
2166f0fa 643 theWorkspace);
2166f0fa 644}