Merging OCC22105, OCC22354, OCC22150 , OCC22199 , OCC22391 and OCC22108
[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>
d4c2114a 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);
d4c2114a 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.
762aacae 644 // 3) draw primitive by vertexes if no edges and bounds array is specified
7fd59977 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
762aacae
A
648
649 // draw primitives by vertex count with the indicies
650 if( p->num_bounds > 0 ) {
651 Tint* offset = 0;
652 for( i = 0, offset = 0 ; i < p->num_bounds ; i++ ) {
653 glDrawElements(draw_mode, p->bounds[i], GL_UNSIGNED_INT, offset);
654 offset += p->bounds[i];
655 }
656 }
657 // draw one (or sequential) primitive by the indicies
658 else {
659 glDrawElements(draw_mode, p->num_edges , GL_UNSIGNED_INT, 0);
660 }
7fd59977 661 }
762aacae 662 else if( p->num_bounds > 0 ) {
7fd59977 663 for( i = n = 0 ; i < p->num_bounds ; i ++ ){
762aacae 664 glDrawArrays(draw_mode, n, p->bounds[i]);
7fd59977 665 n += p->bounds[i];
666 }
667 }
762aacae
A
668 else {
669 glDrawArrays(draw_mode, 0, p->num_vertexs);
670 }
671
7fd59977 672 //bind with 0
673 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
674 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
675 }
676 else {
677 if( p->num_bounds > 0 ) {
678 if( p->num_edges > 0 ) {
679 for( i=n=0 ; i<p->num_bounds ; i++ ) {
680 if( pfc ) glColor3fv ( pfc[i].rgb );
681 if( renderMode == GL_FEEDBACK )
682 draw_primitive_elements( p, draw_mode, p->bounds[i],
683 GL_UNSIGNED_INT,(GLenum*) &p->edges[n]);
684 else
685 glDrawElements( draw_mode, p->bounds[i],
686 GL_UNSIGNED_INT, &p->edges[n]);
687 n += p->bounds[i];
688 }
689 } else {
690 for( i=n=0 ; i<p->num_bounds ; i++ ) {
691 if( pfc )
692 glColor3fv ( pfc[i].rgb );
693 if( renderMode == GL_FEEDBACK )
694 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
695 else
696 {
697 glDrawArrays( draw_mode, n, p->bounds[i]);
698 }
699 n += p->bounds[i];
700 }
701 }
702 } else if( p->num_edges > 0 ) {
703 if( renderMode == GL_FEEDBACK )
704 draw_primitive_elements( p, draw_mode, p->num_edges,
705 GL_UNSIGNED_INT,(GLenum*) &p->edges[0]);
706 else
707 glDrawElements( draw_mode, p->num_edges, GL_UNSIGNED_INT, p->edges);
708 } else {
709 if( renderMode == GL_FEEDBACK )
710 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
711 else
712 glDrawArrays( draw_mode, 0, p->num_vertexs);
713 }
714 }
715
716#ifdef TEST
717 if( p->bufferVBO[VBOVcolours] || pvc ) {
718 glDisable(GL_COLOR_MATERIAL);
719 TelResetMaterial();
720 }
721#endif
722
723 if( p->bufferVBO[VBOVertices] || p->vertices )
724 glDisableClientState(GL_VERTEX_ARRAY);
725 if( p->bufferVBO[VBOVcolours] || p->vcolours )
726 glDisableClientState(GL_COLOR_ARRAY);
727 if( p->bufferVBO[VBOVnormals] || p->vnormals )
728 glDisableClientState(GL_NORMAL_ARRAY);
729 if ( (p->bufferVBO[VBOVtexels] && !ForbidSetTextureMapping ) || p->vtexels )
730 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
731
732 if ( g_nDegenerateModel ){
733 if(draw_mode <= GL_LINE_STRIP)
734 glPopAttrib();
735 return;
736 }
737 }
738
739 if( edge_flag || g_nDegenerateModel )
740 switch ( g_nDegenerateModel ) {
741 default: /* XXX_TDM_NODE or TINY */
742 /*
743 On some NVIDIA graphic cards, using glEdgeFlagPointer() in
744 combination with VBO ( edge flag data put into a VBO buffer)
745 leads to a crash in a driver. Therefore, edge flags are simply
746 igonored when VBOs are enabled, so all the edges are drawn if
747 edge visibility is turned on. In order to draw edges selectively,
748 either disable VBO or turn off edge visibilty in the current
749 primitive array and create a separate primitive array (segments)
750 and put edges to be drawn into it.
751 */
752 draw_edges ( p, edge_flag ? edge_colour : interior_colour );
753 break;
754 // DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
755 case 2: /* XXX_TDM_WIREFRAME */
756 if( p->VBOEnabled == 0 )
757 draw_degenerates_as_lines ( p, edge_flag ? edge_colour : interior_colour );
758 break;
759 case 3: /* XXX_TDM_MARKER */
760 if( p->VBOEnabled == 0 )
761 draw_degenerates_as_points ( p, edge_flag ? edge_colour : interior_colour );
762 break;
763 case 4: /* XXX_TDM_BBOX */
764 if( p->VBOEnabled == 0 )
765 draw_degenerates_as_bboxs ( p, edge_flag ? edge_colour : interior_colour );
766 break;
767 }
768
769 if(draw_mode <= GL_LINE_STRIP)
770 glPopAttrib();
771}
772
773/*----------------------------------------------------------------------*/
774
775static TStatus
776ParrayDelete( TSM_ELEM_DATA data, Tint n, cmn_key *k )
777{
d4c2114a 778 call_def_parray p = (call_def_parray)data.pdata;
779 if( p->VBOEnabled == VBO_OK ) {
780 OpenGl_ResourceCleaner* resCleaner = OpenGl_ResourceCleaner::GetInstance();
781 if( p->bufferVBO[VBOEdges] )
782 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOEdges]) );
783 if( p->bufferVBO[VBOVertices] )
784 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVertices]) );
785 if( p->bufferVBO[VBOVcolours] )
786 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVcolours]) );
787 if( p->bufferVBO[VBOVnormals] )
788 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVnormals]) );
789 if( p->bufferVBO[VBOVtexels] )
790 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVtexels]) );
791 }
792
7fd59977 793 return TSuccess;
794}
795
796/*----------------------------------------------------------------------*/
797
798static void
799draw_edges ( call_def_parray p, tel_colour edge_colour )
800{
801 Tint i, j, n;
802 Tint edge_type=0, line_type_preserve=0;
803 Tfloat edge_width=0, line_width_preserve=0;
804 /* GLboolean texture_on;*/
805
806 GLint renderMode;
807
808 LightOff();
809
810 if( draw_mode > GL_LINE_STRIP ) {
811 CMN_KEY k, k1, k2, k3, k4;
812
813 k1.id = TelPolylineWidth;
814 k2.id = TelPolylineType;
815 k3.id = TelEdgeType;
816 k4.id = TelEdgeWidth;
817
818 TsmGetAttri( 4, &k1, &k2, &k3, &k4 );
819
820 line_width_preserve = k1.data.fdata;
821 line_type_preserve = k2.data.ldata;
822 edge_type = k3.data.ldata;
823 edge_width = k4.data.fdata;
824
825 if( line_width_preserve != edge_width ) {
826 k.id = TelPolylineWidth;
827 k.data.fdata = edge_width;
828 TsmSetAttri( 1, &k );
829 }
830 if( line_type_preserve != edge_type ) {
831 k.id = TelPolylineType;
832 k.data.ldata = edge_type;
833 TsmSetAttri( 1, &k );
834 }
835
836 glPushAttrib( GL_POLYGON_BIT );
837 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
838 }
839
840 // OCC22236 NOTE: draw edges for all situations:
841 // 1) draw elements with GL_LINE style as edges from p->bufferVBO[VBOEdges] indicies array
762aacae
A
842 // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
843 // 3) draw primitive's edges by vertexes if no edges and bounds array is specified
7fd59977 844 if(p->flagBufferVBO == VBO_OK)
845 {
846 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVertices] );
847 glEnableClientState( GL_VERTEX_ARRAY );
848 glColor3fv( edge_colour->rgb );
849 if ( p->num_edges > 0 && p->bufferVBO[VBOEdges] ) {
850 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, p->bufferVBO[VBOEdges]);
762aacae
A
851
852 // draw primitives by vertex count with the indicies
853 if( p->num_bounds > 0 ) {
854 Tint* offset = 0;
855 for( i = 0, offset = 0 ; i < p->num_bounds ; i++ ) {
856 glDrawElements( draw_mode, p->bounds[i], GL_UNSIGNED_INT, offset);
857 offset += p->bounds[i];
858 }
859 }
860 // draw one (or sequential) primitive by the indicies
861 else {
862 glDrawElements( draw_mode, p->num_edges , GL_UNSIGNED_INT, 0);
863 }
7fd59977 864 }
762aacae
A
865 else if( p->num_bounds > 0 ) {
866 for( i = n = 0 ; i < p->num_bounds ; i ++ ){
867 glDrawArrays( draw_mode, n, p->bounds[i]);
7fd59977 868 n += p->bounds[i];
869 }
870 }
762aacae
A
871 else {
872 glDrawArrays( draw_mode, 0, p->num_vertexs);
873 }
874
875 // unbind buffers
7fd59977 876 glDisableClientState(GL_VERTEX_ARRAY);
877 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
878 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
879 }
880 else {
881
882 glEnableClientState(GL_VERTEX_ARRAY);
883 glVertexPointer(3, GL_FLOAT, 0, p->vertices); /* array of vertices */
884#ifdef OGLBUG
885 if( p->edge_vis ) {
886 glEnableClientState(GL_EDGE_FLAG_ARRAY);
887 glEdgeFlagPointer( sizeof(Tchar), p->edge_vis);
888 } else
889 glDisableClientState(GL_EDGE_FLAG_ARRAY);
890#endif
891
892 glGetIntegerv( GL_RENDER_MODE, &renderMode );
893
894 glColor3fv( edge_colour->rgb );
895 if( p->num_bounds > 0 ) {
896 if( p->num_edges > 0 ) {
897 for( i=n=0 ; i<p->num_bounds ; i++ ) {
898#ifndef OGLBUG
899 if( p->edge_vis ) {
900 glBegin( draw_mode );
901 for( j=0 ; j<p->bounds[i] ; j++ ) {
902 glEdgeFlag( p->edge_vis[n+j] );
903 glVertex3fv( &p->vertices[p->edges[n+j]].xyz[0] );
904 }
905 glEnd();
906 } else
907#endif
908 if( renderMode == GL_FEEDBACK )
909 draw_primitive_elements( p, draw_mode, p->bounds[i],
910 GL_UNSIGNED_INT, (GLenum*)&p->edges[n]);
911 else
912 glDrawElements( draw_mode, p->bounds[i],
913 GL_UNSIGNED_INT, &p->edges[n]);
914 n += p->bounds[i];
915 }
916 } else {
917 for( i=n=0 ; i<p->num_bounds ; i++ ) {
918 if( renderMode == GL_FEEDBACK )
919 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
920 else
921 glDrawArrays( draw_mode, n, p->bounds[i]);
922 n += p->bounds[i];
923 }
924 }
925 }
926 else if( p->num_edges > 0 ) {
927#ifndef OGLBUG
928 if( p->edge_vis ) {
929 glBegin( draw_mode );
930 for( i=0 ; i<p->num_edges ; i++ ) {
931 glEdgeFlag( p->edge_vis[i] );
932 glVertex3fv( &p->vertices[p->edges[i]].xyz[0] );
933 }
934 glEnd();
935 } else
936#endif
937 if( renderMode == GL_FEEDBACK )
938 draw_primitive_elements( p, draw_mode, p->num_edges,
939 GL_UNSIGNED_INT,(GLenum*) p->edges);
940 else
941 glDrawElements( draw_mode, p->num_edges,
942 GL_UNSIGNED_INT, p->edges);
943 } else {
944 if( renderMode == GL_FEEDBACK )
945 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
946 else
947 glDrawArrays( draw_mode, 0, p->num_vertexs);
948 }
949 }
950
951 if( draw_mode > GL_LINE_STRIP ) {
952 CMN_KEY k;
953 if( line_width_preserve != edge_width ) {
954 k.id = TelPolylineWidth;
955 k.data.fdata = line_width_preserve;
956 TsmSetAttri( 1, &k );
957 }
958 if( line_type_preserve != edge_type ) {
959 k.id = TelPolylineType;
960 k.data.ldata = line_type_preserve;
961 TsmSetAttri( 1, &k );
962 }
963 glPopAttrib();
964 }
965}
966
967/*----------------------------------------------------------------------*/
968static void draw_degenerates_points_as_points ( call_def_parray p ) {
969
970 Tint j;
971 tel_point pv = p -> vertices;
972
973#ifdef FULL_DEGENER
974 if ( g_fSkipRatio == 1. )
975 return;
976#endif
977
978 for ( j=0 ; j<p->num_vertexs ; j++ ) {
979 glVertex3fv ( &pv[j].xyz[0] );
980 }
981}
982
983/*----------------------------------------------------------------------*/
984static void draw_degenerates_lines_as_points ( call_def_parray p ) {
985
986 Tint j;
987 GLfloat pt[ 3 ];
988 tel_point pv = p -> vertices;
989
990#ifdef FULL_DEGENER
991 if ( g_fSkipRatio == 1. )
992 return;
993#endif
994
995 for ( j=0 ; j<p->num_vertexs ; j+=2 ) {
996 pt[0] = pt[1] = pt[2] = 0.;
997 pt[ 0 ] += pv[j].xyz[ 0 ];
998 pt[ 1 ] += pv[j].xyz[ 1 ];
999 pt[ 2 ] += pv[j].xyz[ 2 ];
1000 pt[ 0 ] += pv[j+1].xyz[ 0 ];
1001 pt[ 1 ] += pv[j+1].xyz[ 1 ];
1002 pt[ 2 ] += pv[j+1].xyz[ 2 ];
1003 pt[ 0 ] /= 2;
1004 pt[ 1 ] /= 2;
1005 pt[ 2 ] /= 2;
1006 glVertex3fv ( pt );
1007 }
1008}
1009
1010/*----------------------------------------------------------------------*/
1011static void draw_degenerates_triangles_as_points ( call_def_parray p ) {
1012
1013 Tint i, j, iv;
1014 GLfloat pt[ 3 ];
1015 tel_point pv = p -> vertices;
1016
1017#ifdef FULL_DEGENER
1018 if ( g_fSkipRatio == 1. )
1019 return;
1020#endif
1021
1022 if( p->num_edges > 0 ) {
1023 for ( j=0 ; j<p->num_edges ; j+=3 ) {
1024 pt[0] = pt[1] = pt[2] = 0.;
1025 for ( i=0 ; i<3 ; i++ ) {
1026 iv = p->edges[j+i];
1027 pt[ 0 ] += pv[iv].xyz[ 0 ];
1028 pt[ 1 ] += pv[iv].xyz[ 1 ];
1029 pt[ 2 ] += pv[iv].xyz[ 2 ];
1030 }
1031 pt[ 0 ] /= 3;
1032 pt[ 1 ] /= 3;
1033 pt[ 2 ] /= 3;
1034 glVertex3fv ( pt );
1035 }
1036 } else {
1037 for ( j=0 ; j<p->num_vertexs ; j+=3 ) {
1038 pt[0] = pt[1] = pt[2] = 0.;
1039 for ( i=0 ; i<3 ; i++ ) {
1040 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1041 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1042 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1043 }
1044 pt[ 0 ] /= 3;
1045 pt[ 1 ] /= 3;
1046 pt[ 2 ] /= 3;
1047 glVertex3fv ( pt );
1048 }
1049 }
1050}
1051
1052/*----------------------------------------------------------------------*/
1053static void draw_degenerates_trianglestrips_as_points ( call_def_parray p ) {
1054
1055 Tint i, j, k, n;
1056 GLfloat pt[ 3 ];
1057 tel_point pv = p -> vertices;
1058
1059#ifdef FULL_DEGENER
1060 if ( g_fSkipRatio == 1. )
1061 return;
1062#endif
1063
1064 if( p->num_bounds > 0 ) {
1065 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1066 for ( j=0 ; j<p->bounds[k]-2 ; j++ ) {
1067 pt[0] = pt[1] = pt[2] = 0.;
1068 for ( i=0 ; i<3 ; i++ ) {
1069 pt[ 0 ] += pv[n+j+i].xyz[ 0 ];
1070 pt[ 1 ] += pv[n+j+i].xyz[ 1 ];
1071 pt[ 2 ] += pv[n+j+i].xyz[ 2 ];
1072 }
1073 pt[ 0 ] /= 3;
1074 pt[ 1 ] /= 3;
1075 pt[ 2 ] /= 3;
1076 glVertex3fv ( pt );
1077 }
1078 n += p->bounds[k];
1079 }
1080 } else {
1081 for ( j=0 ; j<p->num_vertexs-2 ; j++ ) {
1082 pt[0] = pt[1] = pt[2] = 0.;
1083 for ( i=0 ; i<3 ; i++ ) {
1084 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1085 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1086 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1087 }
1088 pt[ 0 ] /= 3;
1089 pt[ 1 ] /= 3;
1090 pt[ 2 ] /= 3;
1091 glVertex3fv ( pt );
1092 }
1093 }
1094}
1095
1096/*----------------------------------------------------------------------*/
1097static void draw_degenerates_polygons_as_points ( call_def_parray p ) {
1098
1099 Tint j, k, n, iv;
1100 GLfloat pt[ 3 ];
1101 tel_point pv = p -> vertices;
1102
1103#ifdef FULL_DEGENER
1104 if ( g_fSkipRatio == 1. )
1105 return;
1106#endif
1107
1108 if( p->num_bounds > 0 ) {
1109 if( p->num_edges > 0 ) {
1110 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1111 pt[0] = pt[1] = pt[2] = 0.;
1112 for ( j=0 ; j<p->bounds[k] ; j++ ) {
1113 iv = p->edges[n+j];
1114 pt[ 0 ] += pv[iv].xyz[ 0 ];
1115 pt[ 1 ] += pv[iv].xyz[ 1 ];
1116 pt[ 2 ] += pv[iv].xyz[ 2 ];
1117 }
1118 pt[ 0 ] /= p->bounds[k];
1119 pt[ 1 ] /= p->bounds[k];
1120 pt[ 2 ] /= p->bounds[k];
1121 glVertex3fv ( pt );
1122 n += p->bounds[k];
1123 }
1124 } else {
1125 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1126 pt[0] = pt[1] = pt[2] = 0.;
1127 for ( j=0 ; j<p->bounds[k] ; j++ ) {
1128 pt[ 0 ] += pv[n+j].xyz[ 0 ];
1129 pt[ 1 ] += pv[n+j].xyz[ 1 ];
1130 pt[ 2 ] += pv[n+j].xyz[ 2 ];
1131 }
1132 pt[ 0 ] /= p->bounds[k];
1133 pt[ 1 ] /= p->bounds[k];
1134 pt[ 2 ] /= p->bounds[k];
1135 glVertex3fv ( pt );
1136 n += p->bounds[k];
1137 }
1138 }
1139 } else if( p->num_edges > 0 ) {
1140 pt[0] = pt[1] = pt[2] = 0.;
1141 for ( j=0 ; j<p->num_edges ; j++ ) {
1142 iv = p->edges[j];
1143 pt[ 0 ] += pv[iv].xyz[ 0 ];
1144 pt[ 1 ] += pv[iv].xyz[ 1 ];
1145 pt[ 2 ] += pv[iv].xyz[ 2 ];
1146 }
1147 pt[ 0 ] /= p->num_edges;
1148 pt[ 1 ] /= p->num_edges;
1149 pt[ 2 ] /= p->num_edges;
1150 glVertex3fv ( pt );
1151 } else {
1152 pt[0] = pt[1] = pt[2] = 0.;
1153 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1154 pt[ 0 ] += pv[j].xyz[ 0 ];
1155 pt[ 1 ] += pv[j].xyz[ 1 ];
1156 pt[ 2 ] += pv[j].xyz[ 2 ];
1157 }
1158 pt[ 0 ] /= p->num_vertexs;
1159 pt[ 1 ] /= p->num_vertexs;
1160 pt[ 2 ] /= p->num_vertexs;
1161 glVertex3fv ( pt );
1162 }
1163}
1164
1165/*----------------------------------------------------------------------*/
1166static void draw_degenerates_quadrangles_as_points ( call_def_parray p ) {
1167
1168 Tint i, j, iv;
1169 GLfloat pt[ 3 ];
1170 tel_point pv = p -> vertices;
1171
1172#ifdef FULL_DEGENER
1173 if ( g_fSkipRatio == 1. )
1174 return;
1175#endif
1176
1177 if( p->num_edges > 0 ) {
1178 for ( j=0 ; j<p->num_edges ; j+=4 ) {
1179 pt[0] = pt[1] = pt[2] = 0.;
1180 for ( i=0 ; i<4 ; i++ ) {
1181 iv = p->edges[j+i];
1182 pt[ 0 ] += pv[iv].xyz[ 0 ];
1183 pt[ 1 ] += pv[iv].xyz[ 1 ];
1184 pt[ 2 ] += pv[iv].xyz[ 2 ];
1185 }
1186 pt[ 0 ] /= 4;
1187 pt[ 1 ] /= 4;
1188 pt[ 2 ] /= 4;
1189 glVertex3fv ( pt );
1190 }
1191 } else {
1192 for ( j=0 ; j<p->num_vertexs ; j+=4 ) {
1193 pt[0] = pt[1] = pt[2] = 0.;
1194 for ( i=0 ; i<4 ; i++ ) {
1195 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1196 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1197 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1198 }
1199 pt[ 0 ] /= 4;
1200 pt[ 1 ] /= 4;
1201 pt[ 2 ] /= 4;
1202 glVertex3fv ( pt );
1203 }
1204 }
1205}
1206
1207/*----------------------------------------------------------------------*/
1208static void draw_degenerates_quadranglestrips_as_points ( call_def_parray p ) {
1209
1210 Tint i, j, k, n;
1211 GLfloat pt[ 3 ];
1212 tel_point pv = p -> vertices;
1213
1214#ifdef FULL_DEGENER
1215 if ( g_fSkipRatio == 1. )
1216 return;
1217#endif
1218
1219 if( p->num_bounds > 0 ) {
1220 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1221 for ( j=0 ; j<p->bounds[k]-2 ; j+=2 ) {
1222 pt[0] = pt[1] = pt[2] = 0.;
1223 for ( i=0 ; i<4 ; i++ ) {
1224 pt[ 0 ] += pv[n+j+i].xyz[ 0 ];
1225 pt[ 1 ] += pv[n+j+i].xyz[ 1 ];
1226 pt[ 2 ] += pv[n+j+i].xyz[ 2 ];
1227 }
1228 pt[ 0 ] /= 4;
1229 pt[ 1 ] /= 4;
1230 pt[ 2 ] /= 4;
1231 glVertex3fv ( pt );
1232 }
1233 n += p->bounds[k];
1234 }
1235 } else {
1236 for ( j=0 ; j<p->num_vertexs-2 ; j+=2 ) {
1237 pt[0] = pt[1] = pt[2] = 0.;
1238 for ( i=0 ; i<4 ; i++ ) {
1239 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1240 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1241 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1242 }
1243 pt[ 0 ] /= 4;
1244 pt[ 1 ] /= 4;
1245 pt[ 2 ] /= 4;
1246 glVertex3fv ( pt );
1247 }
1248 }
1249}
1250
1251/*----------------------------------------------------------------------*/
1252static void draw_degenerates_as_points ( call_def_parray p,
1253 tel_colour edge_colour )
1254{
1255
1256 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1257 LightOff ();
1258 if( zbuff_state ) glDisable(GL_DEPTH_TEST);
1259 glColor3fv( edge_colour->rgb );
1260 glBegin ( GL_POINTS );
1261 switch( draw_mode ) {
1262 case GL_POINTS:
1263 draw_degenerates_points_as_points( p );
1264 break;
1265 case GL_LINES:
1266 draw_degenerates_lines_as_points( p );
1267 break;
1268 case GL_LINE_STRIP:
1269 case GL_POLYGON:
1270 draw_degenerates_polygons_as_points( p );
1271 break;
1272 case GL_TRIANGLES:
1273 draw_degenerates_triangles_as_points( p );
1274 break;
1275 case GL_QUADS:
1276 draw_degenerates_quadrangles_as_points( p );
1277 break;
1278 case GL_TRIANGLE_FAN:
1279 case GL_TRIANGLE_STRIP:
1280 draw_degenerates_trianglestrips_as_points( p );
1281 break;
1282 case GL_QUAD_STRIP:
1283 draw_degenerates_quadranglestrips_as_points( p );
1284 break;
1285 default:
1286 break;
1287 }
1288
1289 glEnd ();
1290
1291 if( zbuff_state ) glEnable(GL_DEPTH_TEST);
1292}
1293
1294/*----------------------------------------------------------------------*/
1295static void draw_degenerates_lines_as_lines ( call_def_parray p ) {
1296
1297 Tint i,j,n,iv;
1298 tel_point pv = p -> vertices;
1299
1300 n = p->num_vertexs;
1301 j = (int)((1.-g_fSkipRatio)*n);
1302 while ( j-- ) {
1303 i = OGL_Rand() % n;
1304 p->keys[i] = -p->keys[i];
1305 };
1306
1307 if( p->num_bounds > 0 ) {
1308 if( p->num_edges > 0 ) {
1309 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1310 glBegin ( GL_LINES );
1311 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1312 iv = p->edges[n+j];
1313 if( p->keys[iv] < 0 ) {
1314 p->keys[iv] = -p->keys[iv];
1315 glVertex3fv ( pv[iv].xyz );
1316 }
1317 }
1318 glEnd();
1319 n += p->bounds[i];
1320 }
1321 } else {
1322 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1323 glBegin ( GL_LINES );
1324 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1325 if( p->keys[n+j] < 0 ) {
1326 p->keys[n+j] = -p->keys[n+j];
1327 glVertex3fv ( pv[n+j].xyz );
1328 }
1329 }
1330 glEnd();
1331 n += p->bounds[i];
1332 }
1333 }
1334 } else if( p->num_edges > 0 ) {
1335 glBegin ( GL_LINES );
1336 for ( j=0 ; j<p->num_edges ; j++ ) {
1337 iv = p->edges[j];
1338 if( p->keys[iv] < 0 ) {
1339 p->keys[iv] = -p->keys[iv];
1340 glVertex3fv ( pv[iv].xyz );
1341 }
1342 }
1343 glEnd();
1344 } else {
1345 glBegin ( GL_LINES );
1346 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1347 if( p->keys[j] < 0 ) {
1348 p->keys[j] = -p->keys[j];
1349 glVertex3fv ( pv[j].xyz );
1350 }
1351 }
1352 glEnd();
1353 }
1354}
1355
1356/*----------------------------------------------------------------------*/
1357static void draw_degenerates_triangles_as_lines ( call_def_parray p )
1358{
1359
1360 Tint i,j,n,iv;
1361 tel_point pv = p -> vertices;
1362
1363 n = p->num_vertexs/3;
1364 j = (int)((1.-g_fSkipRatio)*n);
1365 while ( j-- ) {
1366 i = OGL_Rand() % n; i *= 3;
1367 p->keys[i] = -p->keys[i];
1368 };
1369
1370 if( p->num_edges > 0 ) {
1371 for ( j=0 ; j<p->num_edges ; j+=3 ) {
1372 iv = p->edges[j];
1373 if( p->keys[iv] < 0 ) {
1374 p->keys[iv] = -p->keys[iv];
1375 glBegin ( GL_LINE_LOOP );
1376 for ( i=0 ; i<3 ; i++ ) {
1377 iv = p->edges[j+i];
1378 glVertex3fv ( pv[iv].xyz );
1379 }
1380 glEnd();
1381 }
1382 }
1383 } else {
1384 for ( j=0 ; j<p->num_vertexs ; j+=3 ) {
1385 if( p->keys[j] < 0 ) {
1386 p->keys[j] = -p->keys[j];
1387 glBegin ( GL_LINE_LOOP );
1388 for ( i=0 ; i<3 ; i++ ) {
1389 glVertex3fv ( pv[j+i].xyz );
1390 }
1391 glEnd();
1392 }
1393 }
1394 }
1395}
1396
1397/*----------------------------------------------------------------------*/
1398static void draw_degenerates_trianglestrips_as_lines ( call_def_parray p )
1399{
1400
1401 Tint i,j,k,n,ni;
1402 tel_point pv = p -> vertices;
1403
1404 if( p->num_bounds > 0 ) {
1405 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1406 ni = p->bounds[i]-2;
1407 k = (int)((1.-g_fSkipRatio)*ni);
1408 while ( k-- ) {
1409 j = OGL_Rand() % ni; j += 2;
1410 p->keys[n+j] = -p->keys[n+j];
1411 };
1412 for ( j=2 ; j<p->bounds[i] ; j++ ) {
1413 if( p->keys[n+j] < 0 ) {
1414 p->keys[n+j] = -p->keys[n+j];
1415 glBegin ( GL_LINE_LOOP );
1416 glVertex3fv ( pv[n+j-2].xyz );
1417 glVertex3fv ( pv[n+j-1].xyz );
1418 glVertex3fv ( pv[n+j].xyz );
1419 glEnd();
1420 }
1421 }
1422 n += p->bounds[i];
1423 }
1424 } else {
1425 ni = p->num_vertexs-2;
1426 k = (int)((1.-g_fSkipRatio)*ni);
1427 while ( k-- ) {
1428 j = OGL_Rand() % ni; j += 2;
1429 p->keys[j] = -p->keys[j];
1430 };
1431 for ( j=2 ; j<p->num_vertexs ; j++ ) {
1432 if( p->keys[j] < 0 ) {
1433 p->keys[j] = -p->keys[j];
1434 glBegin ( GL_LINE_LOOP );
1435 glVertex3fv ( pv[j-2].xyz );
1436 glVertex3fv ( pv[j-1].xyz );
1437 glVertex3fv ( pv[j].xyz );
1438 glEnd();
1439 }
1440 }
1441 }
1442}
1443
1444/*----------------------------------------------------------------------*/
1445static void draw_degenerates_polygons_as_lines ( call_def_parray p )
1446{
1447 Tint i,j,n,iv;
1448 tel_point pv = p -> vertices;
1449
1450 n = p->num_vertexs;
1451 j = (int)((1.-g_fSkipRatio)*n);
1452 while ( j-- ) {
1453 i = OGL_Rand() % n;
1454 p->keys[i] = -p->keys[i];
1455 };
1456
1457 if( p->num_bounds > 0 ) {
1458 if( p->num_edges > 0 ) {
1459 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1460 glBegin ( GL_LINE_LOOP );
1461 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1462 iv = p->edges[n+j];
1463 if( p->keys[iv] < 0 ) {
1464 p->keys[iv] = -p->keys[iv];
1465 glVertex3fv ( pv[iv].xyz );
1466 }
1467 }
1468 glEnd();
1469 n += p->bounds[i];
1470 }
1471 } else {
1472 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1473 glBegin ( GL_LINE_LOOP );
1474 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1475 if( p->keys[n+j] < 0 ) {
1476 p->keys[n+j] = -p->keys[n+j];
1477 glVertex3fv ( pv[n+j].xyz );
1478 }
1479 }
1480 glEnd();
1481 n += p->bounds[i];
1482 }
1483 }
1484 } else if( p->num_edges > 0 ) {
1485 glBegin ( GL_LINE_LOOP );
1486 for ( j=0 ; j<p->num_edges ; j++ ) {
1487 iv = p->edges[j];
1488 if( p->keys[iv] < 0 ) {
1489 p->keys[iv] = -p->keys[iv];
1490 glVertex3fv ( pv[iv].xyz );
1491 }
1492 }
1493 glEnd();
1494 } else {
1495 glBegin ( GL_LINE_LOOP );
1496 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1497 if( p->keys[j] < 0 ) {
1498 p->keys[j] = -p->keys[j];
1499 glVertex3fv ( pv[j].xyz );
1500 }
1501 }
1502 glEnd();
1503 }
1504
1505}
1506
1507/*----------------------------------------------------------------------*/
1508static void draw_degenerates_quadrangles_as_lines ( call_def_parray p )
1509{
1510
1511 Tint i,j,n,iv;
1512 tel_point pv = p -> vertices;
1513
1514 n = p->num_vertexs/4;
1515 j = (int)((1.-g_fSkipRatio)*n);
1516 while ( j-- ) {
1517 i = OGL_Rand() % n; i *= 4;
1518 p->keys[i] = -p->keys[i];
1519 };
1520
1521 if( p->num_edges > 0 ) {
1522 for ( j=0 ; j<p->num_edges ; j+=4 ) {
1523 iv = p->edges[j];
1524 if( p->keys[iv] < 0 ) {
1525 p->keys[iv] = -p->keys[iv];
1526 glBegin ( GL_LINE_LOOP );
1527 for ( i=0 ; i<4 ; i++ ) {
1528 iv = p->edges[j+i];
1529 glVertex3fv ( pv[iv].xyz );
1530 }
1531 glEnd();
1532 }
1533 }
1534 } else {
1535 for ( j=0 ; j<p->num_vertexs ; j+=4 ) {
1536 if( p->keys[j] < 0 ) {
1537 p->keys[j] = -p->keys[j];
1538 glBegin ( GL_LINE_LOOP );
1539 for ( i=0 ; i<4 ; i++ ) {
1540 glVertex3fv ( pv[j+i].xyz );
1541 }
1542 glEnd();
1543 }
1544 }
1545 }
1546}
1547
1548/*----------------------------------------------------------------------*/
1549static void draw_degenerates_quadranglestrips_as_lines ( call_def_parray p )
1550{
1551
1552 Tint i,j,k,n,ni;
1553 tel_point pv = p -> vertices;
1554
1555 if( p->num_bounds > 0 ) {
1556 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1557 ni = p->bounds[i]/2-2;
1558 k = (int)((1.-g_fSkipRatio)*ni);
1559 while ( k-- ) {
1560 j = OGL_Rand() % ni; j = j*2+2;
1561 p->keys[n+j] = -p->keys[n+j];
1562 };
1563 for ( j=3 ; j<p->bounds[i] ; j+=2 ) {
1564 if( p->keys[n+j] < 0 ) {
1565 p->keys[n+j] = -p->keys[n+j];
1566 glBegin ( GL_LINE_LOOP );
1567 glVertex3fv ( pv[n+j-3].xyz );
1568 glVertex3fv ( pv[n+j-2].xyz );
1569 glVertex3fv ( pv[n+j-1].xyz );
1570 glVertex3fv ( pv[n+j].xyz );
1571 glEnd();
1572 }
1573 }
1574 n += p->bounds[i];
1575 }
1576 } else {
1577 ni = p->num_vertexs/2-2;
1578 k = (int)((1.-g_fSkipRatio)*ni);
1579 while ( k-- ) {
1580 j = OGL_Rand() % ni; j = j*2+2;
1581 p->keys[j] = -p->keys[j];
1582 };
1583 for ( j=3 ; j<p->num_vertexs ; j+=2 ) {
1584 if( p->keys[j] < 0 ) {
1585 p->keys[j] = -p->keys[j];
1586 glBegin ( GL_LINE_LOOP );
1587 glVertex3fv ( pv[j-3].xyz );
1588 glVertex3fv ( pv[j-2].xyz );
1589 glVertex3fv ( pv[j-1].xyz );
1590 glVertex3fv ( pv[j].xyz );
1591 glEnd();
1592 }
1593 }
1594 }
1595}
1596
1597/*----------------------------------------------------------------------*/
1598static void draw_degenerates_as_lines ( call_def_parray p,
1599 tel_colour edge_colour )
1600{
1601
1602 GLint renderMode;
1603
1604 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1605
1606 LightOff ();
1607
1608 if( zbuff_state ) glDisable(GL_DEPTH_TEST);
1609
1610 glColor3fv( edge_colour->rgb );
1611
1612 if( g_fSkipRatio != 0 ) switch( draw_mode ) {
1613 case GL_POINTS:
1614 draw_degenerates_points_as_points( p );
1615 break;
1616 case GL_LINES:
1617 draw_degenerates_lines_as_lines( p );
1618 break;
1619 case GL_LINE_STRIP:
1620 case GL_POLYGON:
1621 draw_degenerates_polygons_as_lines( p );
1622 break;
1623 case GL_TRIANGLES:
1624 draw_degenerates_triangles_as_lines( p );
1625 break;
1626 case GL_QUADS:
1627 draw_degenerates_quadrangles_as_lines( p );
1628 break;
1629 case GL_TRIANGLE_FAN:
1630 case GL_TRIANGLE_STRIP:
1631 draw_degenerates_trianglestrips_as_lines( p );
1632 break;
1633 case GL_QUAD_STRIP:
1634 draw_degenerates_quadranglestrips_as_lines( p );
1635 break;
1636 default:
1637 break;
1638 }
1639 else {
1640 int i,n;
1641
1642#ifdef OCC3192
1643 GLboolean color_array_mode,
1644 edge_flag_array_mode,
1645 index_array_mode,
1646 normal_array_mode,
1647 texture_coord_array_mode,
1648 vertex_array_mode;
1649#endif
1650 glPushAttrib( GL_POLYGON_BIT );
1651 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
1652
1653#ifdef OCC3192
1654 color_array_mode = glIsEnabled( GL_COLOR_ARRAY );
1655 edge_flag_array_mode = glIsEnabled( GL_EDGE_FLAG_ARRAY );
1656 index_array_mode = glIsEnabled( GL_INDEX_ARRAY );
1657 normal_array_mode = glIsEnabled( GL_NORMAL_ARRAY );
1658 texture_coord_array_mode = glIsEnabled( GL_TEXTURE_COORD_ARRAY );
1659 vertex_array_mode = glIsEnabled( GL_VERTEX_ARRAY );
1660
1661 glDisableClientState( GL_COLOR_ARRAY );
1662 glDisableClientState( GL_EDGE_FLAG_ARRAY );
1663 glDisableClientState( GL_INDEX_ARRAY );
1664 glDisableClientState( GL_NORMAL_ARRAY );
1665 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1666
1667 if( !vertex_array_mode ) glEnableClientState( GL_VERTEX_ARRAY );
1668#else
1669 glEnableClientState( GL_VERTEX_ARRAY );
1670#endif
1671 glVertexPointer(3, GL_FLOAT, 0, p->vertices); /* array of vertices */
1672
1673 glGetIntegerv( GL_RENDER_MODE, &renderMode );
1674
1675 if( p->num_bounds > 0 ) {
1676 if( p->num_edges > 0 ) {
1677 for( i=n=0 ; i<p->num_bounds ; i++ ) {
1678 if( renderMode == GL_FEEDBACK )
1679 draw_primitive_elements( p, draw_mode, p->bounds[i],
1680 GL_UNSIGNED_INT, (GLenum*) &p->edges[n]);
1681 else
1682 glDrawElements( draw_mode, p->bounds[i],
1683 GL_UNSIGNED_INT, &p->edges[n]);
1684 n += p->bounds[i];
1685 }
1686 } else {
1687 for( i=n=0 ; i<p->num_bounds ; i++ ) {
1688 if( renderMode == GL_FEEDBACK )
1689 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
1690 else
1691 glDrawArrays( draw_mode, n, p->bounds[i]);
1692 n += p->bounds[i];
1693 }
1694 }
1695 } else if( p->num_edges > 0 ) {
1696 if( renderMode == GL_FEEDBACK )
1697 draw_primitive_elements( p, draw_mode, p->num_edges,
1698 GL_UNSIGNED_INT, (GLenum*) p->edges);
1699 else
1700 glDrawElements( draw_mode, p->num_edges,
1701 GL_UNSIGNED_INT, p->edges);
1702 } else {
1703 if( renderMode == GL_FEEDBACK )
1704 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
1705 else
1706 glDrawArrays( draw_mode, 0, p->num_vertexs);
1707 }
1708
1709#ifdef OCC3192
1710 if( !vertex_array_mode ) glDisableClientState( GL_VERTEX_ARRAY );
1711
1712 if( color_array_mode ) glEnableClientState( GL_COLOR_ARRAY );
1713 if( edge_flag_array_mode ) glEnableClientState( GL_EDGE_FLAG_ARRAY );
1714 if( index_array_mode ) glEnableClientState( GL_INDEX_ARRAY );
1715 if( normal_array_mode ) glEnableClientState( GL_NORMAL_ARRAY );
1716 if( texture_coord_array_mode ) glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1717#endif
1718 glPopAttrib();
1719 }
1720
1721 if( zbuff_state ) glEnable(GL_DEPTH_TEST);
1722
1723}
1724
1725static void draw_degenerates_as_bboxs ( call_def_parray p,
1726 tel_colour edge_colour )
1727{
1728
1729 Tint i;
1730 GLfloat minp[ 3 ] = { FLT_MAX, FLT_MAX, FLT_MAX };
1731 GLfloat maxp[ 3 ] = { FLT_MIN, FLT_MIN, FLT_MIN };
1732 tel_point pv = p -> vertices;
1733
1734 LightOff ();
1735
1736 glColor3fv( edge_colour->rgb );
1737
1738 for ( i=0 ; i<p->num_vertexs ; ++i ) {
1739 if ( pv[ i ].xyz[ 0 ] < minp[ 0 ] )
1740 minp[ 0 ] = pv[ i ].xyz[ 0 ] ;
1741 if ( pv[ i ].xyz[ 1 ] < minp[ 1 ] )
1742 minp[ 1 ] = pv[ i ].xyz[ 1 ] ;
1743 if ( pv[ i ].xyz[ 2 ] < minp[ 2 ] )
1744 minp[ 2 ] = pv[ i ].xyz[ 2 ] ;
1745
1746 if ( pv[ i ].xyz[ 0 ] > maxp[ 0 ] )
1747 maxp[ 0 ] = pv[ i ].xyz[ 0 ] ;
1748 if ( pv[ i ].xyz[ 1 ] > maxp[ 1 ] )
1749 maxp[ 1 ] = pv[ i ].xyz[ 1 ] ;
1750 if ( pv[ i ].xyz[ 2 ] > maxp[ 2 ] )
1751 maxp[ 2 ] = pv[ i ].xyz[ 2 ] ;
1752 } /* end for ( i ) */
1753
1754 glBegin ( GL_LINE_STRIP );
1755
1756 glVertex3fv ( minp );
1757 glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1758 glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1759 glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1760 glVertex3f ( minp[ 0 ], minp[ 1 ], minp[ 2 ] );
1761
1762 glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
1763 glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1764 glVertex3f ( maxp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1765 glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1766 glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
1767
1768 glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1769 glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1770 glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1771 glVertex3fv ( maxp );
1772 glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1773 glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1774
1775 glEnd();
1776
1777} /* end draw_degenerates_as_bboxs */