1 // Created on: 2011-07-13
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
20 #include <OpenGl_GlCore11.hxx>
22 #include <OpenGl_Polygon.hxx>
24 #include <OpenGl_telem_util.hxx>
26 #include <OpenGl_AspectFace.hxx>
27 #include <OpenGl_Structure.hxx>
28 #include <OpenGl_Workspace.hxx>
30 #if (defined(_WIN32) || defined(__WIN32__))
42 typedef EXTRA_VERTEX* extra_vertex;
46 NCollection_Vector<void *> tmesh_sequence;
47 GLenum triangle_type; /* FSXXX OPTI */
51 static void bgntriangulate( const TEL_POLYGON_DATA *, void (APIENTRY*)() );
52 static void endtriangulate(void);
54 #ifndef GLU_VERSION_1_2
55 #define GLUtesselator GLUtriangulatorObj
56 void gluTessBeginContour();
57 void gluTessBeginPolygon();
58 void gluTessEndPolygon();
59 void gluTessEndContour();
60 #define GLU_TESS_BEGIN 100100
61 #define GLU_TESS_VERTEX 100101
62 #define GLU_TESS_END 100102
63 #define GLU_TESS_ERROR 100103
64 #define GLU_TESS_COMBINE 100105
67 /*----------------------------------------------------------------------*/
69 void OpenGl_Polygon::draw_polygon (const Handle(OpenGl_Workspace) &AWorkspace, Tint front_lighting_model) const
76 tel_texture_coord pvt;
79 pvc = myData.vcolours;
80 pvn = myData.vnormals;
81 pvt = myData.vtexturecoord;
83 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
86 ptr = myData.vertices;
88 glColor3fv( pfc->rgb );
89 if ( front_lighting_model )
90 glNormal3fv( myData.fnormal.xyz );
92 if( myData.reverse_order ) glFrontFace( GL_CW );
94 if (myData.num_vertices == 3) glBegin(GL_TRIANGLES);
95 else if(myData.num_vertices == 4) glBegin(GL_QUADS);
96 else glBegin(GL_POLYGON);
97 if( front_lighting_model )
101 if (pvt && (AWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
102 for( i=0; i<myData.num_vertices; i++, ptr++ )
104 glNormal3fv( pvn[i].xyz );
105 glTexCoord2fv( pvt[i].xy );
106 glVertex3fv( ptr->xyz );
109 for( i=0; i<myData.num_vertices; i++, ptr++ )
111 glNormal3fv( pvn[i].xyz );
112 glVertex3fv( ptr->xyz );
117 for( i=0; i<myData.num_vertices; i++, ptr++ )
119 glVertex3fv( ptr->xyz );
127 for( i=0; i<myData.num_vertices; i++, ptr++ )
129 glColor3fv( pvc[i].rgb );
130 glVertex3fv( ptr->xyz );
135 for( i=0; i<myData.num_vertices; i++, ptr++ )
137 glVertex3fv( ptr->xyz );
142 if( myData.reverse_order ) glFrontFace( GL_CCW );
146 /*----------------------------------------------------------------------*/
148 /* JWR - allow varying the size */
150 static const TEL_POLYGON_DATA *DaTa;
151 static GLUtesselator *tripak = 0;
154 out_bgntmesh( GLenum triangle_type )
156 NCollection_Vector<SEQ_> *dis = DaTa->dsply;
159 #ifdef JWR_DEC_TRIFAN_BUG
160 aSeq.triangle_type = GL_POLYGON;
164 aSeq.triangle_type = triangle_type;
166 glBegin(triangle_type);
170 /*----------------------------------------------------------------------*/
173 out_vert1( void *data )
175 SEQ_ &s = DaTa->dsply->ChangeValue(DaTa->dsply->Length() - 1);
177 s.tmesh_sequence.Append(data);
179 if ( data < (void *)0xffff ) {
182 glVertex3fv( DaTa->vertices[a].xyz );
185 extra_vertex b = (extra_vertex) data;
187 glVertex3fv( b->vert );
192 /*----------------------------------------------------------------------*/
195 out_vert2( void *data )
197 SEQ_ &s = DaTa->dsply->ChangeValue(DaTa->dsply->Length() - 1);
199 s.tmesh_sequence.Append(data);
201 if ( data < (void *)0xffff ) {
204 glColor3fv( DaTa->vcolours[a].rgb );
205 glVertex3fv( DaTa->vertices[a].xyz );
208 extra_vertex b = (extra_vertex) data;
210 glColor3fv( DaTa->vcolours[(b->ind)].rgb );
211 glVertex3fv( b->vert );
215 /*----------------------------------------------------------------------*/
218 out_vert3( void *data )
220 SEQ_ &s = DaTa->dsply->ChangeValue(DaTa->dsply->Length() - 1);
222 s.tmesh_sequence.Append(data);
224 if ( data <= (void *)0xffff ) {
227 glNormal3fv( DaTa->vnormals[a].xyz );
228 glVertex3fv( DaTa->vertices[a].xyz);
231 extra_vertex b = (extra_vertex) data;
233 glNormal3fv( DaTa->vnormals[(b->ind)].xyz );
234 glVertex3fv( b->vert );
238 /*----------------------------------------------------------------------*/
241 mycombine( GLdouble coords[3], int *data, GLfloat w[4], void **dataout)
243 extra_vertex new_vertex = new EXTRA_VERTEX();
245 new_vertex->vert[0] = ( float )coords[0];
246 new_vertex->vert[1] = ( float )coords[1];
247 new_vertex->vert[2] = ( float )coords[2];
248 new_vertex->ind = *data;
249 *dataout = new_vertex;
252 /*----------------------------------------------------------------------*/
260 /*----------------------------------------------------------------------*/
263 out_error( GLenum error )
265 printf( "POLYGON : %s\n", (char *) gluErrorString(error) );
268 /*----------------------------------------------------------------------*/
271 bgntriangulate(const TEL_POLYGON_DATA *d, void ( APIENTRY * out_ver)() )
275 tripak = gluNewTess();
277 #if defined(linux) && !defined(NOGLUfuncptr)
278 gluTessCallback( tripak, GLU_TESS_BEGIN, (_GLUfuncptr)(out_bgntmesh) );
279 gluTessCallback( tripak, GLU_TESS_VERTEX, out_ver );
280 gluTessCallback( tripak, GLU_TESS_END, out_endtmesh );
281 gluTessCallback( tripak, GLU_TESS_ERROR, (_GLUfuncptr)(out_error) );
282 gluTessCallback( tripak, GLU_TESS_COMBINE, (_GLUfuncptr)(mycombine) );
284 gluTessCallback( tripak, GLU_TESS_BEGIN, (void (APIENTRY*)())out_bgntmesh );
285 gluTessCallback( tripak, GLU_TESS_VERTEX, (void (APIENTRY*)())out_ver );
286 gluTessCallback( tripak, GLU_TESS_END, (void (APIENTRY*)())out_endtmesh );
287 gluTessCallback( tripak, GLU_TESS_ERROR, (void (APIENTRY*)())out_error );
288 gluTessCallback( tripak, GLU_TESS_COMBINE, (void (APIENTRY*)())mycombine );
292 /*----------------------------------------------------------------------*/
298 gluDeleteTess(tripak);
301 /*----------------------------------------------------------------------*/
303 void OpenGl_Polygon::draw_polygon_concav (const Handle(OpenGl_Workspace) &AWorkspace, Tint front_lighting_model) const
312 pfc = myData.fcolour;
313 pvc = myData.vcolours;
314 pvn = myData.vnormals;
316 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
319 ptr = myData.vertices;
323 glColor3fv( pfc->rgb );
324 if ( front_lighting_model )
325 glNormal3fv( myData.fnormal.xyz );
327 if( myData.reverse_order ) glFrontFace( GL_CW );
331 if( front_lighting_model )
335 bgntriangulate(&myData, (void (APIENTRY*)())out_vert3);
339 bgntriangulate(&myData, (void (APIENTRY*)())out_vert1);
346 bgntriangulate(&myData, (void (APIENTRY*)())out_vert2);
350 bgntriangulate(&myData, (void (APIENTRY*)())out_vert1);
353 gluTessBeginPolygon( tripak, NULL );
354 gluTessBeginContour( tripak);
356 for( i=0; i<myData.num_vertices; i++, ptr++ )
358 xyz[0] = ptr->xyz[0];
359 xyz[1] = ptr->xyz[1];
360 xyz[2] = ptr->xyz[2];
362 gluTessVertex( tripak, xyz,(void * ) i );
365 double v[ 3 ] = {ptr -> xyz[ 0 ], ptr -> xyz[ 1 ], ptr -> xyz[ 2 ]};
366 gluTessVertex ( tripak, v, ( void* )i );
370 gluTessEndContour( tripak );
371 gluTessEndPolygon( tripak );
376 if( front_lighting_model )
378 draw_tmesh( pvn? 3 : 1 );
382 draw_tmesh( pvc? 2 : 1 );
386 if( myData.reverse_order ) glFrontFace( GL_CCW );
389 /*----------------------------------------------------------------------*/
391 void OpenGl_Polygon::draw_edges (const TEL_COLOUR* theEdgeColor,
392 const Aspect_InteriorStyle theInteriorStyle,
393 const Handle(OpenGl_Workspace)& theWorkspace) const
395 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True);
397 if (theInteriorStyle != Aspect_IS_HIDDENLINE
398 && anAspectFace->Edge == TOff)
403 glDisable (GL_LIGHTING);
404 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
407 const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->SetAspectLine (anAspectFace->AspectEdge());
408 theWorkspace->AspectLine (Standard_True);
410 glColor3fv (theEdgeColor->rgb);
412 glBegin (GL_LINE_LOOP);
413 tel_point ptr = myData.vertices;
414 for (Tint i = 0; i < myData.num_vertices; i++, ptr++)
416 glVertex3fv (ptr->xyz);
420 // Restore line context
421 theWorkspace->SetAspectLine (aPrevAspectLine);
423 theWorkspace->EnableTexture (aPrevTexture);
426 /*----------------------------------------------------------------------*/
428 void OpenGl_Polygon::draw_tmesh ( Tint v ) const
434 NCollection_Vector<SEQ_> *dis = myData.dsply;
435 for( i = 0; i < dis->Length(); i++ )
437 s = &(dis->ChangeValue(i));
439 glBegin(s->triangle_type);
444 for( j = 0, k = 0; j < s->tmesh_sequence.Length(); j++ )
446 if ( s->tmesh_sequence(j) < (void *)0xffff )
447 glVertex3fv( myData.vertices[ (long)s->tmesh_sequence.Value(j) ].xyz );
449 b = (extra_vertex) s->tmesh_sequence(j);
450 glVertex3fv( b->vert );
458 for( j = 0, k = 0; j < s->tmesh_sequence.Length(); j++ )
460 if ( s->tmesh_sequence(j) < (void *)0xffff ) {
461 glColor3fv( myData.vcolours[ (long) s->tmesh_sequence(j) ].rgb );
462 glVertex3fv( myData.vertices[ (long) s->tmesh_sequence(j) ].xyz );
464 b = (extra_vertex) s->tmesh_sequence(j);
465 glColor3fv( myData.vcolours[(b->ind)].rgb);
466 glVertex3fv( b->vert );
473 for( j = 0, k = 0; j < s->tmesh_sequence.Length(); j++ )
475 if ( s->tmesh_sequence(j) < (void *)0xffff ) {
476 glNormal3fv( myData.vnormals[ (long) s->tmesh_sequence(j) ].xyz);
477 glVertex3fv( myData.vertices[ (long) s->tmesh_sequence(j) ].xyz);
479 b = (extra_vertex) s->tmesh_sequence(j);
480 glNormal3fv( myData.vnormals[(b->ind)].xyz);
481 glVertex3fv( b->vert );
491 /*----------------------------------------------------------------------*/
493 OpenGl_Polygon::OpenGl_Polygon (const Graphic3d_Array1OfVertex& AListVertex,
494 const Graphic3d_TypeOfPolygon AType)
496 const Standard_Integer nv = AListVertex.Length();
498 myData.num_vertices = nv;
500 myData.vertices = new TEL_POINT[nv];
501 memcpy( myData.vertices, &AListVertex(AListVertex.Lower()), nv*sizeof(TEL_POINT) );
503 myData.vertex_flag = TEL_VT_NONE;
504 myData.vnormals = NULL;
506 myData.vcolours = NULL;
508 myData.vtexturecoord = NULL;
510 myData.reverse_order = 0;
512 myData.facet_flag = TEL_FA_NONE;
513 TelGetPolygonNormal( myData.vertices, NULL, nv, myData.fnormal.xyz );
515 myData.fcolour = NULL;
517 #if defined(__sgi) || defined(IRIX)
518 // Pb with tesselator on sgi
519 myData.shape_flag = TEL_SHAPE_CONVEX;
523 case Graphic3d_TOP_UNKNOWN :
524 myData.shape_flag = TEL_SHAPE_UNKNOWN;
526 case Graphic3d_TOP_COMPLEX :
527 myData.shape_flag = TEL_SHAPE_COMPLEX;
529 case Graphic3d_TOP_CONCAVE :
530 myData.shape_flag = TEL_SHAPE_CONCAVE;
532 //case Graphic3d_TOP_CONVEX :
534 myData.shape_flag = TEL_SHAPE_CONVEX;
539 myData.dsply = new NCollection_Vector<SEQ_>();
542 /*----------------------------------------------------------------------*/
544 OpenGl_Polygon::~OpenGl_Polygon ()
547 delete myData.fcolour;
548 if( myData.vertices )
549 delete[] myData.vertices;
550 if( myData.vcolours )
551 delete[] myData.vcolours;
552 if( myData.vnormals )
553 delete[] myData.vnormals;
554 if ( myData.vtexturecoord )
555 delete myData.vtexturecoord;
561 for( i = 0; i < myData.dsply->Length(); i++ )
563 for ( j = 0; j < myData.dsply->Value(i).tmesh_sequence.Length() ; j++ )
565 if ( myData.dsply->Value(i).tmesh_sequence(j) >= (void *)0xffff )
566 delete myData.dsply->Value(i).tmesh_sequence(j);
574 /*----------------------------------------------------------------------*/
576 void OpenGl_Polygon::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
578 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
580 Tint front_lighting_model = aspect_face->IntFront.color_mask;
581 const Aspect_InteriorStyle interior_style = aspect_face->InteriorStyle;
582 const TEL_COLOUR *interior_colour = &aspect_face->IntFront.matcol;
583 const TEL_COLOUR *edge_colour = &aspect_face->AspectEdge()->Color();
585 // Use highlight colous
586 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
588 edge_colour = interior_colour = AWorkspace->HighlightColor;
589 front_lighting_model = 0;
592 if( interior_style != Aspect_IS_EMPTY && AWorkspace->DegenerateModel < 2 )
594 if ( front_lighting_model )
595 glEnable(GL_LIGHTING);
597 glDisable(GL_LIGHTING);
599 glColor3fv( interior_colour->rgb );
601 if( myData.shape_flag != TEL_SHAPE_CONVEX )
602 draw_polygon_concav( AWorkspace, front_lighting_model );
604 draw_polygon( AWorkspace, front_lighting_model );
607 /* OCC11904 -- Temporarily disable environment mapping */
608 glPushAttrib(GL_ENABLE_BIT);
609 glDisable(GL_TEXTURE_1D);
610 glDisable(GL_TEXTURE_2D);
612 switch ( AWorkspace->DegenerateModel )
615 draw_edges ( edge_colour, interior_style, AWorkspace );
617 case 3: /* marker degeneration */
621 glPopAttrib(); /* skt: GL_ENABLE_BIT*/
624 void OpenGl_Polygon::Release (const Handle(OpenGl_Context)& theContext)