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 <OpenGl_ResourceCleaner.hxx>
59 #include <OpenGl_ResourceVBO.hxx>
60 #include <InterfaceGraphic_PrimitiveArray.hxx>
61 #include <OpenGl_Memory.hxx>
62 #include <Standard.hxx>
65 # define DEF_DS_INTERNAL
66 # include <OpenGl_degeneration.hxx>
68 #include <OpenGl_Extension.hxx>
70 extern GLboolean g_fBitmap;
72 typedef CALL_DEF_PARRAY *call_def_parray;
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
80 typedef void (APIENTRY* PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
81 typedef void (APIENTRY* PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
82 typedef void (APIENTRY* PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
83 typedef void (APIENTRY* PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
85 typedef void (*PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
86 typedef void (*PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
87 typedef void (*PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
89 typedef void (*PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
91 typedef void (*PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
96 PFNGLGENBUFFERSARBPROC glVBOGenBuffersARB = NULL; // VBO Name Generation Procedure
97 PFNGLBINDBUFFERARBPROC glVBOBindBufferARB = NULL; // VBO Bind Procedure
98 PFNGLBUFFERDATAARBPROC glVBOBufferDataARB = NULL; // VBO Data Loading Procedure
99 PFNGLDELETEBUFFERSARBPROC glVBODeleteBuffersARB = NULL; // VBO Data Deleting Procedure
101 int VBOExtension = 0;
104 #define VBO_NOT_INITIALIZED -1
109 #define glGetProcAddress( x ) glXGetProcAddress( (const GLubyte*) x )
111 #define glGetProcAddress( x ) wglGetProcAddress( x )
114 void clearRAMMemory( CALL_DEF_PARRAY* p )
116 if( p->bufferVBO[VBOEdges] ){
117 Standard::Free((Standard_Address&)p->edges);
120 if( p->bufferVBO[VBOVertices] ){
121 Standard::Free((Standard_Address&)p->vertices);
124 if( p->bufferVBO[VBOVcolours] ){
125 Standard::Free((Standard_Address&)p->vcolours);
128 if( p->bufferVBO[VBOVnormals] ){
129 Standard::Free((Standard_Address&)p->vnormals);
132 if( p->bufferVBO[VBOVtexels] ){
133 Standard::Free((Standard_Address&)p->vtexels);
137 Standard::Free((Standard_Address&)p->edge_vis);
142 void clearGraphicRAMMemory( CALL_DEF_PARRAY* p )
144 if( p->bufferVBO[VBOEdges] ){
145 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOEdges]);
147 if( p->bufferVBO[VBOVertices] ){
148 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVertices]);
150 if( p->bufferVBO[VBOVcolours] ){
151 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVcolours]);
153 if( p->bufferVBO[VBOVnormals] ){
154 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVnormals]);
156 if( p->bufferVBO[VBOVtexels] ){
157 glVBODeleteBuffersARB( 1 , &p->bufferVBO[VBOVtexels]);
159 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
160 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
163 int checkSizeForGraphicMemory( CALL_DEF_PARRAY* p )
165 if( GL_OUT_OF_MEMORY == glGetError() ){
166 p->flagBufferVBO = VBO_ERROR;
167 clearGraphicRAMMemory(p);
170 p->flagBufferVBO = VBO_OK;
171 return p->flagBufferVBO ;
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");
187 static void BuildVBO( CALL_DEF_PARRAY* p )
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 )
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 )
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 )
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)
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 )
235 if( p->flagBufferVBO == VBO_OK )
238 //specify context for VBO resource
239 p->contextId = (Standard_Address)GET_GL_CONTEXT();
243 /*----------------------------------------------------------------------*/
248 /*----------------------------------------------------------------------*/
253 static TStatus ParrayDisplay( TSM_ELEM_DATA, Tint, cmn_key* );
254 static TStatus ParrayAdd( TSM_ELEM_DATA, Tint, cmn_key* );
255 static TStatus ParrayDelete( TSM_ELEM_DATA, Tint, cmn_key* );
256 static TStatus ParrayPrint( TSM_ELEM_DATA, Tint, cmn_key* );
257 static TStatus ParrayInquire( TSM_ELEM_DATA, Tint, cmn_key* );
259 /*static GLboolean lighting_mode;*/
261 static void draw_array(
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, */
275 static void draw_edges ( call_def_parray, tel_colour );
276 static void draw_degenerates_as_points ( call_def_parray, tel_colour );
277 static void draw_degenerates_as_lines ( call_def_parray, tel_colour );
278 static void draw_degenerates_as_bboxs ( call_def_parray, tel_colour );
280 static TStatus (*MtdTbl[])( TSM_ELEM_DATA, Tint, cmn_key* ) =
282 NULL, /* PickTraverse */
289 static GLenum draw_mode;
291 /*----------------------------------------------------------------------*/
296 extern Tint ForbidSetTextureMapping; /* currently defined in tsm/tsm.c */
298 extern int g_nDegenerateModel;
299 extern float g_fSkipRatio;
301 /*----------------------------------------------------------------------*/
304 TelParrayInitClass( TelType* el )
310 /*----------------------------------------------------------------------*/
313 ParrayAdd( TSM_ELEM_DATA d, Tint n, cmn_key *k )
316 if( k[0]->id != PARRAY_ID ) return TFailure;
318 ((tsm_elem_data)(d.pdata))->pdata = k[0]->data.pdata;
323 /*----------------------------------------------------------------------*/
326 ParrayDisplay( TSM_ELEM_DATA data, Tint n, cmn_key *k )
328 CMN_KEY k11, k12, k17, k18, k111, k114, k115;
330 Tint front_lighting_model;
332 TEL_COLOUR interior_colour;
333 TEL_COLOUR edge_colour;
334 TEL_COLOUR line_colour;
342 call_def_parray d = (call_def_parray)data.pdata;
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;
355 k117.id = TelSurfaceAreaProperties;
356 k117.data.pdata = ∝
360 TsmGetAttri( 7, &k12, &k17, &k18, &k111, &k114, &k115, &k117 );
362 TsmGetAttri( 6, &k12, &k17, &k18, &k111, &k114, &k115 );
365 front_lighting_model = k12.data.ldata;
366 interior_style = k17.data.ldata;
367 edge_flag = k18.data.ldata;
370 printf("ParrayDisplay type %d\n",d->type);
374 * Use highlight colours
377 if( k[0]->id == TOn ) {
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;
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;
402 draw_array( d, k[0]->id,
403 front_lighting_model,
418 /*----------------------------------------------------------------------*/
421 draw_primitive_array( call_def_parray p, GLenum mode, GLint first, GLsizei count )
425 for( i=first; i<(first + count); i++ ){
427 glNormal3fv( p->vnormals[i].xyz );
428 if( p->vtexels && !ForbidSetTextureMapping )
429 glTexCoord3fv( p->vtexels[i].xy );
431 glVertex3fv( p->vertices[i].xyz );
433 glColor4ubv( (GLubyte*) p->vcolours[i] );
438 /*----------------------------------------------------------------------*/
440 draw_primitive_elements( call_def_parray p, GLenum mode, GLsizei count, GLenum type, GLenum *indices )
445 for( i=0; i<count; i++ ){
448 glNormal3fv( p->vnormals[index].xyz );
449 if( p->vtexels && !ForbidSetTextureMapping )
450 glTexCoord3fv( p->vtexels[index].xy );
452 glVertex3fv( p->vertices[index].xyz );
454 glColor4ubv( (GLubyte*) p->vcolours[index] );
458 /*----------------------------------------------------------------------*/
460 draw_array( call_def_parray p, Tint hflag,
464 tel_colour interior_colour,
465 tel_colour line_colour,
466 tel_colour edge_colour
474 /* Following pointers have been provided for performance improvement */
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 );
490 pvc[i] = ( pvc[i] & 0x00ffffff );
491 pvc[i] += transp << 24;
498 case TelPointsArrayType:
499 draw_mode = GL_POINTS;
500 glColor3fv( line_colour->rgb );
502 case TelPolylinesArrayType:
503 draw_mode = GL_LINE_STRIP;
504 glColor3fv( line_colour->rgb );
506 case TelSegmentsArrayType:
507 draw_mode = GL_LINES;
508 glColor3fv( line_colour->rgb );
510 case TelPolygonsArrayType:
511 draw_mode = GL_POLYGON;
512 glColor3fv( interior_colour->rgb );
514 case TelTrianglesArrayType:
515 draw_mode = GL_TRIANGLES;
516 glColor3fv( interior_colour->rgb );
518 case TelQuadranglesArrayType:
519 draw_mode = GL_QUADS;
520 glColor3fv( interior_colour->rgb );
522 case TelTriangleStripsArrayType:
523 draw_mode = GL_TRIANGLE_STRIP;
524 glColor3fv( interior_colour->rgb );
526 case TelQuadrangleStripsArrayType:
527 draw_mode = GL_QUAD_STRIP;
528 glColor3fv( interior_colour->rgb );
530 case TelTriangleFansArrayType:
531 draw_mode = GL_TRIANGLE_FAN;
532 glColor3fv( interior_colour->rgb );
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);
545 if( p->VBOEnabled == -1 ){
546 p->VBOEnabled = VBOenabled;
547 if( VBOExtension == 0)
549 if( (VBOExtension == 1) && (p->VBOEnabled != 0))
555 printf(" $$$ g_nDegenerateModel %d\n",g_nDegenerateModel);
557 if ( g_nDegenerateModel < 2 &&
558 ( (draw_mode > GL_LINE_STRIP && interior_style != TSM_EMPTY) ||
559 (draw_mode <= GL_LINE_STRIP /*&& !hflag*/)) ) {
566 if ( interior_style == TSM_HIDDENLINE) {
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*/
577 if( lighting_model == CALL_PHIGS_REFL_NONE || draw_mode <= GL_LINE_STRIP )
580 glGetIntegerv( GL_RENDER_MODE, &renderMode );
582 if ( p->num_vertexs > 0 && p->flagBufferVBO != VBO_OK) {
583 if( renderMode != GL_FEEDBACK ){
585 glVertexPointer(3, GL_FLOAT, 0, p->vertices);/* array of vertices */
586 glEnableClientState(GL_VERTEX_ARRAY);
590 glNormalPointer(GL_FLOAT, 0, p->vnormals);/* array of normals */
591 glEnableClientState(GL_NORMAL_ARRAY);
595 glTexCoordPointer(2, GL_FLOAT, 0, p->vtexels);/* array of texture coordinates */
596 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
601 glColorPointer(4, GL_UNSIGNED_BYTE, 0, pvc); /* array of colors */
603 glColorPointer(3, GL_UNSIGNED_BYTE, 0, pvc); /* array of colors */
605 glEnableClientState(GL_COLOR_ARRAY);
606 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
607 glEnable(GL_COLOR_MATERIAL);
612 //Bindings concrete pointer in accordance with VBO buffer
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);
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);
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);
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);
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.
645 if( p->flagBufferVBO == VBO_OK ){
646 if ( p->num_edges > 0 && p->bufferVBO[VBOEdges] ) {
647 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, p->bufferVBO[VBOEdges]); // for edge indices
648 glDrawElements( draw_mode, p->num_edges , GL_UNSIGNED_INT, 0);
651 for( i = n = 0 ; i < p->num_bounds ; i ++ ){
652 glDrawArrays( draw_mode, n, p->bounds[i]);
657 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
658 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
661 if( p->num_bounds > 0 ) {
662 if( p->num_edges > 0 ) {
663 for( i=n=0 ; i<p->num_bounds ; i++ ) {
664 if( pfc ) glColor3fv ( pfc[i].rgb );
665 if( renderMode == GL_FEEDBACK )
666 draw_primitive_elements( p, draw_mode, p->bounds[i],
667 GL_UNSIGNED_INT,(GLenum*) &p->edges[n]);
669 glDrawElements( draw_mode, p->bounds[i],
670 GL_UNSIGNED_INT, &p->edges[n]);
674 for( i=n=0 ; i<p->num_bounds ; i++ ) {
676 glColor3fv ( pfc[i].rgb );
677 if( renderMode == GL_FEEDBACK )
678 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
681 glDrawArrays( draw_mode, n, p->bounds[i]);
686 } else if( p->num_edges > 0 ) {
687 if( renderMode == GL_FEEDBACK )
688 draw_primitive_elements( p, draw_mode, p->num_edges,
689 GL_UNSIGNED_INT,(GLenum*) &p->edges[0]);
691 glDrawElements( draw_mode, p->num_edges, GL_UNSIGNED_INT, p->edges);
693 if( renderMode == GL_FEEDBACK )
694 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
696 glDrawArrays( draw_mode, 0, p->num_vertexs);
701 if( p->bufferVBO[VBOVcolours] || pvc ) {
702 glDisable(GL_COLOR_MATERIAL);
707 if( p->bufferVBO[VBOVertices] || p->vertices )
708 glDisableClientState(GL_VERTEX_ARRAY);
709 if( p->bufferVBO[VBOVcolours] || p->vcolours )
710 glDisableClientState(GL_COLOR_ARRAY);
711 if( p->bufferVBO[VBOVnormals] || p->vnormals )
712 glDisableClientState(GL_NORMAL_ARRAY);
713 if ( (p->bufferVBO[VBOVtexels] && !ForbidSetTextureMapping ) || p->vtexels )
714 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
716 if ( g_nDegenerateModel ){
717 if(draw_mode <= GL_LINE_STRIP)
723 if( edge_flag || g_nDegenerateModel )
724 switch ( g_nDegenerateModel ) {
725 default: /* XXX_TDM_NODE or TINY */
727 On some NVIDIA graphic cards, using glEdgeFlagPointer() in
728 combination with VBO ( edge flag data put into a VBO buffer)
729 leads to a crash in a driver. Therefore, edge flags are simply
730 igonored when VBOs are enabled, so all the edges are drawn if
731 edge visibility is turned on. In order to draw edges selectively,
732 either disable VBO or turn off edge visibilty in the current
733 primitive array and create a separate primitive array (segments)
734 and put edges to be drawn into it.
736 draw_edges ( p, edge_flag ? edge_colour : interior_colour );
738 // DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
739 case 2: /* XXX_TDM_WIREFRAME */
740 if( p->VBOEnabled == 0 )
741 draw_degenerates_as_lines ( p, edge_flag ? edge_colour : interior_colour );
743 case 3: /* XXX_TDM_MARKER */
744 if( p->VBOEnabled == 0 )
745 draw_degenerates_as_points ( p, edge_flag ? edge_colour : interior_colour );
747 case 4: /* XXX_TDM_BBOX */
748 if( p->VBOEnabled == 0 )
749 draw_degenerates_as_bboxs ( p, edge_flag ? edge_colour : interior_colour );
753 if(draw_mode <= GL_LINE_STRIP)
757 /*----------------------------------------------------------------------*/
760 ParrayDelete( TSM_ELEM_DATA data, Tint n, cmn_key *k )
762 call_def_parray p = (call_def_parray)data.pdata;
763 if( p->VBOEnabled == VBO_OK ) {
764 OpenGl_ResourceCleaner* resCleaner = OpenGl_ResourceCleaner::GetInstance();
765 if( p->bufferVBO[VBOEdges] )
766 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOEdges]) );
767 if( p->bufferVBO[VBOVertices] )
768 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVertices]) );
769 if( p->bufferVBO[VBOVcolours] )
770 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVcolours]) );
771 if( p->bufferVBO[VBOVnormals] )
772 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVnormals]) );
773 if( p->bufferVBO[VBOVtexels] )
774 resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVtexels]) );
780 /*----------------------------------------------------------------------*/
783 draw_edges ( call_def_parray p, tel_colour edge_colour )
786 Tint edge_type=0, line_type_preserve=0;
787 Tfloat edge_width=0, line_width_preserve=0;
788 /* GLboolean texture_on;*/
794 if( draw_mode > GL_LINE_STRIP ) {
795 CMN_KEY k, k1, k2, k3, k4;
797 k1.id = TelPolylineWidth;
798 k2.id = TelPolylineType;
800 k4.id = TelEdgeWidth;
802 TsmGetAttri( 4, &k1, &k2, &k3, &k4 );
804 line_width_preserve = k1.data.fdata;
805 line_type_preserve = k2.data.ldata;
806 edge_type = k3.data.ldata;
807 edge_width = k4.data.fdata;
809 if( line_width_preserve != edge_width ) {
810 k.id = TelPolylineWidth;
811 k.data.fdata = edge_width;
812 TsmSetAttri( 1, &k );
814 if( line_type_preserve != edge_type ) {
815 k.id = TelPolylineType;
816 k.data.ldata = edge_type;
817 TsmSetAttri( 1, &k );
820 glPushAttrib( GL_POLYGON_BIT );
821 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
824 // OCC22236 NOTE: draw edges for all situations:
825 // 1) draw elements with GL_LINE style as edges from p->bufferVBO[VBOEdges] indicies array
826 // 2) draw elements with GL_LINE style as edges from vertice array,
827 // when bounds defines count of primitive's verts.
828 if(p->flagBufferVBO == VBO_OK)
830 glVBOBindBufferARB( GL_ARRAY_BUFFER_ARB, p->bufferVBO[VBOVertices] );
831 glEnableClientState( GL_VERTEX_ARRAY );
832 glColor3fv( edge_colour->rgb );
833 if ( p->num_edges > 0 && p->bufferVBO[VBOEdges] ) {
834 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, p->bufferVBO[VBOEdges]);
835 glDrawElements( draw_mode, p->num_edges, GL_UNSIGNED_INT, 0);
838 for( i = n = 0 ; i < p->num_bounds ; i ++ ) {
839 glDrawArrays( draw_mode , n , p->bounds[i]);
843 glDisableClientState(GL_VERTEX_ARRAY);
844 glVBOBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
845 glVBOBindBufferARB(GL_ELEMENTS_ARRAY_BUFFER_ARB, 0);
849 glEnableClientState(GL_VERTEX_ARRAY);
850 glVertexPointer(3, GL_FLOAT, 0, p->vertices); /* array of vertices */
853 glEnableClientState(GL_EDGE_FLAG_ARRAY);
854 glEdgeFlagPointer( sizeof(Tchar), p->edge_vis);
856 glDisableClientState(GL_EDGE_FLAG_ARRAY);
859 glGetIntegerv( GL_RENDER_MODE, &renderMode );
861 glColor3fv( edge_colour->rgb );
862 if( p->num_bounds > 0 ) {
863 if( p->num_edges > 0 ) {
864 for( i=n=0 ; i<p->num_bounds ; i++ ) {
867 glBegin( draw_mode );
868 for( j=0 ; j<p->bounds[i] ; j++ ) {
869 glEdgeFlag( p->edge_vis[n+j] );
870 glVertex3fv( &p->vertices[p->edges[n+j]].xyz[0] );
875 if( renderMode == GL_FEEDBACK )
876 draw_primitive_elements( p, draw_mode, p->bounds[i],
877 GL_UNSIGNED_INT, (GLenum*)&p->edges[n]);
879 glDrawElements( draw_mode, p->bounds[i],
880 GL_UNSIGNED_INT, &p->edges[n]);
884 for( i=n=0 ; i<p->num_bounds ; i++ ) {
885 if( renderMode == GL_FEEDBACK )
886 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
888 glDrawArrays( draw_mode, n, p->bounds[i]);
893 else if( p->num_edges > 0 ) {
896 glBegin( draw_mode );
897 for( i=0 ; i<p->num_edges ; i++ ) {
898 glEdgeFlag( p->edge_vis[i] );
899 glVertex3fv( &p->vertices[p->edges[i]].xyz[0] );
904 if( renderMode == GL_FEEDBACK )
905 draw_primitive_elements( p, draw_mode, p->num_edges,
906 GL_UNSIGNED_INT,(GLenum*) p->edges);
908 glDrawElements( draw_mode, p->num_edges,
909 GL_UNSIGNED_INT, p->edges);
911 if( renderMode == GL_FEEDBACK )
912 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
914 glDrawArrays( draw_mode, 0, p->num_vertexs);
918 if( draw_mode > GL_LINE_STRIP ) {
920 if( line_width_preserve != edge_width ) {
921 k.id = TelPolylineWidth;
922 k.data.fdata = line_width_preserve;
923 TsmSetAttri( 1, &k );
925 if( line_type_preserve != edge_type ) {
926 k.id = TelPolylineType;
927 k.data.ldata = line_type_preserve;
928 TsmSetAttri( 1, &k );
934 /*----------------------------------------------------------------------*/
935 static void draw_degenerates_points_as_points ( call_def_parray p ) {
938 tel_point pv = p -> vertices;
941 if ( g_fSkipRatio == 1. )
945 for ( j=0 ; j<p->num_vertexs ; j++ ) {
946 glVertex3fv ( &pv[j].xyz[0] );
950 /*----------------------------------------------------------------------*/
951 static void draw_degenerates_lines_as_points ( call_def_parray p ) {
955 tel_point pv = p -> vertices;
958 if ( g_fSkipRatio == 1. )
962 for ( j=0 ; j<p->num_vertexs ; j+=2 ) {
963 pt[0] = pt[1] = pt[2] = 0.;
964 pt[ 0 ] += pv[j].xyz[ 0 ];
965 pt[ 1 ] += pv[j].xyz[ 1 ];
966 pt[ 2 ] += pv[j].xyz[ 2 ];
967 pt[ 0 ] += pv[j+1].xyz[ 0 ];
968 pt[ 1 ] += pv[j+1].xyz[ 1 ];
969 pt[ 2 ] += pv[j+1].xyz[ 2 ];
977 /*----------------------------------------------------------------------*/
978 static void draw_degenerates_triangles_as_points ( call_def_parray p ) {
982 tel_point pv = p -> vertices;
985 if ( g_fSkipRatio == 1. )
989 if( p->num_edges > 0 ) {
990 for ( j=0 ; j<p->num_edges ; j+=3 ) {
991 pt[0] = pt[1] = pt[2] = 0.;
992 for ( i=0 ; i<3 ; i++ ) {
994 pt[ 0 ] += pv[iv].xyz[ 0 ];
995 pt[ 1 ] += pv[iv].xyz[ 1 ];
996 pt[ 2 ] += pv[iv].xyz[ 2 ];
1004 for ( j=0 ; j<p->num_vertexs ; j+=3 ) {
1005 pt[0] = pt[1] = pt[2] = 0.;
1006 for ( i=0 ; i<3 ; i++ ) {
1007 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1008 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1009 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1019 /*----------------------------------------------------------------------*/
1020 static void draw_degenerates_trianglestrips_as_points ( call_def_parray p ) {
1024 tel_point pv = p -> vertices;
1027 if ( g_fSkipRatio == 1. )
1031 if( p->num_bounds > 0 ) {
1032 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1033 for ( j=0 ; j<p->bounds[k]-2 ; j++ ) {
1034 pt[0] = pt[1] = pt[2] = 0.;
1035 for ( i=0 ; i<3 ; i++ ) {
1036 pt[ 0 ] += pv[n+j+i].xyz[ 0 ];
1037 pt[ 1 ] += pv[n+j+i].xyz[ 1 ];
1038 pt[ 2 ] += pv[n+j+i].xyz[ 2 ];
1048 for ( j=0 ; j<p->num_vertexs-2 ; j++ ) {
1049 pt[0] = pt[1] = pt[2] = 0.;
1050 for ( i=0 ; i<3 ; i++ ) {
1051 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1052 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1053 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1063 /*----------------------------------------------------------------------*/
1064 static void draw_degenerates_polygons_as_points ( call_def_parray p ) {
1068 tel_point pv = p -> vertices;
1071 if ( g_fSkipRatio == 1. )
1075 if( p->num_bounds > 0 ) {
1076 if( p->num_edges > 0 ) {
1077 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1078 pt[0] = pt[1] = pt[2] = 0.;
1079 for ( j=0 ; j<p->bounds[k] ; j++ ) {
1081 pt[ 0 ] += pv[iv].xyz[ 0 ];
1082 pt[ 1 ] += pv[iv].xyz[ 1 ];
1083 pt[ 2 ] += pv[iv].xyz[ 2 ];
1085 pt[ 0 ] /= p->bounds[k];
1086 pt[ 1 ] /= p->bounds[k];
1087 pt[ 2 ] /= p->bounds[k];
1092 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1093 pt[0] = pt[1] = pt[2] = 0.;
1094 for ( j=0 ; j<p->bounds[k] ; j++ ) {
1095 pt[ 0 ] += pv[n+j].xyz[ 0 ];
1096 pt[ 1 ] += pv[n+j].xyz[ 1 ];
1097 pt[ 2 ] += pv[n+j].xyz[ 2 ];
1099 pt[ 0 ] /= p->bounds[k];
1100 pt[ 1 ] /= p->bounds[k];
1101 pt[ 2 ] /= p->bounds[k];
1106 } else if( p->num_edges > 0 ) {
1107 pt[0] = pt[1] = pt[2] = 0.;
1108 for ( j=0 ; j<p->num_edges ; j++ ) {
1110 pt[ 0 ] += pv[iv].xyz[ 0 ];
1111 pt[ 1 ] += pv[iv].xyz[ 1 ];
1112 pt[ 2 ] += pv[iv].xyz[ 2 ];
1114 pt[ 0 ] /= p->num_edges;
1115 pt[ 1 ] /= p->num_edges;
1116 pt[ 2 ] /= p->num_edges;
1119 pt[0] = pt[1] = pt[2] = 0.;
1120 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1121 pt[ 0 ] += pv[j].xyz[ 0 ];
1122 pt[ 1 ] += pv[j].xyz[ 1 ];
1123 pt[ 2 ] += pv[j].xyz[ 2 ];
1125 pt[ 0 ] /= p->num_vertexs;
1126 pt[ 1 ] /= p->num_vertexs;
1127 pt[ 2 ] /= p->num_vertexs;
1132 /*----------------------------------------------------------------------*/
1133 static void draw_degenerates_quadrangles_as_points ( call_def_parray p ) {
1137 tel_point pv = p -> vertices;
1140 if ( g_fSkipRatio == 1. )
1144 if( p->num_edges > 0 ) {
1145 for ( j=0 ; j<p->num_edges ; j+=4 ) {
1146 pt[0] = pt[1] = pt[2] = 0.;
1147 for ( i=0 ; i<4 ; i++ ) {
1149 pt[ 0 ] += pv[iv].xyz[ 0 ];
1150 pt[ 1 ] += pv[iv].xyz[ 1 ];
1151 pt[ 2 ] += pv[iv].xyz[ 2 ];
1159 for ( j=0 ; j<p->num_vertexs ; j+=4 ) {
1160 pt[0] = pt[1] = pt[2] = 0.;
1161 for ( i=0 ; i<4 ; i++ ) {
1162 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1163 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1164 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1174 /*----------------------------------------------------------------------*/
1175 static void draw_degenerates_quadranglestrips_as_points ( call_def_parray p ) {
1179 tel_point pv = p -> vertices;
1182 if ( g_fSkipRatio == 1. )
1186 if( p->num_bounds > 0 ) {
1187 for ( k=n=0 ; k<p->num_bounds ; k++ ) {
1188 for ( j=0 ; j<p->bounds[k]-2 ; j+=2 ) {
1189 pt[0] = pt[1] = pt[2] = 0.;
1190 for ( i=0 ; i<4 ; i++ ) {
1191 pt[ 0 ] += pv[n+j+i].xyz[ 0 ];
1192 pt[ 1 ] += pv[n+j+i].xyz[ 1 ];
1193 pt[ 2 ] += pv[n+j+i].xyz[ 2 ];
1203 for ( j=0 ; j<p->num_vertexs-2 ; j+=2 ) {
1204 pt[0] = pt[1] = pt[2] = 0.;
1205 for ( i=0 ; i<4 ; i++ ) {
1206 pt[ 0 ] += pv[j+i].xyz[ 0 ];
1207 pt[ 1 ] += pv[j+i].xyz[ 1 ];
1208 pt[ 2 ] += pv[j+i].xyz[ 2 ];
1218 /*----------------------------------------------------------------------*/
1219 static void draw_degenerates_as_points ( call_def_parray p,
1220 tel_colour edge_colour )
1223 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1225 if( zbuff_state ) glDisable(GL_DEPTH_TEST);
1226 glColor3fv( edge_colour->rgb );
1227 glBegin ( GL_POINTS );
1228 switch( draw_mode ) {
1230 draw_degenerates_points_as_points( p );
1233 draw_degenerates_lines_as_points( p );
1237 draw_degenerates_polygons_as_points( p );
1240 draw_degenerates_triangles_as_points( p );
1243 draw_degenerates_quadrangles_as_points( p );
1245 case GL_TRIANGLE_FAN:
1246 case GL_TRIANGLE_STRIP:
1247 draw_degenerates_trianglestrips_as_points( p );
1250 draw_degenerates_quadranglestrips_as_points( p );
1258 if( zbuff_state ) glEnable(GL_DEPTH_TEST);
1261 /*----------------------------------------------------------------------*/
1262 static void draw_degenerates_lines_as_lines ( call_def_parray p ) {
1265 tel_point pv = p -> vertices;
1268 j = (int)((1.-g_fSkipRatio)*n);
1271 p->keys[i] = -p->keys[i];
1274 if( p->num_bounds > 0 ) {
1275 if( p->num_edges > 0 ) {
1276 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1277 glBegin ( GL_LINES );
1278 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1280 if( p->keys[iv] < 0 ) {
1281 p->keys[iv] = -p->keys[iv];
1282 glVertex3fv ( pv[iv].xyz );
1289 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1290 glBegin ( GL_LINES );
1291 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1292 if( p->keys[n+j] < 0 ) {
1293 p->keys[n+j] = -p->keys[n+j];
1294 glVertex3fv ( pv[n+j].xyz );
1301 } else if( p->num_edges > 0 ) {
1302 glBegin ( GL_LINES );
1303 for ( j=0 ; j<p->num_edges ; j++ ) {
1305 if( p->keys[iv] < 0 ) {
1306 p->keys[iv] = -p->keys[iv];
1307 glVertex3fv ( pv[iv].xyz );
1312 glBegin ( GL_LINES );
1313 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1314 if( p->keys[j] < 0 ) {
1315 p->keys[j] = -p->keys[j];
1316 glVertex3fv ( pv[j].xyz );
1323 /*----------------------------------------------------------------------*/
1324 static void draw_degenerates_triangles_as_lines ( call_def_parray p )
1328 tel_point pv = p -> vertices;
1330 n = p->num_vertexs/3;
1331 j = (int)((1.-g_fSkipRatio)*n);
1333 i = OGL_Rand() % n; i *= 3;
1334 p->keys[i] = -p->keys[i];
1337 if( p->num_edges > 0 ) {
1338 for ( j=0 ; j<p->num_edges ; j+=3 ) {
1340 if( p->keys[iv] < 0 ) {
1341 p->keys[iv] = -p->keys[iv];
1342 glBegin ( GL_LINE_LOOP );
1343 for ( i=0 ; i<3 ; i++ ) {
1345 glVertex3fv ( pv[iv].xyz );
1351 for ( j=0 ; j<p->num_vertexs ; j+=3 ) {
1352 if( p->keys[j] < 0 ) {
1353 p->keys[j] = -p->keys[j];
1354 glBegin ( GL_LINE_LOOP );
1355 for ( i=0 ; i<3 ; i++ ) {
1356 glVertex3fv ( pv[j+i].xyz );
1364 /*----------------------------------------------------------------------*/
1365 static void draw_degenerates_trianglestrips_as_lines ( call_def_parray p )
1369 tel_point pv = p -> vertices;
1371 if( p->num_bounds > 0 ) {
1372 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1373 ni = p->bounds[i]-2;
1374 k = (int)((1.-g_fSkipRatio)*ni);
1376 j = OGL_Rand() % ni; j += 2;
1377 p->keys[n+j] = -p->keys[n+j];
1379 for ( j=2 ; j<p->bounds[i] ; j++ ) {
1380 if( p->keys[n+j] < 0 ) {
1381 p->keys[n+j] = -p->keys[n+j];
1382 glBegin ( GL_LINE_LOOP );
1383 glVertex3fv ( pv[n+j-2].xyz );
1384 glVertex3fv ( pv[n+j-1].xyz );
1385 glVertex3fv ( pv[n+j].xyz );
1392 ni = p->num_vertexs-2;
1393 k = (int)((1.-g_fSkipRatio)*ni);
1395 j = OGL_Rand() % ni; j += 2;
1396 p->keys[j] = -p->keys[j];
1398 for ( j=2 ; j<p->num_vertexs ; j++ ) {
1399 if( p->keys[j] < 0 ) {
1400 p->keys[j] = -p->keys[j];
1401 glBegin ( GL_LINE_LOOP );
1402 glVertex3fv ( pv[j-2].xyz );
1403 glVertex3fv ( pv[j-1].xyz );
1404 glVertex3fv ( pv[j].xyz );
1411 /*----------------------------------------------------------------------*/
1412 static void draw_degenerates_polygons_as_lines ( call_def_parray p )
1415 tel_point pv = p -> vertices;
1418 j = (int)((1.-g_fSkipRatio)*n);
1421 p->keys[i] = -p->keys[i];
1424 if( p->num_bounds > 0 ) {
1425 if( p->num_edges > 0 ) {
1426 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1427 glBegin ( GL_LINE_LOOP );
1428 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1430 if( p->keys[iv] < 0 ) {
1431 p->keys[iv] = -p->keys[iv];
1432 glVertex3fv ( pv[iv].xyz );
1439 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1440 glBegin ( GL_LINE_LOOP );
1441 for ( j=0 ; j<p->bounds[i] ; j++ ) {
1442 if( p->keys[n+j] < 0 ) {
1443 p->keys[n+j] = -p->keys[n+j];
1444 glVertex3fv ( pv[n+j].xyz );
1451 } else if( p->num_edges > 0 ) {
1452 glBegin ( GL_LINE_LOOP );
1453 for ( j=0 ; j<p->num_edges ; j++ ) {
1455 if( p->keys[iv] < 0 ) {
1456 p->keys[iv] = -p->keys[iv];
1457 glVertex3fv ( pv[iv].xyz );
1462 glBegin ( GL_LINE_LOOP );
1463 for ( j=0 ; j<p->num_vertexs ; j++ ) {
1464 if( p->keys[j] < 0 ) {
1465 p->keys[j] = -p->keys[j];
1466 glVertex3fv ( pv[j].xyz );
1474 /*----------------------------------------------------------------------*/
1475 static void draw_degenerates_quadrangles_as_lines ( call_def_parray p )
1479 tel_point pv = p -> vertices;
1481 n = p->num_vertexs/4;
1482 j = (int)((1.-g_fSkipRatio)*n);
1484 i = OGL_Rand() % n; i *= 4;
1485 p->keys[i] = -p->keys[i];
1488 if( p->num_edges > 0 ) {
1489 for ( j=0 ; j<p->num_edges ; j+=4 ) {
1491 if( p->keys[iv] < 0 ) {
1492 p->keys[iv] = -p->keys[iv];
1493 glBegin ( GL_LINE_LOOP );
1494 for ( i=0 ; i<4 ; i++ ) {
1496 glVertex3fv ( pv[iv].xyz );
1502 for ( j=0 ; j<p->num_vertexs ; j+=4 ) {
1503 if( p->keys[j] < 0 ) {
1504 p->keys[j] = -p->keys[j];
1505 glBegin ( GL_LINE_LOOP );
1506 for ( i=0 ; i<4 ; i++ ) {
1507 glVertex3fv ( pv[j+i].xyz );
1515 /*----------------------------------------------------------------------*/
1516 static void draw_degenerates_quadranglestrips_as_lines ( call_def_parray p )
1520 tel_point pv = p -> vertices;
1522 if( p->num_bounds > 0 ) {
1523 for ( i=n=0 ; i<p->num_bounds ; i++ ) {
1524 ni = p->bounds[i]/2-2;
1525 k = (int)((1.-g_fSkipRatio)*ni);
1527 j = OGL_Rand() % ni; j = j*2+2;
1528 p->keys[n+j] = -p->keys[n+j];
1530 for ( j=3 ; j<p->bounds[i] ; j+=2 ) {
1531 if( p->keys[n+j] < 0 ) {
1532 p->keys[n+j] = -p->keys[n+j];
1533 glBegin ( GL_LINE_LOOP );
1534 glVertex3fv ( pv[n+j-3].xyz );
1535 glVertex3fv ( pv[n+j-2].xyz );
1536 glVertex3fv ( pv[n+j-1].xyz );
1537 glVertex3fv ( pv[n+j].xyz );
1544 ni = p->num_vertexs/2-2;
1545 k = (int)((1.-g_fSkipRatio)*ni);
1547 j = OGL_Rand() % ni; j = j*2+2;
1548 p->keys[j] = -p->keys[j];
1550 for ( j=3 ; j<p->num_vertexs ; j+=2 ) {
1551 if( p->keys[j] < 0 ) {
1552 p->keys[j] = -p->keys[j];
1553 glBegin ( GL_LINE_LOOP );
1554 glVertex3fv ( pv[j-3].xyz );
1555 glVertex3fv ( pv[j-2].xyz );
1556 glVertex3fv ( pv[j-1].xyz );
1557 glVertex3fv ( pv[j].xyz );
1564 /*----------------------------------------------------------------------*/
1565 static void draw_degenerates_as_lines ( call_def_parray p,
1566 tel_colour edge_colour )
1571 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1575 if( zbuff_state ) glDisable(GL_DEPTH_TEST);
1577 glColor3fv( edge_colour->rgb );
1579 if( g_fSkipRatio != 0 ) switch( draw_mode ) {
1581 draw_degenerates_points_as_points( p );
1584 draw_degenerates_lines_as_lines( p );
1588 draw_degenerates_polygons_as_lines( p );
1591 draw_degenerates_triangles_as_lines( p );
1594 draw_degenerates_quadrangles_as_lines( p );
1596 case GL_TRIANGLE_FAN:
1597 case GL_TRIANGLE_STRIP:
1598 draw_degenerates_trianglestrips_as_lines( p );
1601 draw_degenerates_quadranglestrips_as_lines( p );
1610 GLboolean color_array_mode,
1611 edge_flag_array_mode,
1614 texture_coord_array_mode,
1617 glPushAttrib( GL_POLYGON_BIT );
1618 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
1621 color_array_mode = glIsEnabled( GL_COLOR_ARRAY );
1622 edge_flag_array_mode = glIsEnabled( GL_EDGE_FLAG_ARRAY );
1623 index_array_mode = glIsEnabled( GL_INDEX_ARRAY );
1624 normal_array_mode = glIsEnabled( GL_NORMAL_ARRAY );
1625 texture_coord_array_mode = glIsEnabled( GL_TEXTURE_COORD_ARRAY );
1626 vertex_array_mode = glIsEnabled( GL_VERTEX_ARRAY );
1628 glDisableClientState( GL_COLOR_ARRAY );
1629 glDisableClientState( GL_EDGE_FLAG_ARRAY );
1630 glDisableClientState( GL_INDEX_ARRAY );
1631 glDisableClientState( GL_NORMAL_ARRAY );
1632 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1634 if( !vertex_array_mode ) glEnableClientState( GL_VERTEX_ARRAY );
1636 glEnableClientState( GL_VERTEX_ARRAY );
1638 glVertexPointer(3, GL_FLOAT, 0, p->vertices); /* array of vertices */
1640 glGetIntegerv( GL_RENDER_MODE, &renderMode );
1642 if( p->num_bounds > 0 ) {
1643 if( p->num_edges > 0 ) {
1644 for( i=n=0 ; i<p->num_bounds ; i++ ) {
1645 if( renderMode == GL_FEEDBACK )
1646 draw_primitive_elements( p, draw_mode, p->bounds[i],
1647 GL_UNSIGNED_INT, (GLenum*) &p->edges[n]);
1649 glDrawElements( draw_mode, p->bounds[i],
1650 GL_UNSIGNED_INT, &p->edges[n]);
1654 for( i=n=0 ; i<p->num_bounds ; i++ ) {
1655 if( renderMode == GL_FEEDBACK )
1656 draw_primitive_array( p, draw_mode, n, p->bounds[i]);
1658 glDrawArrays( draw_mode, n, p->bounds[i]);
1662 } else if( p->num_edges > 0 ) {
1663 if( renderMode == GL_FEEDBACK )
1664 draw_primitive_elements( p, draw_mode, p->num_edges,
1665 GL_UNSIGNED_INT, (GLenum*) p->edges);
1667 glDrawElements( draw_mode, p->num_edges,
1668 GL_UNSIGNED_INT, p->edges);
1670 if( renderMode == GL_FEEDBACK )
1671 draw_primitive_array( p, draw_mode, 0, p->num_vertexs);
1673 glDrawArrays( draw_mode, 0, p->num_vertexs);
1677 if( !vertex_array_mode ) glDisableClientState( GL_VERTEX_ARRAY );
1679 if( color_array_mode ) glEnableClientState( GL_COLOR_ARRAY );
1680 if( edge_flag_array_mode ) glEnableClientState( GL_EDGE_FLAG_ARRAY );
1681 if( index_array_mode ) glEnableClientState( GL_INDEX_ARRAY );
1682 if( normal_array_mode ) glEnableClientState( GL_NORMAL_ARRAY );
1683 if( texture_coord_array_mode ) glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1688 if( zbuff_state ) glEnable(GL_DEPTH_TEST);
1692 static void draw_degenerates_as_bboxs ( call_def_parray p,
1693 tel_colour edge_colour )
1697 GLfloat minp[ 3 ] = { FLT_MAX, FLT_MAX, FLT_MAX };
1698 GLfloat maxp[ 3 ] = { FLT_MIN, FLT_MIN, FLT_MIN };
1699 tel_point pv = p -> vertices;
1703 glColor3fv( edge_colour->rgb );
1705 for ( i=0 ; i<p->num_vertexs ; ++i ) {
1706 if ( pv[ i ].xyz[ 0 ] < minp[ 0 ] )
1707 minp[ 0 ] = pv[ i ].xyz[ 0 ] ;
1708 if ( pv[ i ].xyz[ 1 ] < minp[ 1 ] )
1709 minp[ 1 ] = pv[ i ].xyz[ 1 ] ;
1710 if ( pv[ i ].xyz[ 2 ] < minp[ 2 ] )
1711 minp[ 2 ] = pv[ i ].xyz[ 2 ] ;
1713 if ( pv[ i ].xyz[ 0 ] > maxp[ 0 ] )
1714 maxp[ 0 ] = pv[ i ].xyz[ 0 ] ;
1715 if ( pv[ i ].xyz[ 1 ] > maxp[ 1 ] )
1716 maxp[ 1 ] = pv[ i ].xyz[ 1 ] ;
1717 if ( pv[ i ].xyz[ 2 ] > maxp[ 2 ] )
1718 maxp[ 2 ] = pv[ i ].xyz[ 2 ] ;
1719 } /* end for ( i ) */
1721 glBegin ( GL_LINE_STRIP );
1723 glVertex3fv ( minp );
1724 glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1725 glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1726 glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1727 glVertex3f ( minp[ 0 ], minp[ 1 ], minp[ 2 ] );
1729 glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
1730 glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1731 glVertex3f ( maxp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1732 glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1733 glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
1735 glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1736 glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1737 glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1738 glVertex3fv ( maxp );
1739 glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1740 glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1744 } /* end draw_degenerates_as_bboxs */