OCC22199 OpenGL memory leaks in TKOpenGl
[occt.git] / src / OpenGl / OpenGl_PrimitiveArray.cxx
CommitLineData
7fd59977 1/*
2File OpenGl_PrimitiveArray.c
3
4Created 16/06/2000 : ATS : G005 : Modified version of OpenGl_indexpolygons.c, which use glDrawArrays or glDrawElements for rendering of primitive
521.06.03 : SAN : suppress display at all in animation mode if degenartion ratio == 1 (FULL_DEGENER)
603.07.03 : SAN : draw_degenerates_as_lines() function - all client states disabled except GL_VERTEX_ARRAY
7in order to avoid exceptions in animation mode (OCC3192)
8*/
9
10#define xOGLBUG /* UNFORTUNATLY the edge flags are attached to vertexes
11and not to the edges. So the edge visibillity flags array
12is not usable.
13*/
14
15#define xPRINT
16
17#define TEST
18
19#define FULL_DEGENER
20#define OCC3192
21
22
23#ifndef OGL_Max
24#define OGL_Max(a,b) ((a) > (b) ? (a) : (b))
25#endif
26
27#ifndef OGL_Rand
28static unsigned long vRand = 1L;
29#define OGL_Rand() (vRand = vRand * 214013L + 2531011L)
30#endif
31
32
33#define OCC7833 /* ASL 26/01/05 transparency of polygon with colors assigned to vertices */
34
35/*----------------------------------------------------------------------*/
36/*
37* Includes
38*/
39
40#include <OpenGl_tgl_all.hxx>
41
42#include <stddef.h>
43#include <stdio.h>
44#include <string.h>
45#include <iostream>
46
47#include <OpenGl_cmn_varargs.hxx>
48#include <OpenGl_telem_attri.hxx>
49#include <OpenGl_tsm.hxx>
50#include <OpenGl_telem.hxx>
51#include <OpenGl_telem_util.hxx>
52#include <OpenGl_telem_highlight.hxx>
53#include <OpenGl_telem_inquire.hxx>
54#include <OpenGl_telem_view.hxx>
55#include <OpenGl_tgl_funcs.hxx>
56#include <OpenGl_LightBox.hxx>
57#include <OpenGl_TextureBox.hxx>
161c4476
K
58#include <OpenGl_ResourceCleaner.hxx>
59#include <OpenGl_ResourceVBO.hxx>
7fd59977 60#include <InterfaceGraphic_PrimitiveArray.hxx>
61#include <OpenGl_Memory.hxx>
62#include <Standard.hxx>
63
64# include <float.h>
65# define DEF_DS_INTERNAL
66# include <OpenGl_degeneration.hxx>
67
68#include <OpenGl_Extension.hxx>
69
70extern GLboolean g_fBitmap;
71
72typedef CALL_DEF_PARRAY *call_def_parray;
73
74#define GL_ARRAY_BUFFER_ARB 0x8892
75#define GL_STATIC_DRAW_ARB 0x88E4
76#define GL_ELEMENTS_ARRAY_BUFFER_ARB 0x8893
77#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
78
79#ifdef WNT
80typedef void (APIENTRY* PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
81typedef void (APIENTRY* PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
82typedef void (APIENTRY* PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
83typedef void (APIENTRY* PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
84#else//WNT
85typedef void (*PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
86typedef void (*PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
87typedef void (*PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
88#if defined ( __sgi )
89typedef void (*PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
90#else
91typedef void (*PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
92#endif
93
94#endif//WNT
95
96PFNGLGENBUFFERSARBPROC glVBOGenBuffersARB = NULL; // VBO Name Generation Procedure
97PFNGLBINDBUFFERARBPROC glVBOBindBufferARB = NULL; // VBO Bind Procedure
98PFNGLBUFFERDATAARBPROC glVBOBufferDataARB = NULL; // VBO Data Loading Procedure
99PFNGLDELETEBUFFERSARBPROC glVBODeleteBuffersARB = NULL; // VBO Data Deleting Procedure
100
101int VBOExtension = 0;
102int VBOenabled = 1;
103
104#define VBO_NOT_INITIALIZED -1
105#define VBO_ERROR 0
106#define VBO_OK 1
107
108#ifndef WNT
109#define glGetProcAddress( x ) glXGetProcAddress( (const GLubyte*) x )
110#else
111#define glGetProcAddress( x ) wglGetProcAddress( x )
112#endif
113
114void clearRAMMemory( CALL_DEF_PARRAY* p )
115{
116 if( p->bufferVBO[VBOEdges] ){
117 Standard::Free((Standard_Address&)p->edges);
118 p->edges = NULL;
119 }
120 if( p->bufferVBO[VBOVertices] ){
121 Standard::Free((Standard_Address&)p->vertices);
122 p->vertices = NULL;
123 }
124 if( p->bufferVBO[VBOVcolours] ){
125 Standard::Free((Standard_Address&)p->vcolours);
126 p->vcolours = NULL;
127 }
128 if( p->bufferVBO[VBOVnormals] ){
129 Standard::Free((Standard_Address&)p->vnormals);
130 p->vnormals = NULL;
131 }
132 if( p->bufferVBO[VBOVtexels] ){
133 Standard::Free((Standard_Address&)p->vtexels);
134 p->vtexels = NULL;
135 }
136 if( p->edge_vis ){
137 Standard::Free((Standard_Address&)p->edge_vis);
138 p->edge_vis = NULL;
139 }
140}
141
142void clearGraphicRAMMemory( CALL_DEF_PARRAY* p )
143{
144 if( p->bufferVBO[VBOEdges] ){
145 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOEdges]);
146 }
147 if( p->bufferVBO[VBOVertices] ){
148 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVertices]);
149 }
150 if( p->bufferVBO[VBOVcolours] ){
151 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVcolours]);
152 }
153 if( p->bufferVBO[VBOVnormals] ){
154 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVnormals]);
155 }
156 if( p->bufferVBO[VBOVtexels] ){
157 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVtexels]);
158 }
159 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
160 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
161}
162
163int checkSizeForGraphicMemory( CALL_DEF_PARRAY* p )
164{
165 if( GL_OUT_OF_MEMORY == glGetError() ){
166 p->flagBufferVBO = VBO_ERROR;
167 clearGraphicRAMMemory(p);
168 }
169 else
170 p->flagBufferVBO = VBO_OK;
171 return p->flagBufferVBO ;
172}
173
174int initVBO()
175{
176 if(CheckExtension((char *)"GL_ARB_vertex_buffer_object",(const char *)glGetString( GL_EXTENSIONS ))){
177 glVBOGenBuffersARB = (PFNGLGENBUFFERSARBPROC) glGetProcAddress("glGenBuffersARB");
178 glVBOBindBufferARB = (PFNGLBINDBUFFERARBPROC) glGetProcAddress("glBindBufferARB");
179 glVBOBufferDataARB = (PFNGLBUFFERDATAARBPROC) glGetProcAddress("glBufferDataARB");
180 glVBODeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) glGetProcAddress("glDeleteBuffersARB");
181 VBOExtension = 1;
182 return 1;
183 }
184 return 0;
185}
186
187static void BuildVBO( CALL_DEF_PARRAY* p )
188{
189 int size_reqd = 0;
190 if( p->edges ){
191 size_reqd = ( p->num_edges * sizeof( Tint ) );
192 glVBOGenBuffersARB( 1, &p->bufferVBO[VBOEdges] );
193 glVBOBindBufferARB( GL_ELEMENTS_ARRAY_BUFFER_ARB, p->bufferVBO[VBOEdges] );
194 glVBOBufferDataARB( GL_ELEMENTS_ARRAY_BUFFER_ARB, size_reqd , p->edges, GL_STATIC_DRAW_ARB );
195 if( checkSizeForGraphicMemory( p ) == VBO_ERROR )
196 return;
197 }
198
199 if( p->vertices ){
200 size_reqd = ( p->num_vertexs * sizeof( TEL_POINT ) );
201 glVBOGenBuffersARB( 1, &p->bufferVBO[VBOVertices]);
202 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVertices] );
203 glVBOBufferDataARB( GL_ARRAY_BUFFER_ARB, size_reqd , p->vertices, GL_STATIC_DRAW_ARB );
204 if( checkSizeForGraphicMemory( p ) == VBO_ERROR )
205 return;
206 }
207
208 if( p->vcolours ){
209 size_reqd = ( p->num_vertexs * sizeof( Tint ) );
210 glVBOGenBuffersARB( 1, &p->bufferVBO[VBOVcolours] );
211 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVcolours]);
212 glVBOBufferDataARB( GL_ARRAY_BUFFER_ARB, size_reqd , p->vcolours, GL_STATIC_DRAW_ARB );
213 if( checkSizeForGraphicMemory( p ) == VBO_ERROR )
214 return;
215 }
216
217 if( p->vnormals ){
218 size_reqd = ( p->num_vertexs * sizeof( TEL_POINT ) );
219 glVBOGenBuffersARB( 1, &p->bufferVBO[VBOVnormals] );
220 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVnormals] );
221 glVBOBufferDataARB( GL_ARRAY_BUFFER_ARB, size_reqd , p->vnormals, GL_STATIC_DRAW_ARB );
222 if( checkSizeForGraphicMemory( p ) == VBO_ERROR)
223 return;
224 }
225
226 if( p->vtexels ){
227 size_reqd = ( p->num_vertexs * sizeof( TEL_TEXTURE_COORD ) );
228 glVBOGenBuffersARB( 1, &p->bufferVBO[VBOVtexels] );
229 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVtexels] );
230 glVBOBufferDataARB( GL_ARRAY_BUFFER_ARB, size_reqd , p->vtexels , GL_STATIC_DRAW_ARB );
231 if( checkSizeForGraphicMemory( p ) == VBO_ERROR )
232 return;
233 }
234
235 if( p->flagBufferVBO == VBO_OK )
236 clearRAMMemory(p);
161c4476
K
237
238 //specify context for VBO resource
239 p->contextId = (Standard_Address)GET_GL_CONTEXT();
240
7fd59977 241}
242
243/*----------------------------------------------------------------------*/
244/*
245* Constantes
246*/
247
248/*----------------------------------------------------------------------*/
249/*
250* Prototypes
251*/
252
253static TStatus ParrayDisplay( TSM_ELEM_DATA, Tint, cmn_key* );
254static TStatus ParrayAdd( TSM_ELEM_DATA, Tint, cmn_key* );
255static TStatus ParrayDelete( TSM_ELEM_DATA, Tint, cmn_key* );
256static TStatus ParrayPrint( TSM_ELEM_DATA, Tint, cmn_key* );
257static TStatus ParrayInquire( TSM_ELEM_DATA, Tint, cmn_key* );
258
259/*static GLboolean lighting_mode;*/
260
261static void draw_array(
262 call_def_parray,
263 Tint, /* highlight_flag */
264 Tint, /* front_lighting_model, */
265 Tint, /* interior_style, */
266 Tint, /* edge_flag, */
267 tel_colour, /* interior_colour, */
268 tel_colour, /* line_colour, */
269 tel_colour /* edge_colour, */
270#ifdef OCC7833
271 ,tel_surf_prop
272#endif
273 );
274
275static void draw_edges ( call_def_parray, tel_colour );
276static void draw_degenerates_as_points ( call_def_parray, tel_colour );
277static void draw_degenerates_as_lines ( call_def_parray, tel_colour );
278static void draw_degenerates_as_bboxs ( call_def_parray, tel_colour );
279
280static TStatus (*MtdTbl[])( TSM_ELEM_DATA, Tint, cmn_key* ) =
281{
282 NULL, /* PickTraverse */
283 ParrayDisplay,
284 ParrayAdd,
285 ParrayDelete,
286 0,
287 0
288};
289static GLenum draw_mode;
290
291/*----------------------------------------------------------------------*/
292/*
293* Variables externes
294*/
295
296extern Tint ForbidSetTextureMapping; /* currently defined in tsm/tsm.c */
297
298extern int g_nDegenerateModel;
299extern float g_fSkipRatio;
300
301/*----------------------------------------------------------------------*/
302
303MtblPtr
304TelParrayInitClass( TelType* el )
305{
306 *el = TelParray;
307 return MtdTbl;
308}
309
310/*----------------------------------------------------------------------*/
311
312static TStatus
313ParrayAdd( TSM_ELEM_DATA d, Tint n, cmn_key *k )
314{
315
316 if( k[0]->id != PARRAY_ID ) return TFailure;
317
318 ((tsm_elem_data)(d.pdata))->pdata = k[0]->data.pdata;
319
320 return TSuccess;
321}
322
323/*----------------------------------------------------------------------*/
324
325static TStatus
326ParrayDisplay( TSM_ELEM_DATA data, Tint n, cmn_key *k )
327{
328 CMN_KEY k11, k12, k17, k18, k111, k114, k115;
329
330 Tint front_lighting_model;
331 Tint interior_style;
332 TEL_COLOUR interior_colour;
333 TEL_COLOUR edge_colour;
334 TEL_COLOUR line_colour;
335 Tint edge_flag;
336
337#ifdef OCC7833
338 CMN_KEY k117;
339 TEL_SURF_PROP prop;
340#endif
341
342 call_def_parray d = (call_def_parray)data.pdata;
343
344 k12.id = TelInteriorReflectanceEquation;
345 k17.id = TelInteriorStyle;
346 k18.id = TelEdgeFlag;
347 k111.id = TelInteriorColour;
348 k111.data.pdata = &interior_colour;
349 k114.id = TelEdgeColour;
350 k114.data.pdata = &edge_colour;
351 k115.id = TelPolylineColour;
352 k115.data.pdata = &line_colour;
353
354#ifdef OCC7833
355 k117.id = TelSurfaceAreaProperties;
356 k117.data.pdata = &prop;
357#endif
358
359#ifdef OCC7833
360 TsmGetAttri( 7, &k12, &k17, &k18, &k111, &k114, &k115, &k117 );
361#else
362 TsmGetAttri( 6, &k12, &k17, &k18, &k111, &k114, &k115 );
363#endif
364
365 front_lighting_model = k12.data.ldata;
366 interior_style = k17.data.ldata;
367 edge_flag = k18.data.ldata;
368
369#ifdef PRINT
370 printf("ParrayDisplay type %d\n",d->type);
371#endif
372
373 /*
374 * Use highlight colours
375 */
376
377 if( k[0]->id == TOn ) {
378 TEL_HIGHLIGHT hrep;
379
380 k11.id = TelHighlightIndex;
381 TsmGetAttri( 1, &k11 );
382 if( TelGetHighlightRep( TglActiveWs, k11.data.ldata, &hrep ) == TSuccess ) {
383 if( hrep.type == TelHLForcedColour ) {
384 edge_colour = interior_colour = line_colour = hrep.col;
385 front_lighting_model = CALL_PHIGS_REFL_NONE;
386 } else if( hrep.type == TelHLColour ) {
387 edge_colour = hrep.col;
388 k[0]->id = TOff;
389 }
390 } else {
391 TelGetHighlightRep( TglActiveWs, 0, &hrep );
392 if( hrep.type == TelHLForcedColour ) {
393 edge_colour = interior_colour = line_colour = hrep.col;
394 front_lighting_model = CALL_PHIGS_REFL_NONE;
395 } else if( hrep.type == TelHLColour ) {
396 edge_colour = hrep.col;
397 k[0]->id = TOff;
398 }
399 }
400 }
401
402 draw_array( d, k[0]->id,
403 front_lighting_model,
404 interior_style,
405 edge_flag,
406 &interior_colour,
407 &line_colour,
408 &edge_colour
409#ifdef OCC7833
410 ,&prop
411#endif
412 );
413
414 return TSuccess;
415
416}
417
418/*----------------------------------------------------------------------*/
419
420static void
421draw_primitive_array( call_def_parray p, GLenum mode, GLint first, GLsizei count )
422{
423 int i;
424 glBegin( mode );
425 for( i=first; i<(first + count); i++ ){
426 if( p->vnormals )
427 glNormal3fv( p->vnormals[i].xyz );
428 if( p->vtexels && !ForbidSetTextureMapping )
429 glTexCoord3fv( p->vtexels[i].xy );
430 if( p->vertices )
431 glVertex3fv( p->vertices[i].xyz );
432 if ( p->vcolours )
433 glColor4ubv( (GLubyte*) p->vcolours[i] );
434 }
435 glEnd();
436}
437
438/*----------------------------------------------------------------------*/
439static void
440draw_primitive_elements( call_def_parray p, GLenum mode, GLsizei count, GLenum type, GLenum *indices )
441{
442 int i;
443 GLenum index;
444 glBegin( mode );
445 for( i=0; i<count; i++ ){
446 index = indices[i];
447 if( p->vnormals )
448 glNormal3fv( p->vnormals[index].xyz );
449 if( p->vtexels && !ForbidSetTextureMapping )
450 glTexCoord3fv( p->vtexels[index].xy );
451 if( p->vertices )
452 glVertex3fv( p->vertices[index].xyz );
453 if ( p->vcolours )
454 glColor4ubv( (GLubyte*) p->vcolours[index] );
455 }
456 glEnd();
457}
458/*----------------------------------------------------------------------*/
459static void
460draw_array( call_def_parray p, Tint hflag,
461 Tint lighting_model,
462 Tint interior_style,
463 Tint edge_flag,
464 tel_colour interior_colour,
465 tel_colour line_colour,
466 tel_colour edge_colour
467#ifdef OCC7833
468 ,tel_surf_prop prop
469#endif
470 ){
471 Tint i,n;
472 Tint transp = 0;
473 GLint renderMode;
474 /* Following pointers have been provided for performance improvement */
475 tel_colour pfc;
476 Tint * pvc;
477
478 pvc = p->vcolours;
479 pfc = p->fcolours;
480
481#ifdef OCC7833
482 if( pvc ){
483 for( i=0; i<p->num_vertexs; i++ ){
484 transp = (int)(prop->trans * 255.);
485#if defined (sparc) || defined (__sparc__) || defined (__sparc)
486 pvc[i] = ( pvc[i] & 0xffffff00 );
487 pvc[i] += transp ;
488
489#else
490 pvc[i] = ( pvc[i] & 0x00ffffff );
491 pvc[i] += transp << 24;
492#endif
493 }
494 }
495#endif
496
497 switch( p->type ) {
498 case TelPointsArrayType:
499 draw_mode = GL_POINTS;
500 glColor3fv( line_colour->rgb );
501 break;
502 case TelPolylinesArrayType:
503 draw_mode = GL_LINE_STRIP;
504 glColor3fv( line_colour->rgb );
505 break;
506 case TelSegmentsArrayType:
507 draw_mode = GL_LINES;
508 glColor3fv( line_colour->rgb );
509 break;
510 case TelPolygonsArrayType:
511 draw_mode = GL_POLYGON;
512 glColor3fv( interior_colour->rgb );
513 break;
514 case TelTrianglesArrayType:
515 draw_mode = GL_TRIANGLES;
516 glColor3fv( interior_colour->rgb );
517 break;
518 case TelQuadranglesArrayType:
519 draw_mode = GL_QUADS;
520 glColor3fv( interior_colour->rgb );
521 break;
522 case TelTriangleStripsArrayType:
523 draw_mode = GL_TRIANGLE_STRIP;
524 glColor3fv( interior_colour->rgb );
525 break;
526 case TelQuadrangleStripsArrayType:
527 draw_mode = GL_QUAD_STRIP;
528 glColor3fv( interior_colour->rgb );
529 break;
530 case TelTriangleFansArrayType:
531 draw_mode = GL_TRIANGLE_FAN;
532 glColor3fv( interior_colour->rgb );
533 break;
534 default:
535 return;
536 }
537
538 /* OCC11904 -- Temporarily disable environment mapping */
539 if( draw_mode <= GL_LINE_STRIP ){
540 glPushAttrib(GL_ENABLE_BIT);
541 glDisable(GL_TEXTURE_1D);
542 glDisable(GL_TEXTURE_2D);
543 }
544
545 if( p->VBOEnabled == -1 ){
546 p->VBOEnabled = VBOenabled;
547 if( VBOExtension == 0)
548 initVBO();
549 if( (VBOExtension == 1) && (p->VBOEnabled != 0))
550 BuildVBO( p );
551 }
552
553
554 #ifdef PRINT
555 printf(" $$$ g_nDegenerateModel %d\n",g_nDegenerateModel);
556 #endif
557 if ( g_nDegenerateModel < 2 &&
558 ( (draw_mode > GL_LINE_STRIP && interior_style != TSM_EMPTY) ||
559 (draw_mode <= GL_LINE_STRIP /*&& !hflag*/)) ) {
560
561 if( hflag == TOn ) {
562 pfc = NULL;
563 pvc = NULL;
564 }
565
566 if ( interior_style == TSM_HIDDENLINE) {
567 edge_flag = 1;
568 pfc = NULL;
569 pvc = NULL;
570 }
571
572 /*OCC12297 - Sometimes the GL_LIGHTING mode is activated here
573 without LightOn() call for an unknown reason, so it is necessary
574 to call LightOn() to synchronize LightOn/Off mechanism*/
575 LightOn();
576
577 if( lighting_model == CALL_PHIGS_REFL_NONE || draw_mode <= GL_LINE_STRIP )
578 LightOff();
579
580 glGetIntegerv( GL_RENDER_MODE, &renderMode );
581
582 if ( p->num_vertexs > 0 && p->flagBufferVBO != VBO_OK) {
583 if( renderMode != GL_FEEDBACK ){
584 if( p->vertices ) {
585 glVertexPointer(3, GL_FLOAT, 0, p->vertices);/* array of vertices */
586 glEnableClientState(GL_VERTEX_ARRAY);
587 }
588
589 if( p->vnormals ) {
590 glNormalPointer(GL_FLOAT, 0, p->vnormals);/* array of normals */
591 glEnableClientState(GL_NORMAL_ARRAY);
592 }
593
594 if ( p->vtexels) {
595 glTexCoordPointer(2, GL_FLOAT, 0, p->vtexels);/* array of texture coordinates */
596 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
597 }
598
599 if ( pvc ) {
600#ifdef OCC7833
601 glColorPointer(4, GL_UNSIGNED_BYTE, 0, pvc); /* array of colors */
602#else
603 glColorPointer(3, GL_UNSIGNED_BYTE, 0, pvc); /* array of colors */
604#endif
605 glEnableClientState(GL_COLOR_ARRAY);
606 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
607 glEnable(GL_COLOR_MATERIAL);
608 }
609 }
610 }
611
612 //Bindings concrete pointer in accordance with VBO buffer
613 //Using VBO
614 if ( p->num_vertexs > 0 && p->flagBufferVBO == VBO_OK ) {
615 if( p->bufferVBO[VBOVertices] ){
616 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVertices]);
617 glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);// array of vertices
618 glEnableClientState(GL_VERTEX_ARRAY);
619 }
620
621 if( p->bufferVBO[VBOVnormals] ){
622 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVnormals]);
623 glNormalPointer(GL_FLOAT, 0, (char *) NULL);// array of normals
624 glEnableClientState(GL_NORMAL_ARRAY);
625 }
626
627 if ( p->bufferVBO[VBOVtexels] && !ForbidSetTextureMapping ) {
628 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVtexels]);
629 glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL);/* array of texture coordinates */
630 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
631 }
632
633 if ( p->bufferVBO[VBOVcolours] ) {
634 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVcolours]);
635 glColorPointer( 4, GL_UNSIGNED_BYTE, 0, (char *) NULL);// array of colors
636 glEnableClientState(GL_COLOR_ARRAY);
637 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
638 glEnable(GL_COLOR_MATERIAL);
639 }
640 }
641 // OCC22236 NOTE: draw for all situations:
642 // 1) draw elements from p->bufferVBO[VBOEdges] indicies array
643 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
644 //end bindings
645 if( p->flagBufferVBO == VBO_OK ){
646 if ( p->num_edges > 0 && p->bufferVBO[VBOEdges] ) {
647 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, p->bufferVBO[VBOEdges]); // for edge indices
648 glDrawElements( draw_mode, p->num_edges , GL_UNSIGNED_INT, 0);
649 }
650 else {
651 for( i = n = 0 ; i < p->num_bounds ; i ++ ){
652 glDrawArrays( draw_mode, n, p->bounds[i]);
653 n += p->bounds[i];
654 }
655 }
656 //bind with 0
657 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
658 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
659 }
660 else {
661 if( p->num_bounds > 0 ) {
662 if( p->num_edges > 0 ) {
663 for( i=n=0 ; i<p->num_bounds ; i++ ) {
664 if( pfc ) glColor3fv ( pfc[i].rgb );
665 if( renderMode == GL_FEEDBACK )
666 draw_primitive_elements( p, draw_mode, p->bounds[i],
667 GL_UNSIGNED_INT,(GLenum*) &p->edges[n]);
668 else
669 glDrawElements( draw_mode, p->bounds[i],
670 GL_UNSIGNED_INT, &p->edges[n]);
671 n += p->bounds[i];
672 }
673 } else {
674 for( i=n=0 ; i<p->num_bounds ; i++ ) {
675 if( pfc )
676 glColor3fv ( pfc[i].rgb );
677 if( renderMode == GL_FEEDBACK )
678 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
679 else
680 {
681 glDrawArrays( draw_mode, n, p->bounds[i]);
682 }
683 n += p->bounds[i];
684 }
685 }
686 } else if( p->num_edges > 0 ) {
687 if( renderMode == GL_FEEDBACK )
688 draw_primitive_elements( p, draw_mode, p->num_edges,
689 GL_UNSIGNED_INT,(GLenum*) &p->edges[0]);
690 else
691 glDrawElements( draw_mode, p->num_edges, GL_UNSIGNED_INT, p->edges);
692 } else {
693 if( renderMode == GL_FEEDBACK )
694 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
695 else
696 glDrawArrays( draw_mode, 0, p->num_vertexs);
697 }
698 }
699
700#ifdef TEST
701 if( p->bufferVBO[VBOVcolours] || pvc ) {
702 glDisable(GL_COLOR_MATERIAL);
703 TelResetMaterial();
704 }
705#endif
706
707 if( p->bufferVBO[VBOVertices] || p->vertices )
708 glDisableClientState(GL_VERTEX_ARRAY);
709 if( p->bufferVBO[VBOVcolours] || p->vcolours )
710 glDisableClientState(GL_COLOR_ARRAY);
711 if( p->bufferVBO[VBOVnormals] || p->vnormals )
712 glDisableClientState(GL_NORMAL_ARRAY);
713 if ( (p->bufferVBO[VBOVtexels] && !ForbidSetTextureMapping ) || p->vtexels )
714 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
715
716 if ( g_nDegenerateModel ){
717 if(draw_mode <= GL_LINE_STRIP)
718 glPopAttrib();
719 return;
720 }
721 }
722
723 if( edge_flag || g_nDegenerateModel )
724 switch ( g_nDegenerateModel ) {
725 default: /* XXX_TDM_NODE or TINY */
726 /*
727 On some NVIDIA graphic cards, using glEdgeFlagPointer() in
728 combination with VBO ( edge flag data put into a VBO buffer)
729 leads to a crash in a driver. Therefore, edge flags are simply
730 igonored when VBOs are enabled, so all the edges are drawn if
731 edge visibility is turned on. In order to draw edges selectively,
732 either disable VBO or turn off edge visibilty in the current
733 primitive array and create a separate primitive array (segments)
734 and put edges to be drawn into it.
735 */
736 draw_edges ( p, edge_flag ? edge_colour : interior_colour );
737 break;
738 // DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
739 case 2: /* XXX_TDM_WIREFRAME */
740 if( p->VBOEnabled == 0 )
741 draw_degenerates_as_lines ( p, edge_flag ? edge_colour : interior_colour );
742 break;
743 case 3: /* XXX_TDM_MARKER */
744 if( p->VBOEnabled == 0 )
745 draw_degenerates_as_points ( p, edge_flag ? edge_colour : interior_colour );
746 break;
747 case 4: /* XXX_TDM_BBOX */
748 if( p->VBOEnabled == 0 )
749 draw_degenerates_as_bboxs ( p, edge_flag ? edge_colour : interior_colour );
750 break;
751 }
752
753 if(draw_mode <= GL_LINE_STRIP)
754 glPopAttrib();
755}
756
757/*----------------------------------------------------------------------*/
758
759static TStatus
760ParrayDelete( TSM_ELEM_DATA data, Tint n, cmn_key *k )
761{
161c4476
K
762 call_def_parray p = (call_def_parray)data.pdata;
763 if( p->VBOEnabled == VBO_OK ) {
764 OpenGl_ResourceCleaner* resCleaner = OpenGl_ResourceCleaner::GetInstance();
765 if( p->bufferVBO[VBOEdges] )
766 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOEdges]) );
767 if( p->bufferVBO[VBOVertices] )
768 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVertices]) );
769 if( p->bufferVBO[VBOVcolours] )
770 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVcolours]) );
771 if( p->bufferVBO[VBOVnormals] )
772 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVnormals]) );
773 if( p->bufferVBO[VBOVtexels] )
774 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVtexels]) );
775 }
776
7fd59977 777 return TSuccess;
778}
779
780/*----------------------------------------------------------------------*/
781
782static void
783draw_edges ( call_def_parray p, tel_colour edge_colour )
784{
785 Tint i, j, n;
786 Tint edge_type=0, line_type_preserve=0;
787 Tfloat edge_width=0, line_width_preserve=0;
788 /* GLboolean texture_on;*/
789
790 GLint renderMode;
791
792 LightOff();
793
794 if( draw_mode > GL_LINE_STRIP ) {
795 CMN_KEY k, k1, k2, k3, k4;
796
797 k1.id = TelPolylineWidth;
798 k2.id = TelPolylineType;
799 k3.id = TelEdgeType;
800 k4.id = TelEdgeWidth;
801
802 TsmGetAttri( 4, &k1, &k2, &k3, &k4 );
803
804 line_width_preserve = k1.data.fdata;
805 line_type_preserve = k2.data.ldata;
806 edge_type = k3.data.ldata;
807 edge_width = k4.data.fdata;
808
809 if( line_width_preserve != edge_width ) {
810 k.id = TelPolylineWidth;
811 k.data.fdata = edge_width;
812 TsmSetAttri( 1, &k );
813 }
814 if( line_type_preserve != edge_type ) {
815 k.id = TelPolylineType;
816 k.data.ldata = edge_type;
817 TsmSetAttri( 1, &k );
818 }
819
820 glPushAttrib( GL_POLYGON_BIT );
821 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
822 }
823
824 // OCC22236 NOTE: draw edges for all situations:
825 // 1) draw elements with GL_LINE style as edges from p->bufferVBO[VBOEdges] indicies array
826 // 2) draw elements with GL_LINE style as edges from vertice array,
827 // when bounds defines count of primitive's verts.
828 if(p->flagBufferVBO == VBO_OK)
829 {
830 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVertices] );
831 glEnableClientState( GL_VERTEX_ARRAY );
832 glColor3fv( edge_colour->rgb );
833 if ( p->num_edges > 0 && p->bufferVBO[VBOEdges] ) {
834 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, p->bufferVBO[VBOEdges]);
835 glDrawElements( draw_mode, p->num_edges, GL_UNSIGNED_INT, 0);
836 }
837 else {
838 for( i = n = 0 ; i < p->num_bounds ; i ++ ) {
839 glDrawArrays( draw_mode , n , p->bounds[i]);
840 n += p->bounds[i];
841 }
842 }
843 glDisableClientState(GL_VERTEX_ARRAY);
844 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
845 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
846 }
847 else {
848
849 glEnableClientState(GL_VERTEX_ARRAY);
850 glVertexPointer(3, GL_FLOAT, 0, p->vertices); /* array of vertices */
851#ifdef OGLBUG
852 if( p->edge_vis ) {
853 glEnableClientState(GL_EDGE_FLAG_ARRAY);
854 glEdgeFlagPointer( sizeof(Tchar), p->edge_vis);
855 } else
856 glDisableClientState(GL_EDGE_FLAG_ARRAY);
857#endif
858
859 glGetIntegerv( GL_RENDER_MODE, &renderMode );
860
861 glColor3fv( edge_colour->rgb );
862 if( p->num_bounds > 0 ) {
863 if( p->num_edges > 0 ) {
864 for( i=n=0 ; i<p->num_bounds ; i++ ) {
865#ifndef OGLBUG
866 if( p->edge_vis ) {
867 glBegin( draw_mode );
868 for( j=0 ; j<p->bounds[i] ; j++ ) {
869 glEdgeFlag( p->edge_vis[n+j] );
870 glVertex3fv( &p->vertices[p->edges[n+j]].xyz[0] );
871 }
872 glEnd();
873 } else
874#endif
875 if( renderMode == GL_FEEDBACK )
876 draw_primitive_elements( p, draw_mode, p->bounds[i],
877 GL_UNSIGNED_INT, (GLenum*)&p->edges[n]);
878 else
879 glDrawElements( draw_mode, p->bounds[i],
880 GL_UNSIGNED_INT, &p->edges[n]);
881 n += p->bounds[i];
882 }
883 } else {
884 for( i=n=0 ; i<p->num_bounds ; i++ ) {
885 if( renderMode == GL_FEEDBACK )
886 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
887 else
888 glDrawArrays( draw_mode, n, p->bounds[i]);
889 n += p->bounds[i];
890 }
891 }
892 }
893 else if( p->num_edges > 0 ) {
894#ifndef OGLBUG
895 if( p->edge_vis ) {
896 glBegin( draw_mode );
897 for( i=0 ; i<p->num_edges ; i++ ) {
898 glEdgeFlag( p->edge_vis[i] );
899 glVertex3fv( &p->vertices[p->edges[i]].xyz[0] );
900 }
901 glEnd();
902 } else
903#endif
904 if( renderMode == GL_FEEDBACK )
905 draw_primitive_elements( p, draw_mode, p->num_edges,
906 GL_UNSIGNED_INT,(GLenum*) p->edges);
907 else
908 glDrawElements( draw_mode, p->num_edges,
909 GL_UNSIGNED_INT, p->edges);
910 } else {
911 if( renderMode == GL_FEEDBACK )
912 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
913 else
914 glDrawArrays( draw_mode, 0, p->num_vertexs);
915 }
916 }
917
918 if( draw_mode > GL_LINE_STRIP ) {
919 CMN_KEY k;
920 if( line_width_preserve != edge_width ) {
921 k.id = TelPolylineWidth;
922 k.data.fdata = line_width_preserve;
923 TsmSetAttri( 1, &k );
924 }
925 if( line_type_preserve != edge_type ) {
926 k.id = TelPolylineType;
927 k.data.ldata = line_type_preserve;
928 TsmSetAttri( 1, &k );
929 }
930 glPopAttrib();
931 }
932}
933
934/*----------------------------------------------------------------------*/
935static void draw_degenerates_points_as_points ( call_def_parray p ) {
936
937 Tint j;
938 tel_point pv = p -> vertices;
939
940#ifdef FULL_DEGENER
941 if ( g_fSkipRatio == 1. )
942 return;
943#endif
944
945 for ( j=0 ; j<p->num_vertexs ; j++ ) {
946 glVertex3fv ( &pv[j].xyz[0] );
947 }
948}
949
950/*----------------------------------------------------------------------*/
951static void draw_degenerates_lines_as_points ( call_def_parray p ) {
952
953 Tint j;
954 GLfloat pt[ 3 ];
955 tel_point pv = p -> vertices;
956
957#ifdef FULL_DEGENER
958 if ( g_fSkipRatio == 1. )
959 return;
960#endif
961
962 for ( j=0 ; j<p->num_vertexs ; j+=2 ) {
963 pt[0] = pt[1] = pt[2] = 0.;
964 pt[ 0 ] += pv[j].xyz[ 0 ];
965 pt[ 1 ] += pv[j].xyz[ 1 ];
966 pt[ 2 ] += pv[j].xyz[ 2 ];
967 pt[ 0 ] += pv[j+1].xyz[ 0 ];
968 pt[ 1 ] += pv[j+1].xyz[ 1 ];
969 pt[ 2 ] += pv[j+1].xyz[ 2 ];
970 pt[ 0 ] /= 2;
971 pt[ 1 ] /= 2;
972 pt[ 2 ] /= 2;
973 glVertex3fv ( pt );
974 }
975}
976
977/*----------------------------------------------------------------------*/
978static void draw_degenerates_triangles_as_points ( call_def_parray p ) {
979
980 Tint i, j, iv;
981 GLfloat pt[ 3 ];
982 tel_point pv = p -> vertices;
983
984#ifdef FULL_DEGENER
985 if ( g_fSkipRatio == 1. )
986 return;
987#endif
988
989 if( p->num_edges > 0 ) {
990 for ( j=0 ; j<p->num_edges ; j+=3 ) {
991 pt[0] = pt[1] = pt[2] = 0.;
992 for ( i=0 ; i<3 ; i++ ) {
993 iv = p->edges[j+i];
994 pt[ 0 ] += pv[iv].xyz[ 0 ];
995 pt[ 1 ] += pv[iv].xyz[ 1 ];
996 pt[ 2 ] += pv[iv].xyz[ 2 ];
997 }
998 pt[ 0 ] /= 3;
999 pt[ 1 ] /= 3;
1000 pt[ 2 ] /= 3;
1001 glVertex3fv ( pt );
1002 }
1003 } else {
1004 for ( j=0 ; j<p->num_vertexs ; j+=3 ) {
1005 pt[0] = pt[1] = pt[2] = 0.;
1006 for ( i=0 ; i<3 ; i++ ) {
1007 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1008 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1009 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1010 }
1011 pt[ 0 ] /= 3;
1012 pt[ 1 ] /= 3;
1013 pt[ 2 ] /= 3;
1014 glVertex3fv ( pt );
1015 }
1016 }
1017}
1018
1019/*----------------------------------------------------------------------*/
1020static void draw_degenerates_trianglestrips_as_points ( call_def_parray p ) {
1021
1022 Tint i, j, k, n;
1023 GLfloat pt[ 3 ];
1024 tel_point pv = p -> vertices;
1025
1026#ifdef FULL_DEGENER
1027 if ( g_fSkipRatio == 1. )
1028 return;
1029#endif
1030
1031 if( p->num_bounds > 0 ) {
1032 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1033 for ( j=0 ; j<p->bounds[k]-2 ; j++ ) {
1034 pt[0] = pt[1] = pt[2] = 0.;
1035 for ( i=0 ; i<3 ; i++ ) {
1036 pt[ 0 ] += pv[n+j+i].xyz[ 0 ];
1037 pt[ 1 ] += pv[n+j+i].xyz[ 1 ];
1038 pt[ 2 ] += pv[n+j+i].xyz[ 2 ];
1039 }
1040 pt[ 0 ] /= 3;
1041 pt[ 1 ] /= 3;
1042 pt[ 2 ] /= 3;
1043 glVertex3fv ( pt );
1044 }
1045 n += p->bounds[k];
1046 }
1047 } else {
1048 for ( j=0 ; j<p->num_vertexs-2 ; j++ ) {
1049 pt[0] = pt[1] = pt[2] = 0.;
1050 for ( i=0 ; i<3 ; i++ ) {
1051 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1052 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1053 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1054 }
1055 pt[ 0 ] /= 3;
1056 pt[ 1 ] /= 3;
1057 pt[ 2 ] /= 3;
1058 glVertex3fv ( pt );
1059 }
1060 }
1061}
1062
1063/*----------------------------------------------------------------------*/
1064static void draw_degenerates_polygons_as_points ( call_def_parray p ) {
1065
1066 Tint j, k, n, iv;
1067 GLfloat pt[ 3 ];
1068 tel_point pv = p -> vertices;
1069
1070#ifdef FULL_DEGENER
1071 if ( g_fSkipRatio == 1. )
1072 return;
1073#endif
1074
1075 if( p->num_bounds > 0 ) {
1076 if( p->num_edges > 0 ) {
1077 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1078 pt[0] = pt[1] = pt[2] = 0.;
1079 for ( j=0 ; j<p->bounds[k] ; j++ ) {
1080 iv = p->edges[n+j];
1081 pt[ 0 ] += pv[iv].xyz[ 0 ];
1082 pt[ 1 ] += pv[iv].xyz[ 1 ];
1083 pt[ 2 ] += pv[iv].xyz[ 2 ];
1084 }
1085 pt[ 0 ] /= p->bounds[k];
1086 pt[ 1 ] /= p->bounds[k];
1087 pt[ 2 ] /= p->bounds[k];
1088 glVertex3fv ( pt );
1089 n += p->bounds[k];
1090 }
1091 } else {
1092 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1093 pt[0] = pt[1] = pt[2] = 0.;
1094 for ( j=0 ; j<p->bounds[k] ; j++ ) {
1095 pt[ 0 ] += pv[n+j].xyz[ 0 ];
1096 pt[ 1 ] += pv[n+j].xyz[ 1 ];
1097 pt[ 2 ] += pv[n+j].xyz[ 2 ];
1098 }
1099 pt[ 0 ] /= p->bounds[k];
1100 pt[ 1 ] /= p->bounds[k];
1101 pt[ 2 ] /= p->bounds[k];
1102 glVertex3fv ( pt );
1103 n += p->bounds[k];
1104 }
1105 }
1106 } else if( p->num_edges > 0 ) {
1107 pt[0] = pt[1] = pt[2] = 0.;
1108 for ( j=0 ; j<p->num_edges ; j++ ) {
1109 iv = p->edges[j];
1110 pt[ 0 ] += pv[iv].xyz[ 0 ];
1111 pt[ 1 ] += pv[iv].xyz[ 1 ];
1112 pt[ 2 ] += pv[iv].xyz[ 2 ];
1113 }
1114 pt[ 0 ] /= p->num_edges;
1115 pt[ 1 ] /= p->num_edges;
1116 pt[ 2 ] /= p->num_edges;
1117 glVertex3fv ( pt );
1118 } else {
1119 pt[0] = pt[1] = pt[2] = 0.;
1120 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1121 pt[ 0 ] += pv[j].xyz[ 0 ];
1122 pt[ 1 ] += pv[j].xyz[ 1 ];
1123 pt[ 2 ] += pv[j].xyz[ 2 ];
1124 }
1125 pt[ 0 ] /= p->num_vertexs;
1126 pt[ 1 ] /= p->num_vertexs;
1127 pt[ 2 ] /= p->num_vertexs;
1128 glVertex3fv ( pt );
1129 }
1130}
1131
1132/*----------------------------------------------------------------------*/
1133static void draw_degenerates_quadrangles_as_points ( call_def_parray p ) {
1134
1135 Tint i, j, iv;
1136 GLfloat pt[ 3 ];
1137 tel_point pv = p -> vertices;
1138
1139#ifdef FULL_DEGENER
1140 if ( g_fSkipRatio == 1. )
1141 return;
1142#endif
1143
1144 if( p->num_edges > 0 ) {
1145 for ( j=0 ; j<p->num_edges ; j+=4 ) {
1146 pt[0] = pt[1] = pt[2] = 0.;
1147 for ( i=0 ; i<4 ; i++ ) {
1148 iv = p->edges[j+i];
1149 pt[ 0 ] += pv[iv].xyz[ 0 ];
1150 pt[ 1 ] += pv[iv].xyz[ 1 ];
1151 pt[ 2 ] += pv[iv].xyz[ 2 ];
1152 }
1153 pt[ 0 ] /= 4;
1154 pt[ 1 ] /= 4;
1155 pt[ 2 ] /= 4;
1156 glVertex3fv ( pt );
1157 }
1158 } else {
1159 for ( j=0 ; j<p->num_vertexs ; j+=4 ) {
1160 pt[0] = pt[1] = pt[2] = 0.;
1161 for ( i=0 ; i<4 ; i++ ) {
1162 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1163 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1164 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1165 }
1166 pt[ 0 ] /= 4;
1167 pt[ 1 ] /= 4;
1168 pt[ 2 ] /= 4;
1169 glVertex3fv ( pt );
1170 }
1171 }
1172}
1173
1174/*----------------------------------------------------------------------*/
1175static void draw_degenerates_quadranglestrips_as_points ( call_def_parray p ) {
1176
1177 Tint i, j, k, n;
1178 GLfloat pt[ 3 ];
1179 tel_point pv = p -> vertices;
1180
1181#ifdef FULL_DEGENER
1182 if ( g_fSkipRatio == 1. )
1183 return;
1184#endif
1185
1186 if( p->num_bounds > 0 ) {
1187 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1188 for ( j=0 ; j<p->bounds[k]-2 ; j+=2 ) {
1189 pt[0] = pt[1] = pt[2] = 0.;
1190 for ( i=0 ; i<4 ; i++ ) {
1191 pt[ 0 ] += pv[n+j+i].xyz[ 0 ];
1192 pt[ 1 ] += pv[n+j+i].xyz[ 1 ];
1193 pt[ 2 ] += pv[n+j+i].xyz[ 2 ];
1194 }
1195 pt[ 0 ] /= 4;
1196 pt[ 1 ] /= 4;
1197 pt[ 2 ] /= 4;
1198 glVertex3fv ( pt );
1199 }
1200 n += p->bounds[k];
1201 }
1202 } else {
1203 for ( j=0 ; j<p->num_vertexs-2 ; j+=2 ) {
1204 pt[0] = pt[1] = pt[2] = 0.;
1205 for ( i=0 ; i<4 ; i++ ) {
1206 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1207 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1208 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1209 }
1210 pt[ 0 ] /= 4;
1211 pt[ 1 ] /= 4;
1212 pt[ 2 ] /= 4;
1213 glVertex3fv ( pt );
1214 }
1215 }
1216}
1217
1218/*----------------------------------------------------------------------*/
1219static void draw_degenerates_as_points ( call_def_parray p,
1220 tel_colour edge_colour )
1221{
1222
1223 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1224 LightOff ();
1225 if( zbuff_state ) glDisable(GL_DEPTH_TEST);
1226 glColor3fv( edge_colour->rgb );
1227 glBegin ( GL_POINTS );
1228 switch( draw_mode ) {
1229 case GL_POINTS:
1230 draw_degenerates_points_as_points( p );
1231 break;
1232 case GL_LINES:
1233 draw_degenerates_lines_as_points( p );
1234 break;
1235 case GL_LINE_STRIP:
1236 case GL_POLYGON:
1237 draw_degenerates_polygons_as_points( p );
1238 break;
1239 case GL_TRIANGLES:
1240 draw_degenerates_triangles_as_points( p );
1241 break;
1242 case GL_QUADS:
1243 draw_degenerates_quadrangles_as_points( p );
1244 break;
1245 case GL_TRIANGLE_FAN:
1246 case GL_TRIANGLE_STRIP:
1247 draw_degenerates_trianglestrips_as_points( p );
1248 break;
1249 case GL_QUAD_STRIP:
1250 draw_degenerates_quadranglestrips_as_points( p );
1251 break;
1252 default:
1253 break;
1254 }
1255
1256 glEnd ();
1257
1258 if( zbuff_state ) glEnable(GL_DEPTH_TEST);
1259}
1260
1261/*----------------------------------------------------------------------*/
1262static void draw_degenerates_lines_as_lines ( call_def_parray p ) {
1263
1264 Tint i,j,n,iv;
1265 tel_point pv = p -> vertices;
1266
1267 n = p->num_vertexs;
1268 j = (int)((1.-g_fSkipRatio)*n);
1269 while ( j-- ) {
1270 i = OGL_Rand() % n;
1271 p->keys[i] = -p->keys[i];
1272 };
1273
1274 if( p->num_bounds > 0 ) {
1275 if( p->num_edges > 0 ) {
1276 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1277 glBegin ( GL_LINES );
1278 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1279 iv = p->edges[n+j];
1280 if( p->keys[iv] < 0 ) {
1281 p->keys[iv] = -p->keys[iv];
1282 glVertex3fv ( pv[iv].xyz );
1283 }
1284 }
1285 glEnd();
1286 n += p->bounds[i];
1287 }
1288 } else {
1289 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1290 glBegin ( GL_LINES );
1291 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1292 if( p->keys[n+j] < 0 ) {
1293 p->keys[n+j] = -p->keys[n+j];
1294 glVertex3fv ( pv[n+j].xyz );
1295 }
1296 }
1297 glEnd();
1298 n += p->bounds[i];
1299 }
1300 }
1301 } else if( p->num_edges > 0 ) {
1302 glBegin ( GL_LINES );
1303 for ( j=0 ; j<p->num_edges ; j++ ) {
1304 iv = p->edges[j];
1305 if( p->keys[iv] < 0 ) {
1306 p->keys[iv] = -p->keys[iv];
1307 glVertex3fv ( pv[iv].xyz );
1308 }
1309 }
1310 glEnd();
1311 } else {
1312 glBegin ( GL_LINES );
1313 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1314 if( p->keys[j] < 0 ) {
1315 p->keys[j] = -p->keys[j];
1316 glVertex3fv ( pv[j].xyz );
1317 }
1318 }
1319 glEnd();
1320 }
1321}
1322
1323/*----------------------------------------------------------------------*/
1324static void draw_degenerates_triangles_as_lines ( call_def_parray p )
1325{
1326
1327 Tint i,j,n,iv;
1328 tel_point pv = p -> vertices;
1329
1330 n = p->num_vertexs/3;
1331 j = (int)((1.-g_fSkipRatio)*n);
1332 while ( j-- ) {
1333 i = OGL_Rand() % n; i *= 3;
1334 p->keys[i] = -p->keys[i];
1335 };
1336
1337 if( p->num_edges > 0 ) {
1338 for ( j=0 ; j<p->num_edges ; j+=3 ) {
1339 iv = p->edges[j];
1340 if( p->keys[iv] < 0 ) {
1341 p->keys[iv] = -p->keys[iv];
1342 glBegin ( GL_LINE_LOOP );
1343 for ( i=0 ; i<3 ; i++ ) {
1344 iv = p->edges[j+i];
1345 glVertex3fv ( pv[iv].xyz );
1346 }
1347 glEnd();
1348 }
1349 }
1350 } else {
1351 for ( j=0 ; j<p->num_vertexs ; j+=3 ) {
1352 if( p->keys[j] < 0 ) {
1353 p->keys[j] = -p->keys[j];
1354 glBegin ( GL_LINE_LOOP );
1355 for ( i=0 ; i<3 ; i++ ) {
1356 glVertex3fv ( pv[j+i].xyz );
1357 }
1358 glEnd();
1359 }
1360 }
1361 }
1362}
1363
1364/*----------------------------------------------------------------------*/
1365static void draw_degenerates_trianglestrips_as_lines ( call_def_parray p )
1366{
1367
1368 Tint i,j,k,n,ni;
1369 tel_point pv = p -> vertices;
1370
1371 if( p->num_bounds > 0 ) {
1372 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1373 ni = p->bounds[i]-2;
1374 k = (int)((1.-g_fSkipRatio)*ni);
1375 while ( k-- ) {
1376 j = OGL_Rand() % ni; j += 2;
1377 p->keys[n+j] = -p->keys[n+j];
1378 };
1379 for ( j=2 ; j<p->bounds[i] ; j++ ) {
1380 if( p->keys[n+j] < 0 ) {
1381 p->keys[n+j] = -p->keys[n+j];
1382 glBegin ( GL_LINE_LOOP );
1383 glVertex3fv ( pv[n+j-2].xyz );
1384 glVertex3fv ( pv[n+j-1].xyz );
1385 glVertex3fv ( pv[n+j].xyz );
1386 glEnd();
1387 }
1388 }
1389 n += p->bounds[i];
1390 }
1391 } else {
1392 ni = p->num_vertexs-2;
1393 k = (int)((1.-g_fSkipRatio)*ni);
1394 while ( k-- ) {
1395 j = OGL_Rand() % ni; j += 2;
1396 p->keys[j] = -p->keys[j];
1397 };
1398 for ( j=2 ; j<p->num_vertexs ; j++ ) {
1399 if( p->keys[j] < 0 ) {
1400 p->keys[j] = -p->keys[j];
1401 glBegin ( GL_LINE_LOOP );
1402 glVertex3fv ( pv[j-2].xyz );
1403 glVertex3fv ( pv[j-1].xyz );
1404 glVertex3fv ( pv[j].xyz );
1405 glEnd();
1406 }
1407 }
1408 }
1409}
1410
1411/*----------------------------------------------------------------------*/
1412static void draw_degenerates_polygons_as_lines ( call_def_parray p )
1413{
1414 Tint i,j,n,iv;
1415 tel_point pv = p -> vertices;
1416
1417 n = p->num_vertexs;
1418 j = (int)((1.-g_fSkipRatio)*n);
1419 while ( j-- ) {
1420 i = OGL_Rand() % n;
1421 p->keys[i] = -p->keys[i];
1422 };
1423
1424 if( p->num_bounds > 0 ) {
1425 if( p->num_edges > 0 ) {
1426 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1427 glBegin ( GL_LINE_LOOP );
1428 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1429 iv = p->edges[n+j];
1430 if( p->keys[iv] < 0 ) {
1431 p->keys[iv] = -p->keys[iv];
1432 glVertex3fv ( pv[iv].xyz );
1433 }
1434 }
1435 glEnd();
1436 n += p->bounds[i];
1437 }
1438 } else {
1439 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1440 glBegin ( GL_LINE_LOOP );
1441 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1442 if( p->keys[n+j] < 0 ) {
1443 p->keys[n+j] = -p->keys[n+j];
1444 glVertex3fv ( pv[n+j].xyz );
1445 }
1446 }
1447 glEnd();
1448 n += p->bounds[i];
1449 }
1450 }
1451 } else if( p->num_edges > 0 ) {
1452 glBegin ( GL_LINE_LOOP );
1453 for ( j=0 ; j<p->num_edges ; j++ ) {
1454 iv = p->edges[j];
1455 if( p->keys[iv] < 0 ) {
1456 p->keys[iv] = -p->keys[iv];
1457 glVertex3fv ( pv[iv].xyz );
1458 }
1459 }
1460 glEnd();
1461 } else {
1462 glBegin ( GL_LINE_LOOP );
1463 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1464 if( p->keys[j] < 0 ) {
1465 p->keys[j] = -p->keys[j];
1466 glVertex3fv ( pv[j].xyz );
1467 }
1468 }
1469 glEnd();
1470 }
1471
1472}
1473
1474/*----------------------------------------------------------------------*/
1475static void draw_degenerates_quadrangles_as_lines ( call_def_parray p )
1476{
1477
1478 Tint i,j,n,iv;
1479 tel_point pv = p -> vertices;
1480
1481 n = p->num_vertexs/4;
1482 j = (int)((1.-g_fSkipRatio)*n);
1483 while ( j-- ) {
1484 i = OGL_Rand() % n; i *= 4;
1485 p->keys[i] = -p->keys[i];
1486 };
1487
1488 if( p->num_edges > 0 ) {
1489 for ( j=0 ; j<p->num_edges ; j+=4 ) {
1490 iv = p->edges[j];
1491 if( p->keys[iv] < 0 ) {
1492 p->keys[iv] = -p->keys[iv];
1493 glBegin ( GL_LINE_LOOP );
1494 for ( i=0 ; i<4 ; i++ ) {
1495 iv = p->edges[j+i];
1496 glVertex3fv ( pv[iv].xyz );
1497 }
1498 glEnd();
1499 }
1500 }
1501 } else {
1502 for ( j=0 ; j<p->num_vertexs ; j+=4 ) {
1503 if( p->keys[j] < 0 ) {
1504 p->keys[j] = -p->keys[j];
1505 glBegin ( GL_LINE_LOOP );
1506 for ( i=0 ; i<4 ; i++ ) {
1507 glVertex3fv ( pv[j+i].xyz );
1508 }
1509 glEnd();
1510 }
1511 }
1512 }
1513}
1514
1515/*----------------------------------------------------------------------*/
1516static void draw_degenerates_quadranglestrips_as_lines ( call_def_parray p )
1517{
1518
1519 Tint i,j,k,n,ni;
1520 tel_point pv = p -> vertices;
1521
1522 if( p->num_bounds > 0 ) {
1523 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1524 ni = p->bounds[i]/2-2;
1525 k = (int)((1.-g_fSkipRatio)*ni);
1526 while ( k-- ) {
1527 j = OGL_Rand() % ni; j = j*2+2;
1528 p->keys[n+j] = -p->keys[n+j];
1529 };
1530 for ( j=3 ; j<p->bounds[i] ; j+=2 ) {
1531 if( p->keys[n+j] < 0 ) {
1532 p->keys[n+j] = -p->keys[n+j];
1533 glBegin ( GL_LINE_LOOP );
1534 glVertex3fv ( pv[n+j-3].xyz );
1535 glVertex3fv ( pv[n+j-2].xyz );
1536 glVertex3fv ( pv[n+j-1].xyz );
1537 glVertex3fv ( pv[n+j].xyz );
1538 glEnd();
1539 }
1540 }
1541 n += p->bounds[i];
1542 }
1543 } else {
1544 ni = p->num_vertexs/2-2;
1545 k = (int)((1.-g_fSkipRatio)*ni);
1546 while ( k-- ) {
1547 j = OGL_Rand() % ni; j = j*2+2;
1548 p->keys[j] = -p->keys[j];
1549 };
1550 for ( j=3 ; j<p->num_vertexs ; j+=2 ) {
1551 if( p->keys[j] < 0 ) {
1552 p->keys[j] = -p->keys[j];
1553 glBegin ( GL_LINE_LOOP );
1554 glVertex3fv ( pv[j-3].xyz );
1555 glVertex3fv ( pv[j-2].xyz );
1556 glVertex3fv ( pv[j-1].xyz );
1557 glVertex3fv ( pv[j].xyz );
1558 glEnd();
1559 }
1560 }
1561 }
1562}
1563
1564/*----------------------------------------------------------------------*/
1565static void draw_degenerates_as_lines ( call_def_parray p,
1566 tel_colour edge_colour )
1567{
1568
1569 GLint renderMode;
1570
1571 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1572
1573 LightOff ();
1574
1575 if( zbuff_state ) glDisable(GL_DEPTH_TEST);
1576
1577 glColor3fv( edge_colour->rgb );
1578
1579 if( g_fSkipRatio != 0 ) switch( draw_mode ) {
1580 case GL_POINTS:
1581 draw_degenerates_points_as_points( p );
1582 break;
1583 case GL_LINES:
1584 draw_degenerates_lines_as_lines( p );
1585 break;
1586 case GL_LINE_STRIP:
1587 case GL_POLYGON:
1588 draw_degenerates_polygons_as_lines( p );
1589 break;
1590 case GL_TRIANGLES:
1591 draw_degenerates_triangles_as_lines( p );
1592 break;
1593 case GL_QUADS:
1594 draw_degenerates_quadrangles_as_lines( p );
1595 break;
1596 case GL_TRIANGLE_FAN:
1597 case GL_TRIANGLE_STRIP:
1598 draw_degenerates_trianglestrips_as_lines( p );
1599 break;
1600 case GL_QUAD_STRIP:
1601 draw_degenerates_quadranglestrips_as_lines( p );
1602 break;
1603 default:
1604 break;
1605 }
1606 else {
1607 int i,n;
1608
1609#ifdef OCC3192
1610 GLboolean color_array_mode,
1611 edge_flag_array_mode,
1612 index_array_mode,
1613 normal_array_mode,
1614 texture_coord_array_mode,
1615 vertex_array_mode;
1616#endif
1617 glPushAttrib( GL_POLYGON_BIT );
1618 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
1619
1620#ifdef OCC3192
1621 color_array_mode = glIsEnabled( GL_COLOR_ARRAY );
1622 edge_flag_array_mode = glIsEnabled( GL_EDGE_FLAG_ARRAY );
1623 index_array_mode = glIsEnabled( GL_INDEX_ARRAY );
1624 normal_array_mode = glIsEnabled( GL_NORMAL_ARRAY );
1625 texture_coord_array_mode = glIsEnabled( GL_TEXTURE_COORD_ARRAY );
1626 vertex_array_mode = glIsEnabled( GL_VERTEX_ARRAY );
1627
1628 glDisableClientState( GL_COLOR_ARRAY );
1629 glDisableClientState( GL_EDGE_FLAG_ARRAY );
1630 glDisableClientState( GL_INDEX_ARRAY );
1631 glDisableClientState( GL_NORMAL_ARRAY );
1632 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1633
1634 if( !vertex_array_mode ) glEnableClientState( GL_VERTEX_ARRAY );
1635#else
1636 glEnableClientState( GL_VERTEX_ARRAY );
1637#endif
1638 glVertexPointer(3, GL_FLOAT, 0, p->vertices); /* array of vertices */
1639
1640 glGetIntegerv( GL_RENDER_MODE, &renderMode );
1641
1642 if( p->num_bounds > 0 ) {
1643 if( p->num_edges > 0 ) {
1644 for( i=n=0 ; i<p->num_bounds ; i++ ) {
1645 if( renderMode == GL_FEEDBACK )
1646 draw_primitive_elements( p, draw_mode, p->bounds[i],
1647 GL_UNSIGNED_INT, (GLenum*) &p->edges[n]);
1648 else
1649 glDrawElements( draw_mode, p->bounds[i],
1650 GL_UNSIGNED_INT, &p->edges[n]);
1651 n += p->bounds[i];
1652 }
1653 } else {
1654 for( i=n=0 ; i<p->num_bounds ; i++ ) {
1655 if( renderMode == GL_FEEDBACK )
1656 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
1657 else
1658 glDrawArrays( draw_mode, n, p->bounds[i]);
1659 n += p->bounds[i];
1660 }
1661 }
1662 } else if( p->num_edges > 0 ) {
1663 if( renderMode == GL_FEEDBACK )
1664 draw_primitive_elements( p, draw_mode, p->num_edges,
1665 GL_UNSIGNED_INT, (GLenum*) p->edges);
1666 else
1667 glDrawElements( draw_mode, p->num_edges,
1668 GL_UNSIGNED_INT, p->edges);
1669 } else {
1670 if( renderMode == GL_FEEDBACK )
1671 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
1672 else
1673 glDrawArrays( draw_mode, 0, p->num_vertexs);
1674 }
1675
1676#ifdef OCC3192
1677 if( !vertex_array_mode ) glDisableClientState( GL_VERTEX_ARRAY );
1678
1679 if( color_array_mode ) glEnableClientState( GL_COLOR_ARRAY );
1680 if( edge_flag_array_mode ) glEnableClientState( GL_EDGE_FLAG_ARRAY );
1681 if( index_array_mode ) glEnableClientState( GL_INDEX_ARRAY );
1682 if( normal_array_mode ) glEnableClientState( GL_NORMAL_ARRAY );
1683 if( texture_coord_array_mode ) glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1684#endif
1685 glPopAttrib();
1686 }
1687
1688 if( zbuff_state ) glEnable(GL_DEPTH_TEST);
1689
1690}
1691
1692static void draw_degenerates_as_bboxs ( call_def_parray p,
1693 tel_colour edge_colour )
1694{
1695
1696 Tint i;
1697 GLfloat minp[ 3 ] = { FLT_MAX, FLT_MAX, FLT_MAX };
1698 GLfloat maxp[ 3 ] = { FLT_MIN, FLT_MIN, FLT_MIN };
1699 tel_point pv = p -> vertices;
1700
1701 LightOff ();
1702
1703 glColor3fv( edge_colour->rgb );
1704
1705 for ( i=0 ; i<p->num_vertexs ; ++i ) {
1706 if ( pv[ i ].xyz[ 0 ] < minp[ 0 ] )
1707 minp[ 0 ] = pv[ i ].xyz[ 0 ] ;
1708 if ( pv[ i ].xyz[ 1 ] < minp[ 1 ] )
1709 minp[ 1 ] = pv[ i ].xyz[ 1 ] ;
1710 if ( pv[ i ].xyz[ 2 ] < minp[ 2 ] )
1711 minp[ 2 ] = pv[ i ].xyz[ 2 ] ;
1712
1713 if ( pv[ i ].xyz[ 0 ] > maxp[ 0 ] )
1714 maxp[ 0 ] = pv[ i ].xyz[ 0 ] ;
1715 if ( pv[ i ].xyz[ 1 ] > maxp[ 1 ] )
1716 maxp[ 1 ] = pv[ i ].xyz[ 1 ] ;
1717 if ( pv[ i ].xyz[ 2 ] > maxp[ 2 ] )
1718 maxp[ 2 ] = pv[ i ].xyz[ 2 ] ;
1719 } /* end for ( i ) */
1720
1721 glBegin ( GL_LINE_STRIP );
1722
1723 glVertex3fv ( minp );
1724 glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1725 glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1726 glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1727 glVertex3f ( minp[ 0 ], minp[ 1 ], minp[ 2 ] );
1728
1729 glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
1730 glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1731 glVertex3f ( maxp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1732 glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1733 glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
1734
1735 glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1736 glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1737 glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1738 glVertex3fv ( maxp );
1739 glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1740 glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1741
1742 glEnd();
1743
1744} /* end draw_degenerates_as_bboxs */