0023546: Test report failure in Debug mode due to debug messages
[occt.git] / src / OpenGl / OpenGl_Polygon.cxx
CommitLineData
b311480e 1// Created on: 2011-07-13
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
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.
9//
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.
12//
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.
19
2166f0fa 20
5f8b738e 21#include <OpenGl_GlCore11.hxx>
2166f0fa
SK
22
23#include <OpenGl_Polygon.hxx>
24
2166f0fa
SK
25#include <OpenGl_telem_util.hxx>
26#include <OpenGl_TextureBox.hxx>
2166f0fa
SK
27
28#include <OpenGl_AspectFace.hxx>
29#include <OpenGl_Structure.hxx>
30
31#include <GL/glu.h>
32
33#if (defined(_WIN32) || defined(__WIN32__))
34 #define STATIC
35#else
36 #define STATIC static
37#endif
38
39struct EXTRA_VERTEX
40{
41 GLfloat vert[3];
42 int ind;
1c35b92f 43 DEFINE_STANDARD_ALLOC
2166f0fa
SK
44};
45typedef EXTRA_VERTEX* extra_vertex;
46
47struct SEQ_
48{
9d35f668 49 NCollection_Vector<void *> tmesh_sequence;
2166f0fa 50 GLenum triangle_type; /* FSXXX OPTI */
1c35b92f 51 DEFINE_STANDARD_ALLOC
2166f0fa
SK
52};
53
2166f0fa
SK
54static void bgntriangulate( const TEL_POLYGON_DATA *, void (APIENTRY*)() );
55static void endtriangulate(void);
56
57#ifndef GLU_VERSION_1_2
58 #define GLUtesselator GLUtriangulatorObj
59 void gluTessBeginContour();
60 void gluTessBeginPolygon();
61 void gluTessEndPolygon();
62 void gluTessEndContour();
63 #define GLU_TESS_BEGIN 100100
64 #define GLU_TESS_VERTEX 100101
65 #define GLU_TESS_END 100102
66 #define GLU_TESS_ERROR 100103
67 #define GLU_TESS_COMBINE 100105
68#endif
69
70/*----------------------------------------------------------------------*/
71
72void OpenGl_Polygon::draw_polygon (const Handle(OpenGl_Workspace) &AWorkspace, Tint front_lighting_model) const
73{
74 Tint i;
75
76 tel_point ptr;
77 tel_point pvn;
78 tel_colour pfc, pvc;
79 tel_texture_coord pvt;
80
81 pfc = myData.fcolour;
82 pvc = myData.vcolours;
83 pvn = myData.vnormals;
84 pvt = myData.vtexturecoord;
85
86 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
87 pvc = pfc = NULL;
88
89 ptr = myData.vertices;
90 if ( pfc )
91 glColor3fv( pfc->rgb );
92 if ( front_lighting_model )
93 glNormal3fv( myData.fnormal.xyz );
94
95 if( myData.reverse_order ) glFrontFace( GL_CW );
96
97 if (myData.num_vertices == 3) glBegin(GL_TRIANGLES);
98 else if(myData.num_vertices == 4) glBegin(GL_QUADS);
99 else glBegin(GL_POLYGON);
100 if( front_lighting_model )
101 {
102 if( pvn )
103 {
104 if (pvt && (AWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
105 for( i=0; i<myData.num_vertices; i++, ptr++ )
106 {
107 glNormal3fv( pvn[i].xyz );
108 glTexCoord2fv( pvt[i].xy );
109 glVertex3fv( ptr->xyz );
110 }
111 else
112 for( i=0; i<myData.num_vertices; i++, ptr++ )
113 {
114 glNormal3fv( pvn[i].xyz );
115 glVertex3fv( ptr->xyz );
116 }
117 }
118 else
119 {
120 for( i=0; i<myData.num_vertices; i++, ptr++ )
121 {
122 glVertex3fv( ptr->xyz );
123 }
124 }
125 }
126 else
127 {
128 if( pvc )
129 {
130 for( i=0; i<myData.num_vertices; i++, ptr++ )
131 {
132 glColor3fv( pvc[i].rgb );
133 glVertex3fv( ptr->xyz );
134 }
135 }
136 else
137 {
138 for( i=0; i<myData.num_vertices; i++, ptr++ )
139 {
140 glVertex3fv( ptr->xyz );
141 }
142 }
143 }
144 glEnd();
145 if( myData.reverse_order ) glFrontFace( GL_CCW );
146
147}
148
149/*----------------------------------------------------------------------*/
150
151/* JWR - allow varying the size */
152
2166f0fa
SK
153static const TEL_POLYGON_DATA *DaTa;
154static GLUtesselator *tripak = 0;
155
156STATIC void APIENTRY
157out_bgntmesh( GLenum triangle_type )
158{
9d35f668 159 NCollection_Vector<SEQ_> *dis = DaTa->dsply;
2166f0fa 160
9d35f668 161 SEQ_ aSeq;
2166f0fa 162#ifdef JWR_DEC_TRIFAN_BUG
9d35f668 163 aSeq.triangle_type = GL_POLYGON;
164 dis->Append(aSeq);
2166f0fa
SK
165 glBegin(GL_POLYGON);
166#else
9d35f668 167 aSeq.triangle_type = triangle_type;
168 dis->Append(aSeq);
2166f0fa
SK
169 glBegin(triangle_type);
170#endif
171}
172
173/*----------------------------------------------------------------------*/
174
175STATIC void APIENTRY
176out_vert1( void *data )
177{
9d35f668 178 SEQ_ &s = DaTa->dsply->ChangeValue(DaTa->dsply->Length() - 1);
2166f0fa 179
9d35f668 180 s.tmesh_sequence.Append(data);
2166f0fa
SK
181
182 if ( data < (void *)0xffff ) {
183 long a = (long)data;
184
185 glVertex3fv( DaTa->vertices[a].xyz );
186 }
187 else {
188 extra_vertex b = (extra_vertex) data;
189
190 glVertex3fv( b->vert );
191 }
192
193}
194
195/*----------------------------------------------------------------------*/
196
197STATIC void APIENTRY
198out_vert2( void *data )
199{
9d35f668 200 SEQ_ &s = DaTa->dsply->ChangeValue(DaTa->dsply->Length() - 1);
2166f0fa 201
9d35f668 202 s.tmesh_sequence.Append(data);
2166f0fa
SK
203
204 if ( data < (void *)0xffff ) {
205 long a = (long)data;
206
207 glColor3fv( DaTa->vcolours[a].rgb );
208 glVertex3fv( DaTa->vertices[a].xyz );
209 }
210 else {
211 extra_vertex b = (extra_vertex) data;
212
213 glColor3fv( DaTa->vcolours[(b->ind)].rgb );
214 glVertex3fv( b->vert );
215 }
216}
217
218/*----------------------------------------------------------------------*/
219
220STATIC void APIENTRY
221out_vert3( void *data )
222{
9d35f668 223 SEQ_ &s = DaTa->dsply->ChangeValue(DaTa->dsply->Length() - 1);
2166f0fa 224
9d35f668 225 s.tmesh_sequence.Append(data);
2166f0fa
SK
226
227 if ( data <= (void *)0xffff ) {
228 long a = (long)data;
229
230 glNormal3fv( DaTa->vnormals[a].xyz );
231 glVertex3fv( DaTa->vertices[a].xyz);
232 }
233 else {
234 extra_vertex b = (extra_vertex) data;
235
236 glNormal3fv( DaTa->vnormals[(b->ind)].xyz );
237 glVertex3fv( b->vert );
238 }
239}
240
241/*----------------------------------------------------------------------*/
242
243STATIC void APIENTRY
244mycombine( GLdouble coords[3], int *data, GLfloat w[4], void **dataout)
245{
9d35f668 246 extra_vertex new_vertex = new EXTRA_VERTEX();
2166f0fa
SK
247
248 new_vertex->vert[0] = ( float )coords[0];
249 new_vertex->vert[1] = ( float )coords[1];
250 new_vertex->vert[2] = ( float )coords[2];
251 new_vertex->ind = *data;
252 *dataout = new_vertex;
253}
254
255/*----------------------------------------------------------------------*/
256
257STATIC void APIENTRY
258out_endtmesh( void )
259{
260 glEnd();
261}
262
263/*----------------------------------------------------------------------*/
264
265STATIC void APIENTRY
266out_error( GLenum error )
267{
268 printf( "POLYGON : %s\n", (char *) gluErrorString(error) );
269}
270
271/*----------------------------------------------------------------------*/
272
273static void
274bgntriangulate(const TEL_POLYGON_DATA *d, void ( APIENTRY * out_ver)() )
275{
276 DaTa = d;
277
278 tripak = gluNewTess();
279
280#if defined(linux) && !defined(NOGLUfuncptr)
281 gluTessCallback( tripak, GLU_TESS_BEGIN, (_GLUfuncptr)(out_bgntmesh) );
282 gluTessCallback( tripak, GLU_TESS_VERTEX, out_ver );
283 gluTessCallback( tripak, GLU_TESS_END, out_endtmesh );
284 gluTessCallback( tripak, GLU_TESS_ERROR, (_GLUfuncptr)(out_error) );
285 gluTessCallback( tripak, GLU_TESS_COMBINE, (_GLUfuncptr)(mycombine) );
286#else
287 gluTessCallback( tripak, GLU_TESS_BEGIN, (void (APIENTRY*)())out_bgntmesh );
288 gluTessCallback( tripak, GLU_TESS_VERTEX, (void (APIENTRY*)())out_ver );
289 gluTessCallback( tripak, GLU_TESS_END, (void (APIENTRY*)())out_endtmesh );
290 gluTessCallback( tripak, GLU_TESS_ERROR, (void (APIENTRY*)())out_error );
291 gluTessCallback( tripak, GLU_TESS_COMBINE, (void (APIENTRY*)())mycombine );
292#endif
293}
294
295/*----------------------------------------------------------------------*/
296
297static void
298endtriangulate()
299{
300 DaTa = 0;
301 gluDeleteTess(tripak);
302}
303
304/*----------------------------------------------------------------------*/
305
306void OpenGl_Polygon::draw_polygon_concav (const Handle(OpenGl_Workspace) &AWorkspace, Tint front_lighting_model) const
307{
308 long i;
309
310 tel_point pvn;
311 tel_point ptr;
312 tel_colour pfc, pvc;
313 GLdouble xyz[3];
314
315 pfc = myData.fcolour;
316 pvc = myData.vcolours;
317 pvn = myData.vnormals;
318
319 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
320 pvc = pfc = NULL;
321
322 ptr = myData.vertices;
323 DaTa = &myData;
324
325 if ( pfc )
326 glColor3fv( pfc->rgb );
327 if ( front_lighting_model )
328 glNormal3fv( myData.fnormal.xyz );
329
330 if( myData.reverse_order ) glFrontFace( GL_CW );
331
332 if( !myData.dsply )
333 {
334 if( front_lighting_model )
335 {
336 if( pvn )
337 {
338 bgntriangulate(&myData, (void (APIENTRY*)())out_vert3);
339 }
340 else
341 {
342 bgntriangulate(&myData, (void (APIENTRY*)())out_vert1);
343 }
344 }
345 else
346 {
347 if( pvc )
348 {
349 bgntriangulate(&myData, (void (APIENTRY*)())out_vert2);
350 }
351 else
352 {
353 bgntriangulate(&myData, (void (APIENTRY*)())out_vert1);
354 }
355 }
356 gluTessBeginPolygon( tripak, NULL );
357 gluTessBeginContour( tripak);
358
359 for( i=0; i<myData.num_vertices; i++, ptr++ )
360 {
361 xyz[0] = ptr->xyz[0];
362 xyz[1] = ptr->xyz[1];
363 xyz[2] = ptr->xyz[2];
364#ifndef WNT
365 gluTessVertex( tripak, xyz,(void * ) i );
366#else
367 {
368 double v[ 3 ] = {ptr -> xyz[ 0 ], ptr -> xyz[ 1 ], ptr -> xyz[ 2 ]};
369 gluTessVertex ( tripak, v, ( void* )i );
370 }
371#endif /* WNT */
372 }
373 gluTessEndContour( tripak );
374 gluTessEndPolygon( tripak );
375 endtriangulate();
376 }
377 else
378 {
379 if( front_lighting_model )
380 {
381 draw_tmesh( pvn? 3 : 1 );
382 }
383 else
384 {
385 draw_tmesh( pvc? 2 : 1 );
386 }
387 }
388
389 if( myData.reverse_order ) glFrontFace( GL_CCW );
390}
391
392/*----------------------------------------------------------------------*/
393
394void OpenGl_Polygon::draw_edges (const TEL_COLOUR *edge_colour, const Aspect_InteriorStyle interior_style, const Handle(OpenGl_Workspace) &AWorkspace) const
395{
396 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
397
398 if ( interior_style != Aspect_IS_HIDDENLINE && aspect_face->Context().Edge == TOff )
399 return;
400
401 glDisable(GL_LIGHTING);
402 const GLboolean texture_on = IsTextureEnabled();
403 if (texture_on) DisableTexture();
404
405 // Setup line aspect
406 const OpenGl_AspectLine *aspect_line_old = AWorkspace->SetAspectLine( aspect_face->AspectEdge() );
407 AWorkspace->AspectLine( Standard_True );
408
409 Tint i;
410 tel_point ptr = myData.vertices;
411
412 glColor3fv( edge_colour->rgb );
413
414 glBegin(GL_LINE_LOOP);
415 for( i=0; i<myData.num_vertices; i++, ptr++ )
416 {
417 glVertex3fv( ptr->xyz );
418 }
419 glEnd();
420
421 // Restore line context
422 AWorkspace->SetAspectLine( aspect_line_old );
423
424 if (texture_on) EnableTexture();
425}
426
427/*----------------------------------------------------------------------*/
428
429void OpenGl_Polygon::draw_tmesh ( Tint v ) const
430{
431 Tint i, j, k;
432 SEQ_ *s;
433 extra_vertex b;
434
9d35f668 435 NCollection_Vector<SEQ_> *dis = myData.dsply;
436 for( i = 0; i < dis->Length(); i++ )
2166f0fa 437 {
9d35f668 438 s = &(dis->ChangeValue(i));
2166f0fa
SK
439
440 glBegin(s->triangle_type);
441 switch( v )
442 {
443 case 1:
444 {
9d35f668 445 for( j = 0, k = 0; j < s->tmesh_sequence.Length(); j++ )
2166f0fa 446 {
9d35f668 447 if ( s->tmesh_sequence(j) < (void *)0xffff )
448 glVertex3fv( myData.vertices[ (long)s->tmesh_sequence.Value(j) ].xyz );
2166f0fa 449 else {
9d35f668 450 b = (extra_vertex) s->tmesh_sequence(j);
2166f0fa
SK
451 glVertex3fv( b->vert );
452 }
453
454 }
455 break;
456 }
457 case 2:
458 {
9d35f668 459 for( j = 0, k = 0; j < s->tmesh_sequence.Length(); j++ )
2166f0fa 460 {
9d35f668 461 if ( s->tmesh_sequence(j) < (void *)0xffff ) {
462 glColor3fv( myData.vcolours[ (long) s->tmesh_sequence(j) ].rgb );
463 glVertex3fv( myData.vertices[ (long) s->tmesh_sequence(j) ].xyz );
2166f0fa 464 } else {
9d35f668 465 b = (extra_vertex) s->tmesh_sequence(j);
2166f0fa
SK
466 glColor3fv( myData.vcolours[(b->ind)].rgb);
467 glVertex3fv( b->vert );
468 }
469 }
470 break;
471 }
472 case 3:
473 {
9d35f668 474 for( j = 0, k = 0; j < s->tmesh_sequence.Length(); j++ )
2166f0fa 475 {
9d35f668 476 if ( s->tmesh_sequence(j) < (void *)0xffff ) {
477 glNormal3fv( myData.vnormals[ (long) s->tmesh_sequence(j) ].xyz);
478 glVertex3fv( myData.vertices[ (long) s->tmesh_sequence(j) ].xyz);
2166f0fa 479 } else {
9d35f668 480 b = (extra_vertex) s->tmesh_sequence(j);
2166f0fa
SK
481 glNormal3fv( myData.vnormals[(b->ind)].xyz);
482 glVertex3fv( b->vert );
483 }
484 }
485 break;
486 }
487 }
488 glEnd();
489 }
490}
491
492/*----------------------------------------------------------------------*/
493
494OpenGl_Polygon::OpenGl_Polygon (const Graphic3d_Array1OfVertex& AListVertex,
495 const Graphic3d_TypeOfPolygon AType)
496{
497 const Standard_Integer nv = AListVertex.Length();
498
499 myData.num_vertices = nv;
500
501 myData.vertices = new TEL_POINT[nv];
502 memcpy( myData.vertices, &AListVertex(AListVertex.Lower()), nv*sizeof(TEL_POINT) );
503
504 myData.vertex_flag = TEL_VT_NONE;
505 myData.vnormals = NULL;
506
507 myData.vcolours = NULL;
508
509 myData.vtexturecoord = NULL;
510
511 myData.reverse_order = 0;
512
513 myData.facet_flag = TEL_FA_NONE;
514 TelGetPolygonNormal( myData.vertices, NULL, nv, myData.fnormal.xyz );
515
516 myData.fcolour = NULL;
517
518#if defined(__sgi) || defined(IRIX)
519 // Pb with tesselator on sgi
520 myData.shape_flag = TEL_SHAPE_CONVEX;
521#else
522 switch (AType)
523 {
524 case Graphic3d_TOP_UNKNOWN :
525 myData.shape_flag = TEL_SHAPE_UNKNOWN;
526 break;
527 case Graphic3d_TOP_COMPLEX :
528 myData.shape_flag = TEL_SHAPE_COMPLEX;
529 break;
530 case Graphic3d_TOP_CONCAVE :
531 myData.shape_flag = TEL_SHAPE_CONCAVE;
532 break;
533 //case Graphic3d_TOP_CONVEX :
534 default :
535 myData.shape_flag = TEL_SHAPE_CONVEX;
536 break;
537 }
538#endif
539
9d35f668 540 myData.dsply = new NCollection_Vector<SEQ_>();
2166f0fa
SK
541}
542
543/*----------------------------------------------------------------------*/
544
545OpenGl_Polygon::~OpenGl_Polygon ()
546{
547 if( myData.fcolour )
548 delete myData.fcolour;
549 if( myData.vertices )
550 delete[] myData.vertices;
551 if( myData.vcolours )
552 delete[] myData.vcolours;
553 if( myData.vnormals )
554 delete[] myData.vnormals;
555 if ( myData.vtexturecoord )
556 delete myData.vtexturecoord;
557
558 if ( myData.dsply )
559 {
560 Tint i, j;
561
9d35f668 562 for( i = 0; i < myData.dsply->Length(); i++ )
2166f0fa 563 {
9d35f668 564 for ( j = 0; j < myData.dsply->Value(i).tmesh_sequence.Length() ; j++ )
565 {
566 if ( myData.dsply->Value(i).tmesh_sequence(j) >= (void *)0xffff )
567 delete myData.dsply->Value(i).tmesh_sequence(j);
2166f0fa 568 }
2166f0fa 569 }
9d35f668 570
2166f0fa
SK
571 delete myData.dsply;
572 }
573}
574
575/*----------------------------------------------------------------------*/
576
577void OpenGl_Polygon::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
578{
579 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
580
581 Tint front_lighting_model = aspect_face->Context().IntFront.color_mask;
582 const Aspect_InteriorStyle interior_style = aspect_face->Context().InteriorStyle;
583 const TEL_COLOUR *interior_colour = &aspect_face->Context().IntFront.matcol;
584 const TEL_COLOUR *edge_colour = &aspect_face->AspectEdge()->Color();
585
586 // Use highlight colous
587 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
588 {
589 edge_colour = interior_colour = AWorkspace->HighlightColor;
590 front_lighting_model = 0;
591 }
592
593 if( interior_style != Aspect_IS_EMPTY && AWorkspace->DegenerateModel < 2 )
594 {
595 if ( front_lighting_model )
596 glEnable(GL_LIGHTING);
597 else
598 glDisable(GL_LIGHTING);
599
600 glColor3fv( interior_colour->rgb );
601
602 if( myData.shape_flag != TEL_SHAPE_CONVEX )
603 draw_polygon_concav( AWorkspace, front_lighting_model );
604 else
605 draw_polygon( AWorkspace, front_lighting_model );
606 }
607
608 /* OCC11904 -- Temporarily disable environment mapping */
609 glPushAttrib(GL_ENABLE_BIT);
610 glDisable(GL_TEXTURE_1D);
611 glDisable(GL_TEXTURE_2D);
612
613 switch ( AWorkspace->DegenerateModel )
614 {
615 default:
616 draw_edges ( edge_colour, interior_style, AWorkspace );
617 break;
618 case 3: /* marker degeneration */
619 break;
620 }
621
622 glPopAttrib(); /* skt: GL_ENABLE_BIT*/
623}
624
5e27df78 625void OpenGl_Polygon::Release (const Handle(OpenGl_Context)& theContext)
626{
627 //
628}