2 File OpenGl_PrimitiveArray.c
4 Created 16/06/2000 : ATS : G005 : Modified version of OpenGl_indexpolygons.c, which use glDrawArrays or glDrawElements for rendering of primitive
5 21.06.03 : SAN : suppress display at all in animation mode if degenartion ratio == 1 (FULL_DEGENER)
6 03.07.03 : SAN : draw_degenerates_as_lines() function - all client states disabled except GL_VERTEX_ARRAY
7 in order to avoid exceptions in animation mode (OCC3192)
10 #define xOGLBUG /* UNFORTUNATLY the edge flags are attached to vertexes
11 and not to the edges. So the edge visibillity flags array
24 #define OGL_Max(a,b) ((a) > (b) ? (a) : (b))
28 static unsigned long vRand = 1L;
29 #define OGL_Rand() (vRand = vRand * 214013L + 2531011L)
33 #define OCC7833 /* ASL 26/01/05 transparency of polygon with colors assigned to vertices */
35 /*----------------------------------------------------------------------*/
40 #include <OpenGl_tgl_all.hxx>
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>
63 # define DEF_DS_INTERNAL
64 # include <OpenGl_degeneration.hxx>
66 #include <OpenGl_Extension.hxx>
68 extern GLboolean g_fBitmap;
70 typedef CALL_DEF_PARRAY *call_def_parray;
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
78 typedef void (APIENTRY* PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
79 typedef void (APIENTRY* PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
80 typedef void (APIENTRY* PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
81 typedef void (APIENTRY* PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
83 typedef void (*PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
84 typedef void (*PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
85 typedef void (*PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
87 typedef void (*PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
89 typedef void (*PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
94 PFNGLGENBUFFERSARBPROC glVBOGenBuffersARB = NULL; // VBO Name Generation Procedure
95 PFNGLBINDBUFFERARBPROC glVBOBindBufferARB = NULL; // VBO Bind Procedure
96 PFNGLBUFFERDATAARBPROC glVBOBufferDataARB = NULL; // VBO Data Loading Procedure
97 PFNGLDELETEBUFFERSARBPROC glVBODeleteBuffersARB = NULL; // VBO Data Deleting Procedure
102 #define VBO_NOT_INITIALIZED -1
107 #define glGetProcAddress( x ) glXGetProcAddress( (const GLubyte*) x )
109 #define glGetProcAddress( x ) wglGetProcAddress( x )
112 void clearRAMMemory( CALL_DEF_PARRAY* p )
114 if( p->bufferVBO[VBOEdges] ){
115 Standard::Free((Standard_Address&)p->edges);
118 if( p->bufferVBO[VBOVertices] ){
119 Standard::Free((Standard_Address&)p->vertices);
122 if( p->bufferVBO[VBOVcolours] ){
123 Standard::Free((Standard_Address&)p->vcolours);
126 if( p->bufferVBO[VBOVnormals] ){
127 Standard::Free((Standard_Address&)p->vnormals);
130 if( p->bufferVBO[VBOVtexels] ){
131 Standard::Free((Standard_Address&)p->vtexels);
135 Standard::Free((Standard_Address&)p->edge_vis);
140 void clearGraphicRAMMemory( CALL_DEF_PARRAY* p )
142 if( p->bufferVBO[VBOEdges] ){
143 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOEdges]);
145 if( p->bufferVBO[VBOVertices] ){
146 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVertices]);
148 if( p->bufferVBO[VBOVcolours] ){
149 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVcolours]);
151 if( p->bufferVBO[VBOVnormals] ){
152 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVnormals]);
154 if( p->bufferVBO[VBOVtexels] ){
155 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVtexels]);
157 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
158 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
161 int checkSizeForGraphicMemory( CALL_DEF_PARRAY* p )
163 if( GL_OUT_OF_MEMORY == glGetError() ){
164 p->flagBufferVBO = VBO_ERROR;
165 clearGraphicRAMMemory(p);
168 p->flagBufferVBO = VBO_OK;
169 return p->flagBufferVBO ;
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");
185 static void BuildVBO( CALL_DEF_PARRAY* p )
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 )
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 )
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 )
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)
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 )
233 if( p->flagBufferVBO == VBO_OK )
237 /*----------------------------------------------------------------------*/
242 /*----------------------------------------------------------------------*/
247 static TStatus ParrayDisplay( TSM_ELEM_DATA, Tint, cmn_key* );
248 static TStatus ParrayAdd( TSM_ELEM_DATA, Tint, cmn_key* );
249 static TStatus ParrayDelete( TSM_ELEM_DATA, Tint, cmn_key* );
250 static TStatus ParrayPrint( TSM_ELEM_DATA, Tint, cmn_key* );
251 static TStatus ParrayInquire( TSM_ELEM_DATA, Tint, cmn_key* );
253 /*static GLboolean lighting_mode;*/
255 static void draw_array(
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, */
269 static void draw_edges ( call_def_parray, tel_colour );
270 static void draw_degenerates_as_points ( call_def_parray, tel_colour );
271 static void draw_degenerates_as_lines ( call_def_parray, tel_colour );
272 static void draw_degenerates_as_bboxs ( call_def_parray, tel_colour );
274 static TStatus (*MtdTbl[])( TSM_ELEM_DATA, Tint, cmn_key* ) =
276 NULL, /* PickTraverse */
283 static GLenum draw_mode;
285 /*----------------------------------------------------------------------*/
290 extern Tint ForbidSetTextureMapping; /* currently defined in tsm/tsm.c */
292 extern int g_nDegenerateModel;
293 extern float g_fSkipRatio;
295 /*----------------------------------------------------------------------*/
298 TelParrayInitClass( TelType* el )
304 /*----------------------------------------------------------------------*/
307 ParrayAdd( TSM_ELEM_DATA d, Tint n, cmn_key *k )
310 if( k[0]->id != PARRAY_ID ) return TFailure;
312 ((tsm_elem_data)(d.pdata))->pdata = k[0]->data.pdata;
317 /*----------------------------------------------------------------------*/
320 ParrayDisplay( TSM_ELEM_DATA data, Tint n, cmn_key *k )
322 CMN_KEY k11, k12, k17, k18, k111, k114, k115;
324 Tint front_lighting_model;
326 TEL_COLOUR interior_colour;
327 TEL_COLOUR edge_colour;
328 TEL_COLOUR line_colour;
336 call_def_parray d = (call_def_parray)data.pdata;
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;
349 k117.id = TelSurfaceAreaProperties;
350 k117.data.pdata = ∝
354 TsmGetAttri( 7, &k12, &k17, &k18, &k111, &k114, &k115, &k117 );
356 TsmGetAttri( 6, &k12, &k17, &k18, &k111, &k114, &k115 );
359 front_lighting_model = k12.data.ldata;
360 interior_style = k17.data.ldata;
361 edge_flag = k18.data.ldata;
364 printf("ParrayDisplay type %d\n",d->type);
368 * Use highlight colours
371 if( k[0]->id == TOn ) {
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;
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;
396 draw_array( d, k[0]->id,
397 front_lighting_model,
412 /*----------------------------------------------------------------------*/
415 draw_primitive_array( call_def_parray p, GLenum mode, GLint first, GLsizei count )
419 for( i=first; i<(first + count); i++ ){
421 glNormal3fv( p->vnormals[i].xyz );
422 if( p->vtexels && !ForbidSetTextureMapping )
423 glTexCoord3fv( p->vtexels[i].xy );
425 glVertex3fv( p->vertices[i].xyz );
427 glColor4ubv( (GLubyte*) p->vcolours[i] );
432 /*----------------------------------------------------------------------*/
434 draw_primitive_elements( call_def_parray p, GLenum mode, GLsizei count, GLenum type, GLenum *indices )
439 for( i=0; i<count; i++ ){
442 glNormal3fv( p->vnormals[index].xyz );
443 if( p->vtexels && !ForbidSetTextureMapping )
444 glTexCoord3fv( p->vtexels[index].xy );
446 glVertex3fv( p->vertices[index].xyz );
448 glColor4ubv( (GLubyte*) p->vcolours[index] );
452 /*----------------------------------------------------------------------*/
454 draw_array( call_def_parray p, Tint hflag,
458 tel_colour interior_colour,
459 tel_colour line_colour,
460 tel_colour edge_colour
468 /* Following pointers have been provided for performance improvement */
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 );
484 pvc[i] = ( pvc[i] & 0x00ffffff );
485 pvc[i] += transp << 24;
492 case TelPointsArrayType:
493 draw_mode = GL_POINTS;
494 glColor3fv( line_colour->rgb );
496 case TelPolylinesArrayType:
497 draw_mode = GL_LINE_STRIP;
498 glColor3fv( line_colour->rgb );
500 case TelSegmentsArrayType:
501 draw_mode = GL_LINES;
502 glColor3fv( line_colour->rgb );
504 case TelPolygonsArrayType:
505 draw_mode = GL_POLYGON;
506 glColor3fv( interior_colour->rgb );
508 case TelTrianglesArrayType:
509 draw_mode = GL_TRIANGLES;
510 glColor3fv( interior_colour->rgb );
512 case TelQuadranglesArrayType:
513 draw_mode = GL_QUADS;
514 glColor3fv( interior_colour->rgb );
516 case TelTriangleStripsArrayType:
517 draw_mode = GL_TRIANGLE_STRIP;
518 glColor3fv( interior_colour->rgb );
520 case TelQuadrangleStripsArrayType:
521 draw_mode = GL_QUAD_STRIP;
522 glColor3fv( interior_colour->rgb );
524 case TelTriangleFansArrayType:
525 draw_mode = GL_TRIANGLE_FAN;
526 glColor3fv( interior_colour->rgb );
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);
539 if( p->VBOEnabled == -1 ){
540 p->VBOEnabled = VBOenabled;
541 if( VBOExtension == 0)
543 if( (VBOExtension == 1) && (p->VBOEnabled != 0))
549 printf(" $$$ g_nDegenerateModel %d\n",g_nDegenerateModel);
551 if ( g_nDegenerateModel < 2 &&
552 ( (draw_mode > GL_LINE_STRIP && interior_style != TSM_EMPTY) ||
553 (draw_mode <= GL_LINE_STRIP /*&& !hflag*/)) ) {
560 if ( interior_style == TSM_HIDDENLINE) {
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*/
571 if( lighting_model == CALL_PHIGS_REFL_NONE || draw_mode <= GL_LINE_STRIP )
574 glGetIntegerv( GL_RENDER_MODE, &renderMode );
576 if ( p->num_vertexs > 0 && p->flagBufferVBO != VBO_OK) {
577 if( renderMode != GL_FEEDBACK ){
579 glVertexPointer(3, GL_FLOAT, 0, p->vertices);/* array of vertices */
580 glEnableClientState(GL_VERTEX_ARRAY);
584 glNormalPointer(GL_FLOAT, 0, p->vnormals);/* array of normals */
585 glEnableClientState(GL_NORMAL_ARRAY);
589 glTexCoordPointer(2, GL_FLOAT, 0, p->vtexels);/* array of texture coordinates */
590 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
595 glColorPointer(4, GL_UNSIGNED_BYTE, 0, pvc); /* array of colors */
597 glColorPointer(3, GL_UNSIGNED_BYTE, 0, pvc); /* array of colors */
599 glEnableClientState(GL_COLOR_ARRAY);
600 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
601 glEnable(GL_COLOR_MATERIAL);
606 //Bindings concrete pointer in accordance with VBO buffer
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);
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);
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);
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);
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.
638 // 3) draw primitive by vertexes if no edges and bounds array is specified
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
643 // draw primitives by vertex count with the indicies
644 if( p->num_bounds > 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];
651 // draw one (or sequential) primitive by the indicies
653 glDrawElements(draw_mode, p->num_edges , GL_UNSIGNED_INT, 0);
656 else if( p->num_bounds > 0 ) {
657 for( i = n = 0 ; i < p->num_bounds ; i ++ ){
658 glDrawArrays(draw_mode, n, p->bounds[i]);
663 glDrawArrays(draw_mode, 0, p->num_vertexs);
667 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
668 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
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]);
679 glDrawElements( draw_mode, p->bounds[i],
680 GL_UNSIGNED_INT, &p->edges[n]);
684 for( i=n=0 ; i<p->num_bounds ; i++ ) {
686 glColor3fv ( pfc[i].rgb );
687 if( renderMode == GL_FEEDBACK )
688 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
691 glDrawArrays( draw_mode, n, p->bounds[i]);
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]);
701 glDrawElements( draw_mode, p->num_edges, GL_UNSIGNED_INT, p->edges);
703 if( renderMode == GL_FEEDBACK )
704 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
706 glDrawArrays( draw_mode, 0, p->num_vertexs);
711 if( p->bufferVBO[VBOVcolours] || pvc ) {
712 glDisable(GL_COLOR_MATERIAL);
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);
726 if ( g_nDegenerateModel ){
727 if(draw_mode <= GL_LINE_STRIP)
733 if( edge_flag || g_nDegenerateModel )
734 switch ( g_nDegenerateModel ) {
735 default: /* XXX_TDM_NODE or TINY */
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.
746 draw_edges ( p, edge_flag ? edge_colour : interior_colour );
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 );
753 case 3: /* XXX_TDM_MARKER */
754 if( p->VBOEnabled == 0 )
755 draw_degenerates_as_points ( p, edge_flag ? edge_colour : interior_colour );
757 case 4: /* XXX_TDM_BBOX */
758 if( p->VBOEnabled == 0 )
759 draw_degenerates_as_bboxs ( p, edge_flag ? edge_colour : interior_colour );
763 if(draw_mode <= GL_LINE_STRIP)
767 /*----------------------------------------------------------------------*/
770 ParrayDelete( TSM_ELEM_DATA data, Tint n, cmn_key *k )
775 /*----------------------------------------------------------------------*/
778 draw_edges ( call_def_parray p, tel_colour edge_colour )
781 Tint edge_type=0, line_type_preserve=0;
782 Tfloat edge_width=0, line_width_preserve=0;
783 /* GLboolean texture_on;*/
789 if( draw_mode > GL_LINE_STRIP ) {
790 CMN_KEY k, k1, k2, k3, k4;
792 k1.id = TelPolylineWidth;
793 k2.id = TelPolylineType;
795 k4.id = TelEdgeWidth;
797 TsmGetAttri( 4, &k1, &k2, &k3, &k4 );
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;
804 if( line_width_preserve != edge_width ) {
805 k.id = TelPolylineWidth;
806 k.data.fdata = edge_width;
807 TsmSetAttri( 1, &k );
809 if( line_type_preserve != edge_type ) {
810 k.id = TelPolylineType;
811 k.data.ldata = edge_type;
812 TsmSetAttri( 1, &k );
815 glPushAttrib( GL_POLYGON_BIT );
816 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
819 // OCC22236 NOTE: draw edges for all situations:
820 // 1) draw elements with GL_LINE style as edges from p->bufferVBO[VBOEdges] indicies array
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
823 if(p->flagBufferVBO == VBO_OK)
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]);
831 // draw primitives by vertex count with the indicies
832 if( p->num_bounds > 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];
839 // draw one (or sequential) primitive by the indicies
841 glDrawElements( draw_mode, p->num_edges , GL_UNSIGNED_INT, 0);
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]);
851 glDrawArrays( draw_mode, 0, p->num_vertexs);
855 glDisableClientState(GL_VERTEX_ARRAY);
856 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
857 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
861 glEnableClientState(GL_VERTEX_ARRAY);
862 glVertexPointer(3, GL_FLOAT, 0, p->vertices); /* array of vertices */
865 glEnableClientState(GL_EDGE_FLAG_ARRAY);
866 glEdgeFlagPointer( sizeof(Tchar), p->edge_vis);
868 glDisableClientState(GL_EDGE_FLAG_ARRAY);
871 glGetIntegerv( GL_RENDER_MODE, &renderMode );
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++ ) {
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] );
887 if( renderMode == GL_FEEDBACK )
888 draw_primitive_elements( p, draw_mode, p->bounds[i],
889 GL_UNSIGNED_INT, (GLenum*)&p->edges[n]);
891 glDrawElements( draw_mode, p->bounds[i],
892 GL_UNSIGNED_INT, &p->edges[n]);
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]);
900 glDrawArrays( draw_mode, n, p->bounds[i]);
905 else if( p->num_edges > 0 ) {
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] );
916 if( renderMode == GL_FEEDBACK )
917 draw_primitive_elements( p, draw_mode, p->num_edges,
918 GL_UNSIGNED_INT,(GLenum*) p->edges);
920 glDrawElements( draw_mode, p->num_edges,
921 GL_UNSIGNED_INT, p->edges);
923 if( renderMode == GL_FEEDBACK )
924 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
926 glDrawArrays( draw_mode, 0, p->num_vertexs);
930 if( draw_mode > GL_LINE_STRIP ) {
932 if( line_width_preserve != edge_width ) {
933 k.id = TelPolylineWidth;
934 k.data.fdata = line_width_preserve;
935 TsmSetAttri( 1, &k );
937 if( line_type_preserve != edge_type ) {
938 k.id = TelPolylineType;
939 k.data.ldata = line_type_preserve;
940 TsmSetAttri( 1, &k );
946 /*----------------------------------------------------------------------*/
947 static void draw_degenerates_points_as_points ( call_def_parray p ) {
950 tel_point pv = p -> vertices;
953 if ( g_fSkipRatio == 1. )
957 for ( j=0 ; j<p->num_vertexs ; j++ ) {
958 glVertex3fv ( &pv[j].xyz[0] );
962 /*----------------------------------------------------------------------*/
963 static void draw_degenerates_lines_as_points ( call_def_parray p ) {
967 tel_point pv = p -> vertices;
970 if ( g_fSkipRatio == 1. )
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 ];
989 /*----------------------------------------------------------------------*/
990 static void draw_degenerates_triangles_as_points ( call_def_parray p ) {
994 tel_point pv = p -> vertices;
997 if ( g_fSkipRatio == 1. )
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++ ) {
1006 pt[ 0 ] += pv[iv].xyz[ 0 ];
1007 pt[ 1 ] += pv[iv].xyz[ 1 ];
1008 pt[ 2 ] += pv[iv].xyz[ 2 ];
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 ];
1031 /*----------------------------------------------------------------------*/
1032 static void draw_degenerates_trianglestrips_as_points ( call_def_parray p ) {
1036 tel_point pv = p -> vertices;
1039 if ( g_fSkipRatio == 1. )
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 ];
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 ];
1075 /*----------------------------------------------------------------------*/
1076 static void draw_degenerates_polygons_as_points ( call_def_parray p ) {
1080 tel_point pv = p -> vertices;
1083 if ( g_fSkipRatio == 1. )
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++ ) {
1093 pt[ 0 ] += pv[iv].xyz[ 0 ];
1094 pt[ 1 ] += pv[iv].xyz[ 1 ];
1095 pt[ 2 ] += pv[iv].xyz[ 2 ];
1097 pt[ 0 ] /= p->bounds[k];
1098 pt[ 1 ] /= p->bounds[k];
1099 pt[ 2 ] /= p->bounds[k];
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 ];
1111 pt[ 0 ] /= p->bounds[k];
1112 pt[ 1 ] /= p->bounds[k];
1113 pt[ 2 ] /= p->bounds[k];
1118 } else if( p->num_edges > 0 ) {
1119 pt[0] = pt[1] = pt[2] = 0.;
1120 for ( j=0 ; j<p->num_edges ; j++ ) {
1122 pt[ 0 ] += pv[iv].xyz[ 0 ];
1123 pt[ 1 ] += pv[iv].xyz[ 1 ];
1124 pt[ 2 ] += pv[iv].xyz[ 2 ];
1126 pt[ 0 ] /= p->num_edges;
1127 pt[ 1 ] /= p->num_edges;
1128 pt[ 2 ] /= p->num_edges;
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 ];
1137 pt[ 0 ] /= p->num_vertexs;
1138 pt[ 1 ] /= p->num_vertexs;
1139 pt[ 2 ] /= p->num_vertexs;
1144 /*----------------------------------------------------------------------*/
1145 static void draw_degenerates_quadrangles_as_points ( call_def_parray p ) {
1149 tel_point pv = p -> vertices;
1152 if ( g_fSkipRatio == 1. )
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++ ) {
1161 pt[ 0 ] += pv[iv].xyz[ 0 ];
1162 pt[ 1 ] += pv[iv].xyz[ 1 ];
1163 pt[ 2 ] += pv[iv].xyz[ 2 ];
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 ];
1186 /*----------------------------------------------------------------------*/
1187 static void draw_degenerates_quadranglestrips_as_points ( call_def_parray p ) {
1191 tel_point pv = p -> vertices;
1194 if ( g_fSkipRatio == 1. )
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 ];
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 ];
1230 /*----------------------------------------------------------------------*/
1231 static void draw_degenerates_as_points ( call_def_parray p,
1232 tel_colour edge_colour )
1235 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1237 if( zbuff_state ) glDisable(GL_DEPTH_TEST);
1238 glColor3fv( edge_colour->rgb );
1239 glBegin ( GL_POINTS );
1240 switch( draw_mode ) {
1242 draw_degenerates_points_as_points( p );
1245 draw_degenerates_lines_as_points( p );
1249 draw_degenerates_polygons_as_points( p );
1252 draw_degenerates_triangles_as_points( p );
1255 draw_degenerates_quadrangles_as_points( p );
1257 case GL_TRIANGLE_FAN:
1258 case GL_TRIANGLE_STRIP:
1259 draw_degenerates_trianglestrips_as_points( p );
1262 draw_degenerates_quadranglestrips_as_points( p );
1270 if( zbuff_state ) glEnable(GL_DEPTH_TEST);
1273 /*----------------------------------------------------------------------*/
1274 static void draw_degenerates_lines_as_lines ( call_def_parray p ) {
1277 tel_point pv = p -> vertices;
1280 j = (int)((1.-g_fSkipRatio)*n);
1283 p->keys[i] = -p->keys[i];
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++ ) {
1292 if( p->keys[iv] < 0 ) {
1293 p->keys[iv] = -p->keys[iv];
1294 glVertex3fv ( pv[iv].xyz );
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 );
1313 } else if( p->num_edges > 0 ) {
1314 glBegin ( GL_LINES );
1315 for ( j=0 ; j<p->num_edges ; j++ ) {
1317 if( p->keys[iv] < 0 ) {
1318 p->keys[iv] = -p->keys[iv];
1319 glVertex3fv ( pv[iv].xyz );
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 );
1335 /*----------------------------------------------------------------------*/
1336 static void draw_degenerates_triangles_as_lines ( call_def_parray p )
1340 tel_point pv = p -> vertices;
1342 n = p->num_vertexs/3;
1343 j = (int)((1.-g_fSkipRatio)*n);
1345 i = OGL_Rand() % n; i *= 3;
1346 p->keys[i] = -p->keys[i];
1349 if( p->num_edges > 0 ) {
1350 for ( j=0 ; j<p->num_edges ; j+=3 ) {
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++ ) {
1357 glVertex3fv ( pv[iv].xyz );
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 );
1376 /*----------------------------------------------------------------------*/
1377 static void draw_degenerates_trianglestrips_as_lines ( call_def_parray p )
1381 tel_point pv = p -> vertices;
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);
1388 j = OGL_Rand() % ni; j += 2;
1389 p->keys[n+j] = -p->keys[n+j];
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 );
1404 ni = p->num_vertexs-2;
1405 k = (int)((1.-g_fSkipRatio)*ni);
1407 j = OGL_Rand() % ni; j += 2;
1408 p->keys[j] = -p->keys[j];
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 );
1423 /*----------------------------------------------------------------------*/
1424 static void draw_degenerates_polygons_as_lines ( call_def_parray p )
1427 tel_point pv = p -> vertices;
1430 j = (int)((1.-g_fSkipRatio)*n);
1433 p->keys[i] = -p->keys[i];
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++ ) {
1442 if( p->keys[iv] < 0 ) {
1443 p->keys[iv] = -p->keys[iv];
1444 glVertex3fv ( pv[iv].xyz );
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 );
1463 } else if( p->num_edges > 0 ) {
1464 glBegin ( GL_LINE_LOOP );
1465 for ( j=0 ; j<p->num_edges ; j++ ) {
1467 if( p->keys[iv] < 0 ) {
1468 p->keys[iv] = -p->keys[iv];
1469 glVertex3fv ( pv[iv].xyz );
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 );
1486 /*----------------------------------------------------------------------*/
1487 static void draw_degenerates_quadrangles_as_lines ( call_def_parray p )
1491 tel_point pv = p -> vertices;
1493 n = p->num_vertexs/4;
1494 j = (int)((1.-g_fSkipRatio)*n);
1496 i = OGL_Rand() % n; i *= 4;
1497 p->keys[i] = -p->keys[i];
1500 if( p->num_edges > 0 ) {
1501 for ( j=0 ; j<p->num_edges ; j+=4 ) {
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++ ) {
1508 glVertex3fv ( pv[iv].xyz );
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 );
1527 /*----------------------------------------------------------------------*/
1528 static void draw_degenerates_quadranglestrips_as_lines ( call_def_parray p )
1532 tel_point pv = p -> vertices;
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);
1539 j = OGL_Rand() % ni; j = j*2+2;
1540 p->keys[n+j] = -p->keys[n+j];
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 );
1556 ni = p->num_vertexs/2-2;
1557 k = (int)((1.-g_fSkipRatio)*ni);
1559 j = OGL_Rand() % ni; j = j*2+2;
1560 p->keys[j] = -p->keys[j];
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 );
1576 /*----------------------------------------------------------------------*/
1577 static void draw_degenerates_as_lines ( call_def_parray p,
1578 tel_colour edge_colour )
1583 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1587 if( zbuff_state ) glDisable(GL_DEPTH_TEST);
1589 glColor3fv( edge_colour->rgb );
1591 if( g_fSkipRatio != 0 ) switch( draw_mode ) {
1593 draw_degenerates_points_as_points( p );
1596 draw_degenerates_lines_as_lines( p );
1600 draw_degenerates_polygons_as_lines( p );
1603 draw_degenerates_triangles_as_lines( p );
1606 draw_degenerates_quadrangles_as_lines( p );
1608 case GL_TRIANGLE_FAN:
1609 case GL_TRIANGLE_STRIP:
1610 draw_degenerates_trianglestrips_as_lines( p );
1613 draw_degenerates_quadranglestrips_as_lines( p );
1622 GLboolean color_array_mode,
1623 edge_flag_array_mode,
1626 texture_coord_array_mode,
1629 glPushAttrib( GL_POLYGON_BIT );
1630 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
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 );
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 );
1646 if( !vertex_array_mode ) glEnableClientState( GL_VERTEX_ARRAY );
1648 glEnableClientState( GL_VERTEX_ARRAY );
1650 glVertexPointer(3, GL_FLOAT, 0, p->vertices); /* array of vertices */
1652 glGetIntegerv( GL_RENDER_MODE, &renderMode );
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]);
1661 glDrawElements( draw_mode, p->bounds[i],
1662 GL_UNSIGNED_INT, &p->edges[n]);
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]);
1670 glDrawArrays( draw_mode, n, p->bounds[i]);
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);
1679 glDrawElements( draw_mode, p->num_edges,
1680 GL_UNSIGNED_INT, p->edges);
1682 if( renderMode == GL_FEEDBACK )
1683 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
1685 glDrawArrays( draw_mode, 0, p->num_vertexs);
1689 if( !vertex_array_mode ) glDisableClientState( GL_VERTEX_ARRAY );
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 );
1700 if( zbuff_state ) glEnable(GL_DEPTH_TEST);
1704 static void draw_degenerates_as_bboxs ( call_def_parray p,
1705 tel_colour edge_colour )
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;
1715 glColor3fv( edge_colour->rgb );
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 ] ;
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 ) */
1733 glBegin ( GL_LINE_STRIP );
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 ] );
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 ] );
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 ] );
1756 } /* end draw_degenerates_as_bboxs */