0023791: Remove obsolete functionality - animation mode and degeneration presentation...
[occt.git] / src / OpenGl / OpenGl_Workspace_5.cxx
1 // Created on: 2011-08-05
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
20
21 #include <OpenGl_GlCore11.hxx>
22
23 #include <OpenGl_Workspace.hxx>
24
25 #include <OpenGl_AspectLine.hxx>
26 #include <OpenGl_AspectFace.hxx>
27 #include <OpenGl_AspectMarker.hxx>
28 #include <OpenGl_AspectText.hxx>
29
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33
34 /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */
35 #ifdef HAVE_GL2PS
36   #include <gl2ps.h>
37   /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
38      Pragma comment for gl2ps.lib is defined only here. */
39   #ifdef _MSC_VER
40   #pragma comment( lib, "gl2ps.lib" )
41   #endif
42 #endif
43
44 #include <Aspect_PolygonOffsetMode.hxx>
45 #include <OpenGl_View.hxx>
46
47 /*----------------------------------------------------------------------*/
48
49 static void TelUpdatePolygonOffsets( const TEL_POFFSET_PARAM *pdata )
50 {
51   if ( ( pdata->mode & Aspect_POM_Fill ) == Aspect_POM_Fill )
52     glEnable ( GL_POLYGON_OFFSET_FILL );
53   else
54     glDisable ( GL_POLYGON_OFFSET_FILL );
55
56   if ( ( pdata->mode & Aspect_POM_Line ) == Aspect_POM_Line )
57     glEnable ( GL_POLYGON_OFFSET_LINE );
58   else
59     glDisable( GL_POLYGON_OFFSET_LINE );
60
61   if ( ( pdata->mode & Aspect_POM_Point ) == Aspect_POM_Point )
62     glEnable ( GL_POLYGON_OFFSET_POINT );
63   else
64     glDisable( GL_POLYGON_OFFSET_POINT );
65
66   glPolygonOffset( pdata->factor, pdata->units );
67 }
68
69 /*----------------------------------------------------------------------*/
70
71 void OpenGl_Workspace::UpdateMaterial( const int flag )
72 {
73   // Case of Hiddenline
74   if (AspectFace_set->InteriorStyle == Aspect_IS_HIDDENLINE)
75   {
76         myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
77     myAspectFaceHl.IntFront.matcol     = BackgroundColor();
78     myAspectFaceHl.IntFront.color_mask = 0;
79     myAspectFaceHl.IntBack.color_mask  = 0;
80
81         AspectFace_set = &myAspectFaceHl;
82     return;
83   }
84
85   const OPENGL_SURF_PROP *prop = NULL;
86   GLenum face = 0;
87   if ( flag == TEL_FRONT_MATERIAL )
88   {
89     prop = &AspectFace_set->IntFront;
90     face = GL_FRONT_AND_BACK;
91   }
92   else
93   {
94     prop = &AspectFace_set->IntBack;
95     face = GL_BACK;
96   }
97
98   const unsigned int rm = prop->color_mask;
99
100   if ( !rm ) return;
101
102   // Handling transparency
103   if ( (NamedStatus & OPENGL_NS_2NDPASSDO) == 0 )
104   {
105     if ( myUseTransparency && prop->trans != 1.0F )
106     {
107       // Render transparent
108       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
109       glEnable (GL_BLEND);
110       glDepthMask (GL_FALSE);
111     }
112     else
113     {
114       // Render opaque
115       if ( (NamedStatus & OPENGL_NS_ANTIALIASING) == 0 )
116       {
117         glBlendFunc (GL_ONE, GL_ZERO);
118         glDisable (GL_BLEND);
119       }
120       glDepthMask (GL_TRUE);
121     }
122   }
123
124   static float  mAmb[4];
125   static float  mDiff[4];
126   static float  mSpec[4];
127   static float  mEmsv[4];
128   static float  mShin;
129
130   static const float defspeccol[4] = { 1.F, 1.F, 1.F, 1.F };
131
132   // Reset material
133   if ( NamedStatus & OPENGL_NS_RESMAT )
134   {
135     // Ambient component
136     if( rm & OPENGL_AMBIENT_MASK )
137     {
138       const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
139
140       mAmb[0] = prop->amb * c[0];
141       mAmb[1] = prop->amb * c[1];
142       mAmb[2] = prop->amb * c[2];
143     }
144     else
145     {
146       mAmb[0] = 0.F;
147       mAmb[1] = 0.F;
148       mAmb[2] = 0.F;
149     }
150     mAmb[3] = 1.F;
151
152     // Diffusion component
153     if( rm & OPENGL_DIFFUSE_MASK )
154     {
155       const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
156
157       mDiff[0] = prop->diff * c[0];
158       mDiff[1] = prop->diff * c[1];
159       mDiff[2] = prop->diff * c[2];
160     }
161     else
162     {
163       mDiff[0] = 0.F;
164       mDiff[1] = 0.F;
165       mDiff[2] = 0.F;
166     }
167     mDiff[3] = 1.F;
168
169     if (NamedStatus & OPENGL_NS_2NDPASSDO)
170     {
171       mDiff[3] = prop->env_reflexion;
172     }
173     else
174     {
175       if (myUseTransparency) mDiff[3] = prop->trans;
176       // If the material reflects the environment scene, the second pass is needed
177       if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
178     }
179
180     // Specular component
181     if( rm & OPENGL_SPECULAR_MASK )
182     {
183       const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
184
185       mSpec[0] = prop->spec * c[0];
186       mSpec[1] = prop->spec * c[1];
187       mSpec[2] = prop->spec * c[2];
188     }
189     else {
190       mSpec[0] = 0.F;
191       mSpec[1] = 0.F;
192       mSpec[2] = 0.F;
193     }
194     mSpec[3] = 1.F;
195
196     // Emissive component
197     if( rm & OPENGL_EMISSIVE_MASK )
198     {
199       const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
200
201       mEmsv[0] = prop->emsv * c[0];
202       mEmsv[1] = prop->emsv * c[1];
203       mEmsv[2] = prop->emsv * c[2];
204     }
205     else {
206       mEmsv[0] = 0.F;
207       mEmsv[1] = 0.F;
208       mEmsv[2] = 0.F;
209     }
210     mEmsv[3] = 1.F;
211
212     /* Coeficient de brillance */
213     mShin = prop->shine;
214
215     glMaterialfv(face, GL_AMBIENT, mAmb );
216     glMaterialfv(face, GL_DIFFUSE, mDiff );
217     glMaterialfv(face, GL_SPECULAR, mSpec);
218     glMaterialfv(face, GL_EMISSION, mEmsv);
219     glMaterialf(face, GL_SHININESS, mShin);
220
221     NamedStatus &= ~OPENGL_NS_RESMAT;
222   }
223
224   // Set Material Optimize
225   else
226   {
227     // Ambient component
228     if( rm & OPENGL_AMBIENT_MASK )
229     {
230       const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
231
232       if (mAmb[0] != prop->amb * c[0] ||
233           mAmb[1] != prop->amb * c[1] ||
234           mAmb[2] != prop->amb * c[2] )
235       {
236         mAmb[0] = prop->amb * c[0];
237         mAmb[1] = prop->amb * c[1];
238         mAmb[2] = prop->amb * c[2];
239         mAmb[3] = 1.F;
240
241         glMaterialfv(face, GL_AMBIENT, mAmb);
242       }
243     }
244     else
245     {
246       if ( mAmb[0] != 0.F || mAmb[1] != 0.F || mAmb[2] != 0.F )
247       {
248         mAmb[0] = 0.F;
249         mAmb[1] = 0.F;
250         mAmb[2] = 0.F;
251         mAmb[3] = 1.F;
252
253         glMaterialfv(face, GL_AMBIENT, mAmb);
254       }
255     }
256
257     // Diffusion component
258     if( rm & OPENGL_DIFFUSE_MASK )
259     {
260       const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
261
262       if (mDiff[0] != prop->diff * c[0] ||
263           mDiff[1] != prop->diff * c[1] ||
264           mDiff[2] != prop->diff * c[2] ||
265           mDiff[3] != ((NamedStatus & OPENGL_NS_2NDPASSDO)? prop->env_reflexion : (myUseTransparency? prop->trans : 1.0F)))
266       {
267         mDiff[0] = prop->diff * c[0];
268         mDiff[1] = prop->diff * c[1];
269         mDiff[2] = prop->diff * c[2];
270         mDiff[3] = 1.F;
271
272         if (NamedStatus & OPENGL_NS_2NDPASSDO)
273         {
274           mDiff[3] = prop->env_reflexion;
275         }
276         else
277         {
278           if (myUseTransparency) mDiff[3] = prop->trans;
279           // If the material reflects the environment scene, the second pass is needed
280           if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
281         }
282
283         glMaterialfv(face, GL_DIFFUSE, mDiff );
284       }
285     }
286     else
287     {
288       Tfloat newDiff3 = 1.F;
289
290       if (NamedStatus & OPENGL_NS_2NDPASSDO)
291       {
292         newDiff3 = prop->env_reflexion;
293       }
294       else
295       {
296         if (myUseTransparency) newDiff3 = prop->trans;
297         // If the material reflects the environment scene, the second pass is needed
298         if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
299       }
300
301       /* OCC19915: Even if diffuse reflectance is disabled,
302       still trying to update the current transparency if it
303       differs from the previous value  */
304       if ( mDiff[0] != 0.F || mDiff[1] != 0.F || mDiff[2] != 0.F || fabs(mDiff[3] - newDiff3) > 0.01F )
305       {
306         mDiff[0] = 0.F;
307         mDiff[1] = 0.F;
308         mDiff[2] = 0.F;
309         mDiff[3] = newDiff3;
310
311         glMaterialfv(face, GL_DIFFUSE, mDiff);
312       }
313     }
314
315     // Specular component
316     if( rm & OPENGL_SPECULAR_MASK )
317     {
318       const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
319
320       if (mSpec[0] != prop->spec * c[0] ||
321           mSpec[1] != prop->spec * c[1] ||
322           mSpec[2] != prop->spec * c[2])
323       {
324         mSpec[0] = prop->spec * c[0];
325         mSpec[1] = prop->spec * c[1];
326         mSpec[2] = prop->spec * c[2];
327         mSpec[3] = 1.F;
328
329         glMaterialfv(face, GL_SPECULAR, mSpec);
330       }
331     }
332     else
333     {
334       if ( mSpec[0] != 0.F || mSpec[1] != 0.F || mSpec[2] != 0.F )
335       {
336         mSpec[0] = 0.F;
337         mSpec[1] = 0.F;
338         mSpec[2] = 0.F;
339         mSpec[3] = 1.F;
340
341         glMaterialfv(face, GL_SPECULAR, mSpec);
342       }
343     }
344
345     // Emissive component
346     if( rm & OPENGL_EMISSIVE_MASK )
347     {
348       const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
349
350       if (mEmsv[0] != prop->emsv * c[0] ||
351           mEmsv[1] != prop->emsv * c[1] ||
352           mEmsv[2] != prop->emsv * c[2])
353       {
354         mEmsv[0] = prop->emsv * c[0];
355         mEmsv[1] = prop->emsv * c[1];
356         mEmsv[2] = prop->emsv * c[2];
357         mEmsv[3] = 1.F;
358
359         glMaterialfv(face, GL_EMISSION, mEmsv);
360       }
361     }
362     else
363     {
364       if ( mEmsv[0] != 0.F || mEmsv[1] != 0.F || mEmsv[2] != 0.F )
365       {
366         mEmsv[0] = 0.F;
367         mEmsv[1] = 0.F;
368         mEmsv[2] = 0.F;
369         mEmsv[3] = 1.F;
370
371         glMaterialfv(face, GL_EMISSION, mEmsv);
372       }
373     }
374
375     // Shining coefficient
376     if( mShin != prop->shine )
377     {
378       mShin = prop->shine;
379       glMaterialf(face, GL_SHININESS, mShin);
380     }
381   }
382 }
383
384 /*----------------------------------------------------------------------*/
385
386 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
387 {
388   const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
389   AspectLine_set = AnAspect;
390   return AspectLine_old;
391 }
392
393 /*----------------------------------------------------------------------*/
394
395 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
396 {
397   const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
398   AspectFace_set = AnAspect;
399   return AspectFace_old;
400 }
401
402 /*----------------------------------------------------------------------*/
403
404 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
405 {
406   const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
407   AspectMarker_set = AnAspect;
408   return AspectMarker_old;
409 }
410
411 /*----------------------------------------------------------------------*/
412
413 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
414 {
415   const OpenGl_AspectText *AspectText_old = AspectText_set;
416   AspectText_set = AnAspect;
417   return AspectText_old;
418 }
419
420 /*----------------------------------------------------------------------*/
421
422 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix(const OpenGl_Matrix *AMatrix)
423 {
424   const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
425   ViewMatrix_applied = AMatrix;
426
427   OpenGl_Matrix lmat;
428   OpenGl_Transposemat3( &lmat, StructureMatrix_applied );
429
430   glMatrixMode (GL_MODELVIEW);
431   OpenGl_Matrix rmat;
432   OpenGl_Multiplymat3 (&rmat, &lmat, ViewMatrix_applied);
433   glLoadMatrixf ((const GLfloat* )rmat.mat);
434
435   return ViewMatrix_old;
436 }
437
438 /*----------------------------------------------------------------------*/
439
440 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix(const OpenGl_Matrix *AMatrix)
441 {
442   const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
443   StructureMatrix_applied = AMatrix;
444
445   OpenGl_Matrix lmat;
446   OpenGl_Transposemat3( &lmat, AMatrix );
447
448   glMatrixMode (GL_MODELVIEW);
449   OpenGl_Matrix rmat;
450   OpenGl_Multiplymat3 (&rmat, &lmat, ViewMatrix_applied);
451   glLoadMatrixf ((const GLfloat* )rmat.mat);
452
453   return StructureMatrix_old;
454 }
455
456 /*----------------------------------------------------------------------*/
457
458 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
459 {
460   if ( WithApply && (AspectLine_set != AspectLine_applied) )
461   {
462     glColor3fv(AspectLine_set->Color().rgb);
463
464     if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
465     {
466       myDisplay->SetTypeOfLine(AspectLine_set->Type());
467     }
468
469     if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
470     {
471       glLineWidth( (GLfloat)AspectLine_set->Width() );
472 #ifdef HAVE_GL2PS
473       gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
474 #endif
475     }
476
477     AspectLine_applied = AspectLine_set;
478   }
479   return AspectLine_set;
480 }
481
482 /*----------------------------------------------------------------------*/
483
484 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
485 {
486   if (!theToApply || (AspectFace_set == AspectFace_applied))
487   {
488     return AspectFace_set;
489   }
490
491   const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle;
492   if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle != anIntstyle)
493   {
494     switch (anIntstyle)
495     {
496       case Aspect_IS_EMPTY:
497       case Aspect_IS_HOLLOW:
498       {
499         glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
500         break;
501       }
502       case Aspect_IS_HATCH:
503       {
504         glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
505                 myDisplay->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch : TEL_HS_SOLID);
506         break;
507       }
508       case Aspect_IS_SOLID:
509       case Aspect_IS_HIDDENLINE:
510       {
511         glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
512         glDisable (GL_POLYGON_STIPPLE);
513         break;
514       }
515       case 5: //szvgl - no corresponding enumeration item Aspect_IS_POINT
516       {
517         glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
518         break;
519       }
520     }
521   }
522
523   if (anIntstyle == Aspect_IS_HATCH)
524   {
525     const Tint hatchstyle = AspectFace_set->Hatch;
526     if (AspectFace_applied == NULL || AspectFace_applied->Hatch != hatchstyle)
527     {
528       myDisplay->SetTypeOfHatch(hatchstyle);
529     }
530   }
531
532   if (!ActiveView()->Backfacing())
533   {
534     const Tint aCullingMode = AspectFace_set->CullingMode;
535     if (AspectFace_applied == NULL || AspectFace_applied->CullingMode != aCullingMode)
536     {
537       switch ((TelCullMode )aCullingMode)
538       {
539         case TelCullNone:
540         {
541           glDisable (GL_CULL_FACE);
542           break;
543         }
544         case TelCullFront:
545         {
546           glCullFace (GL_FRONT);
547           glEnable (GL_CULL_FACE);
548           break;
549         }
550         case TelCullBack:
551         {
552           glCullFace (GL_BACK);
553           glEnable (GL_CULL_FACE);
554           break;
555         }
556       }
557     }
558   }
559
560   // Aspect_POM_None means: do not change current settings
561   if ((AspectFace_set->PolygonOffset.mode & Aspect_POM_None) != Aspect_POM_None)
562   {
563     if (PolygonOffset_applied         == NULL
564      || PolygonOffset_applied->mode   != AspectFace_set->PolygonOffset.mode
565      || PolygonOffset_applied->factor != AspectFace_set->PolygonOffset.factor
566      || PolygonOffset_applied->units  != AspectFace_set->PolygonOffset.units)
567     {
568       PolygonOffset_applied = &AspectFace_set->PolygonOffset;
569       TelUpdatePolygonOffsets (PolygonOffset_applied);
570     }
571   }
572
573   UpdateMaterial (TEL_FRONT_MATERIAL);
574   if (AspectFace_set->DistinguishingMode == TOn)
575   {
576     UpdateMaterial (TEL_BACK_MATERIAL);
577   }
578
579   if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
580   {
581     if (AspectFace_set->doTextureMap)
582     {
583       EnableTexture (AspectFace_set->TextureRes,
584                      AspectFace_set->TextureParams);
585     }
586     else
587     {
588       DisableTexture();
589     }
590   }
591
592   AspectFace_applied = AspectFace_set;
593   return AspectFace_set;
594 }
595
596 /*----------------------------------------------------------------------*/
597
598 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
599 {
600   if (theToApply && (AspectMarker_set != AspectMarker_applied))
601   {
602     if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
603     {
604       glPointSize (AspectMarker_set->Scale());
605     #ifdef HAVE_GL2PS
606       gl2psPointSize (AspectMarker_set->Scale());
607     #endif
608     }
609     AspectMarker_applied = AspectMarker_set;
610   }
611   return AspectMarker_set;
612 }
613
614 /*----------------------------------------------------------------------*/
615
616 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
617 {
618   if (theWithApply)
619   {
620     AspectText_applied = AspectText_set;
621     TextParam_applied  = TextParam_set;
622   }
623
624   return AspectText_set;
625 }