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