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