1 // File: OpenGl_Polygon.cxx
2 // Created: 13 July 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_Context.hxx>
8 #include <OpenGl_Polygon.hxx>
10 #include <OpenGl_tgl_all.hxx>
11 #include <OpenGl_telem_util.hxx>
12 #include <OpenGl_TextureBox.hxx>
13 #include <OpenGl_Memory.hxx>
15 #include <OpenGl_AspectFace.hxx>
16 #include <OpenGl_Structure.hxx>
20 #if (defined(_WIN32) || defined(__WIN32__))
32 typedef EXTRA_VERTEX* extra_vertex;
36 Tint ts_num, ts_alloc;
37 void **tmesh_sequence;
38 GLenum triangle_type; /* FSXXX OPTI */
42 struct OPENGL_DISPLAY_PGN
50 static void bgntriangulate( const TEL_POLYGON_DATA *, void (APIENTRY*)() );
51 static void endtriangulate(void);
53 #ifndef GLU_VERSION_1_2
54 #define GLUtesselator GLUtriangulatorObj
55 void gluTessBeginContour();
56 void gluTessBeginPolygon();
57 void gluTessEndPolygon();
58 void gluTessEndContour();
59 #define GLU_TESS_BEGIN 100100
60 #define GLU_TESS_VERTEX 100101
61 #define GLU_TESS_END 100102
62 #define GLU_TESS_ERROR 100103
63 #define GLU_TESS_COMBINE 100105
66 /*----------------------------------------------------------------------*/
68 void OpenGl_Polygon::draw_polygon (const Handle(OpenGl_Workspace) &AWorkspace, Tint front_lighting_model) const
75 tel_texture_coord pvt;
78 pvc = myData.vcolours;
79 pvn = myData.vnormals;
80 pvt = myData.vtexturecoord;
82 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
85 ptr = myData.vertices;
87 glColor3fv( pfc->rgb );
88 if ( front_lighting_model )
89 glNormal3fv( myData.fnormal.xyz );
91 if( myData.reverse_order ) glFrontFace( GL_CW );
93 if (myData.num_vertices == 3) glBegin(GL_TRIANGLES);
94 else if(myData.num_vertices == 4) glBegin(GL_QUADS);
95 else glBegin(GL_POLYGON);
96 if( front_lighting_model )
100 if (pvt && (AWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
101 for( i=0; i<myData.num_vertices; i++, ptr++ )
103 glNormal3fv( pvn[i].xyz );
104 glTexCoord2fv( pvt[i].xy );
105 glVertex3fv( ptr->xyz );
108 for( i=0; i<myData.num_vertices; i++, ptr++ )
110 glNormal3fv( pvn[i].xyz );
111 glVertex3fv( ptr->xyz );
116 for( i=0; i<myData.num_vertices; i++, ptr++ )
118 glVertex3fv( ptr->xyz );
126 for( i=0; i<myData.num_vertices; i++, ptr++ )
128 glColor3fv( pvc[i].rgb );
129 glVertex3fv( ptr->xyz );
134 for( i=0; i<myData.num_vertices; i++, ptr++ )
136 glVertex3fv( ptr->xyz );
141 if( myData.reverse_order ) glFrontFace( GL_CCW );
145 /*----------------------------------------------------------------------*/
147 /* JWR - allow varying the size */
151 static int seq_increment = INCREMENT;
153 static const TEL_POLYGON_DATA *DaTa;
154 static GLUtesselator *tripak = 0;
157 out_bgntmesh( GLenum triangle_type )
159 OPENGL_DISPLAY_PGN *dis = DaTa->dsply;
162 if( dis->num_alloc < dis->num_of_seq )
164 dis->num_alloc += seq_increment;
168 dis->seq = new SEQ_[dis->num_alloc];
172 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
173 dis->seq = (SEQ_*)realloc( dis->seq, dis->num_alloc*sizeof(SEQ_) );
175 dis->seq = cmn_resizemem<SEQ_>( dis->seq, dis->num_alloc );
179 dis->seq[ dis->num_of_seq - 1 ].ts_num = 0;
180 dis->seq[ dis->num_of_seq - 1 ].ts_alloc = 0;
181 dis->seq[ dis->num_of_seq - 1 ].tmesh_sequence = 0;
183 #ifdef JWR_DEC_TRIFAN_BUG
184 dis->seq[ dis->num_of_seq - 1 ].triangle_type = GL_POLYGON;
187 dis->seq[ dis->num_of_seq - 1 ].triangle_type = triangle_type;
188 glBegin(triangle_type);
192 /*----------------------------------------------------------------------*/
195 out_vert1( void *data )
197 SEQ_ *s = &( DaTa->dsply->seq[ DaTa->dsply->num_of_seq - 1 ] );
200 if( s->ts_alloc < s->ts_num )
202 s->ts_alloc += seq_increment;
204 if( s->tmesh_sequence == 0 )
206 s->tmesh_sequence = new void*[s->ts_alloc];
210 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
211 s->tmesh_sequence = (void**)realloc( s->tmesh_sequence, s->ts_alloc*sizeof(void*));
213 s->tmesh_sequence = cmn_resizemem<void*>( s->tmesh_sequence, s->ts_alloc);
217 s->tmesh_sequence[ s->ts_num - 1 ] = data;
220 if ( data < (void *)0xffff ) {
223 glVertex3fv( DaTa->vertices[a].xyz );
226 extra_vertex b = (extra_vertex) data;
228 glVertex3fv( b->vert );
233 /*----------------------------------------------------------------------*/
236 out_vert2( void *data )
238 SEQ_ *s = &( DaTa->dsply->seq[ DaTa->dsply->num_of_seq - 1 ] );
241 if( s->ts_alloc < s->ts_num )
243 s->ts_alloc += seq_increment;
245 if( s->tmesh_sequence == 0 )
247 s->tmesh_sequence = new void*[s->ts_alloc];
251 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
252 s->tmesh_sequence = (void**)( s->tmesh_sequence, s->ts_alloc*sizeof(void*) );
254 s->tmesh_sequence = cmn_resizemem<void*>( s->tmesh_sequence, s->ts_alloc );
258 s->tmesh_sequence[ s->ts_num - 1 ] = data;
260 if ( data < (void *)0xffff ) {
263 glColor3fv( DaTa->vcolours[a].rgb );
264 glVertex3fv( DaTa->vertices[a].xyz );
267 extra_vertex b = (extra_vertex) data;
269 glColor3fv( DaTa->vcolours[(b->ind)].rgb );
270 glVertex3fv( b->vert );
274 /*----------------------------------------------------------------------*/
277 out_vert3( void *data )
279 SEQ_ *s = &( DaTa->dsply->seq[ DaTa->dsply->num_of_seq - 1 ] );
282 if( s->ts_alloc < s->ts_num )
284 s->ts_alloc += seq_increment;
286 if( s->tmesh_sequence == 0 )
288 s->tmesh_sequence = new void*[s->ts_alloc];
292 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
293 s->tmesh_sequence = (void**)realloc( s->tmesh_sequence, s->ts_alloc*sizeof(void*) );
295 s->tmesh_sequence = cmn_resizemem<void*>( s->tmesh_sequence, s->ts_alloc );
299 s->tmesh_sequence[ s->ts_num - 1 ] = data;
301 if ( data <= (void *)0xffff ) {
304 glNormal3fv( DaTa->vnormals[a].xyz );
305 glVertex3fv( DaTa->vertices[a].xyz);
308 extra_vertex b = (extra_vertex) data;
310 glNormal3fv( DaTa->vnormals[(b->ind)].xyz );
311 glVertex3fv( b->vert );
315 /*----------------------------------------------------------------------*/
318 mycombine( GLdouble coords[3], int *data, GLfloat w[4], void **dataout)
320 extra_vertex new_vertex = (extra_vertex) malloc(sizeof(EXTRA_VERTEX));
322 new_vertex->vert[0] = ( float )coords[0];
323 new_vertex->vert[1] = ( float )coords[1];
324 new_vertex->vert[2] = ( float )coords[2];
325 new_vertex->ind = *data;
326 *dataout = new_vertex;
329 /*----------------------------------------------------------------------*/
337 /*----------------------------------------------------------------------*/
340 out_error( GLenum error )
342 printf( "POLYGON : %s\n", (char *) gluErrorString(error) );
345 /*----------------------------------------------------------------------*/
348 bgntriangulate(const TEL_POLYGON_DATA *d, void ( APIENTRY * out_ver)() )
352 tripak = gluNewTess();
354 #if defined(linux) && !defined(NOGLUfuncptr)
355 gluTessCallback( tripak, GLU_TESS_BEGIN, (_GLUfuncptr)(out_bgntmesh) );
356 gluTessCallback( tripak, GLU_TESS_VERTEX, out_ver );
357 gluTessCallback( tripak, GLU_TESS_END, out_endtmesh );
358 gluTessCallback( tripak, GLU_TESS_ERROR, (_GLUfuncptr)(out_error) );
359 gluTessCallback( tripak, GLU_TESS_COMBINE, (_GLUfuncptr)(mycombine) );
361 gluTessCallback( tripak, GLU_TESS_BEGIN, (void (APIENTRY*)())out_bgntmesh );
362 gluTessCallback( tripak, GLU_TESS_VERTEX, (void (APIENTRY*)())out_ver );
363 gluTessCallback( tripak, GLU_TESS_END, (void (APIENTRY*)())out_endtmesh );
364 gluTessCallback( tripak, GLU_TESS_ERROR, (void (APIENTRY*)())out_error );
365 gluTessCallback( tripak, GLU_TESS_COMBINE, (void (APIENTRY*)())mycombine );
369 /*----------------------------------------------------------------------*/
375 gluDeleteTess(tripak);
378 /*----------------------------------------------------------------------*/
380 void OpenGl_Polygon::draw_polygon_concav (const Handle(OpenGl_Workspace) &AWorkspace, Tint front_lighting_model) const
389 pfc = myData.fcolour;
390 pvc = myData.vcolours;
391 pvn = myData.vnormals;
393 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
396 ptr = myData.vertices;
400 glColor3fv( pfc->rgb );
401 if ( front_lighting_model )
402 glNormal3fv( myData.fnormal.xyz );
404 if( myData.reverse_order ) glFrontFace( GL_CW );
408 if( front_lighting_model )
412 bgntriangulate(&myData, (void (APIENTRY*)())out_vert3);
416 bgntriangulate(&myData, (void (APIENTRY*)())out_vert1);
423 bgntriangulate(&myData, (void (APIENTRY*)())out_vert2);
427 bgntriangulate(&myData, (void (APIENTRY*)())out_vert1);
430 gluTessBeginPolygon( tripak, NULL );
431 gluTessBeginContour( tripak);
433 for( i=0; i<myData.num_vertices; i++, ptr++ )
435 xyz[0] = ptr->xyz[0];
436 xyz[1] = ptr->xyz[1];
437 xyz[2] = ptr->xyz[2];
439 gluTessVertex( tripak, xyz,(void * ) i );
442 double v[ 3 ] = {ptr -> xyz[ 0 ], ptr -> xyz[ 1 ], ptr -> xyz[ 2 ]};
443 gluTessVertex ( tripak, v, ( void* )i );
447 gluTessEndContour( tripak );
448 gluTessEndPolygon( tripak );
453 if( front_lighting_model )
455 draw_tmesh( pvn? 3 : 1 );
459 draw_tmesh( pvc? 2 : 1 );
463 if( myData.reverse_order ) glFrontFace( GL_CCW );
466 /*----------------------------------------------------------------------*/
468 void OpenGl_Polygon::draw_edges (const TEL_COLOUR *edge_colour, const Aspect_InteriorStyle interior_style, const Handle(OpenGl_Workspace) &AWorkspace) const
470 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
472 if ( interior_style != Aspect_IS_HIDDENLINE && aspect_face->Context().Edge == TOff )
475 glDisable(GL_LIGHTING);
476 const GLboolean texture_on = IsTextureEnabled();
477 if (texture_on) DisableTexture();
480 const OpenGl_AspectLine *aspect_line_old = AWorkspace->SetAspectLine( aspect_face->AspectEdge() );
481 AWorkspace->AspectLine( Standard_True );
484 tel_point ptr = myData.vertices;
486 glColor3fv( edge_colour->rgb );
488 glBegin(GL_LINE_LOOP);
489 for( i=0; i<myData.num_vertices; i++, ptr++ )
491 glVertex3fv( ptr->xyz );
495 // Restore line context
496 AWorkspace->SetAspectLine( aspect_line_old );
498 if (texture_on) EnableTexture();
501 /*----------------------------------------------------------------------*/
503 void OpenGl_Polygon::draw_tmesh ( Tint v ) const
509 OPENGL_DISPLAY_PGN *dis = myData.dsply;
510 for( i = 0; i < dis->num_of_seq; i++ )
514 glBegin(s->triangle_type);
519 for( j = 0, k = 0; j < s->ts_num; j++ )
521 if ( s->tmesh_sequence[j] < (void *)0xffff )
522 glVertex3fv( myData.vertices[ (long)s->tmesh_sequence[ j ] ].xyz );
524 extra_vertex b = (extra_vertex)s->tmesh_sequence[j];
525 glVertex3fv( b->vert );
533 for( j = 0, k = 0; j < s->ts_num; j++ )
535 if ( s->tmesh_sequence[j] < (void *)0xffff ) {
536 glColor3fv( myData.vcolours[ (long) s->tmesh_sequence[ j ] ].rgb );
537 glVertex3fv( myData.vertices[ (long) s->tmesh_sequence[ j ] ].xyz );
539 b = (extra_vertex) s->tmesh_sequence[j];
540 glColor3fv( myData.vcolours[(b->ind)].rgb);
541 glVertex3fv( b->vert );
548 for( j = 0, k = 0; j < s->ts_num; j++ )
550 if ( s->tmesh_sequence[j] < (void *)0xffff ) {
551 glNormal3fv( myData.vnormals[ (long) s->tmesh_sequence[ j ] ].xyz);
552 glVertex3fv( myData.vertices[ (long) s->tmesh_sequence[ j ] ].xyz);
554 b = (extra_vertex) s->tmesh_sequence[j];
555 glNormal3fv( myData.vnormals[(b->ind)].xyz);
556 glVertex3fv( b->vert );
566 /*----------------------------------------------------------------------*/
568 OpenGl_Polygon::OpenGl_Polygon (const Graphic3d_Array1OfVertex& AListVertex,
569 const Graphic3d_TypeOfPolygon AType)
571 const Standard_Integer nv = AListVertex.Length();
573 myData.num_vertices = nv;
575 myData.vertices = new TEL_POINT[nv];
576 memcpy( myData.vertices, &AListVertex(AListVertex.Lower()), nv*sizeof(TEL_POINT) );
578 myData.vertex_flag = TEL_VT_NONE;
579 myData.vnormals = NULL;
581 myData.vcolours = NULL;
583 myData.vtexturecoord = NULL;
585 myData.reverse_order = 0;
587 myData.facet_flag = TEL_FA_NONE;
588 TelGetPolygonNormal( myData.vertices, NULL, nv, myData.fnormal.xyz );
590 myData.fcolour = NULL;
592 #if defined(__sgi) || defined(IRIX)
593 // Pb with tesselator on sgi
594 myData.shape_flag = TEL_SHAPE_CONVEX;
598 case Graphic3d_TOP_UNKNOWN :
599 myData.shape_flag = TEL_SHAPE_UNKNOWN;
601 case Graphic3d_TOP_COMPLEX :
602 myData.shape_flag = TEL_SHAPE_COMPLEX;
604 case Graphic3d_TOP_CONCAVE :
605 myData.shape_flag = TEL_SHAPE_CONCAVE;
607 //case Graphic3d_TOP_CONVEX :
609 myData.shape_flag = TEL_SHAPE_CONVEX;
614 myData.dsply = new OPENGL_DISPLAY_PGN();
615 myData.dsply->num_of_seq = 0;
616 myData.dsply->num_alloc = 0;
617 myData.dsply->seq = NULL;
620 /*----------------------------------------------------------------------*/
622 OpenGl_Polygon::~OpenGl_Polygon ()
625 delete myData.fcolour;
626 if( myData.vertices )
627 delete[] myData.vertices;
628 if( myData.vcolours )
629 delete[] myData.vcolours;
630 if( myData.vnormals )
631 delete[] myData.vnormals;
632 if ( myData.vtexturecoord )
633 delete myData.vtexturecoord;
639 for( i = 0; i < myData.dsply->num_of_seq; i++ )
641 if(myData.dsply->seq[i].tmesh_sequence) {
642 for ( j = 0; j < myData.dsply->seq[i].ts_num ; j++ ) {
643 if ( myData.dsply->seq[i].tmesh_sequence[j] >= (void *)0xffff )
644 free(myData.dsply->seq[i].tmesh_sequence[j]);
647 delete[] myData.dsply->seq[i].tmesh_sequence;
649 delete[] myData.dsply->seq;
654 /*----------------------------------------------------------------------*/
656 void OpenGl_Polygon::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
658 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
660 Tint front_lighting_model = aspect_face->Context().IntFront.color_mask;
661 const Aspect_InteriorStyle interior_style = aspect_face->Context().InteriorStyle;
662 const TEL_COLOUR *interior_colour = &aspect_face->Context().IntFront.matcol;
663 const TEL_COLOUR *edge_colour = &aspect_face->AspectEdge()->Color();
665 // Use highlight colous
666 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
668 edge_colour = interior_colour = AWorkspace->HighlightColor;
669 front_lighting_model = 0;
672 if( interior_style != Aspect_IS_EMPTY && AWorkspace->DegenerateModel < 2 )
674 if ( front_lighting_model )
675 glEnable(GL_LIGHTING);
677 glDisable(GL_LIGHTING);
679 glColor3fv( interior_colour->rgb );
681 if( myData.shape_flag != TEL_SHAPE_CONVEX )
682 draw_polygon_concav( AWorkspace, front_lighting_model );
684 draw_polygon( AWorkspace, front_lighting_model );
687 /* OCC11904 -- Temporarily disable environment mapping */
688 glPushAttrib(GL_ENABLE_BIT);
689 glDisable(GL_TEXTURE_1D);
690 glDisable(GL_TEXTURE_2D);
692 switch ( AWorkspace->DegenerateModel )
695 draw_edges ( edge_colour, interior_style, AWorkspace );
697 case 3: /* marker degeneration */
701 glPopAttrib(); /* skt: GL_ENABLE_BIT*/
704 /*----------------------------------------------------------------------*/