1 // Created on: 2011-08-05
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.
21 #include <OpenGl_GlCore11.hxx>
23 #include <OpenGl_Workspace.hxx>
25 #include <OpenGl_AspectLine.hxx>
26 #include <OpenGl_AspectFace.hxx>
27 #include <OpenGl_AspectMarker.hxx>
28 #include <OpenGl_AspectText.hxx>
34 /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */
37 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
38 Pragma comment for gl2ps.lib is defined only here. */
40 #pragma comment( lib, "gl2ps.lib" )
44 #include <OpenGl_TextureBox.hxx>
45 #include <Aspect_PolygonOffsetMode.hxx>
46 #include <OpenGl_View.hxx>
48 /*----------------------------------------------------------------------*/
50 static void TelUpdatePolygonOffsets( const TEL_POFFSET_PARAM *pdata )
52 if ( ( pdata->mode & Aspect_POM_Fill ) == Aspect_POM_Fill )
53 glEnable ( GL_POLYGON_OFFSET_FILL );
55 glDisable ( GL_POLYGON_OFFSET_FILL );
57 if ( ( pdata->mode & Aspect_POM_Line ) == Aspect_POM_Line )
58 glEnable ( GL_POLYGON_OFFSET_LINE );
60 glDisable( GL_POLYGON_OFFSET_LINE );
62 if ( ( pdata->mode & Aspect_POM_Point ) == Aspect_POM_Point )
63 glEnable ( GL_POLYGON_OFFSET_POINT );
65 glDisable( GL_POLYGON_OFFSET_POINT );
67 glPolygonOffset( pdata->factor, pdata->units );
70 /*----------------------------------------------------------------------*/
72 void OpenGl_Workspace::UpdateMaterial( const int flag )
75 if (AspectFace_set->Context().InteriorStyle == Aspect_IS_HIDDENLINE)
77 /* szvgl - IMPORTANT!!! */
78 static TEL_CONTEXT_FACE hl_context_face;
79 static OpenGl_AspectFace hl_aspect_face;
81 hl_context_face = AspectFace_set->Context();
83 hl_context_face.IntFront.matcol = BackgroundColor();
84 hl_context_face.IntFront.color_mask = 0;
85 hl_context_face.IntBack.color_mask = 0;
87 hl_aspect_face.SetContext(hl_context_face);
88 hl_aspect_face.SetAspectEdge(AspectFace_set->AspectEdge());
90 AspectFace_set = &hl_aspect_face;
94 const OPENGL_SURF_PROP *prop = NULL;
96 if ( flag == TEL_FRONT_MATERIAL )
98 prop = &AspectFace_set->Context().IntFront;
99 face = GL_FRONT_AND_BACK;
103 prop = &AspectFace_set->Context().IntBack;
107 const unsigned int rm = prop->color_mask;
111 // Handling transparency
112 if ( (NamedStatus & OPENGL_NS_2NDPASSDO) == 0 )
114 if ( myUseTransparency && prop->trans != 1.0F )
116 // Render transparent
117 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
119 glDepthMask (GL_FALSE);
124 if ( (NamedStatus & OPENGL_NS_ANTIALIASING) == 0 )
126 glBlendFunc (GL_ONE, GL_ZERO);
127 glDisable (GL_BLEND);
129 glDepthMask (GL_TRUE);
133 static float mAmb[4];
134 static float mDiff[4];
135 static float mSpec[4];
136 static float mEmsv[4];
139 static const float defspeccol[4] = { 1.F, 1.F, 1.F, 1.F };
142 if ( NamedStatus & OPENGL_NS_RESMAT )
145 if( rm & OPENGL_AMBIENT_MASK )
147 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
149 mAmb[0] = prop->amb * c[0];
150 mAmb[1] = prop->amb * c[1];
151 mAmb[2] = prop->amb * c[2];
161 // Diffusion component
162 if( rm & OPENGL_DIFFUSE_MASK )
164 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
166 mDiff[0] = prop->diff * c[0];
167 mDiff[1] = prop->diff * c[1];
168 mDiff[2] = prop->diff * c[2];
178 if (NamedStatus & OPENGL_NS_2NDPASSDO)
180 mDiff[3] = prop->env_reflexion;
184 if (myUseTransparency) mDiff[3] = prop->trans;
185 // If the material reflects the environment scene, the second pass is needed
186 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
189 // Specular component
190 if( rm & OPENGL_SPECULAR_MASK )
192 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
194 mSpec[0] = prop->spec * c[0];
195 mSpec[1] = prop->spec * c[1];
196 mSpec[2] = prop->spec * c[2];
205 // Emissive component
206 if( rm & OPENGL_EMISSIVE_MASK )
208 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
210 mEmsv[0] = prop->emsv * c[0];
211 mEmsv[1] = prop->emsv * c[1];
212 mEmsv[2] = prop->emsv * c[2];
221 /* Coeficient de brillance */
224 glMaterialfv(face, GL_AMBIENT, mAmb );
225 glMaterialfv(face, GL_DIFFUSE, mDiff );
226 glMaterialfv(face, GL_SPECULAR, mSpec);
227 glMaterialfv(face, GL_EMISSION, mEmsv);
228 glMaterialf(face, GL_SHININESS, mShin);
230 NamedStatus &= ~OPENGL_NS_RESMAT;
233 // Set Material Optimize
237 if( rm & OPENGL_AMBIENT_MASK )
239 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
241 if (mAmb[0] != prop->amb * c[0] ||
242 mAmb[1] != prop->amb * c[1] ||
243 mAmb[2] != prop->amb * c[2] )
245 mAmb[0] = prop->amb * c[0];
246 mAmb[1] = prop->amb * c[1];
247 mAmb[2] = prop->amb * c[2];
250 glMaterialfv(face, GL_AMBIENT, mAmb);
255 if ( mAmb[0] != 0.F || mAmb[1] != 0.F || mAmb[2] != 0.F )
262 glMaterialfv(face, GL_AMBIENT, mAmb);
266 // Diffusion component
267 if( rm & OPENGL_DIFFUSE_MASK )
269 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
271 if (mDiff[0] != prop->diff * c[0] ||
272 mDiff[1] != prop->diff * c[1] ||
273 mDiff[2] != prop->diff * c[2] ||
274 mDiff[3] != ((NamedStatus & OPENGL_NS_2NDPASSDO)? prop->env_reflexion : (myUseTransparency? prop->trans : 1.0F)))
276 mDiff[0] = prop->diff * c[0];
277 mDiff[1] = prop->diff * c[1];
278 mDiff[2] = prop->diff * c[2];
281 if (NamedStatus & OPENGL_NS_2NDPASSDO)
283 mDiff[3] = prop->env_reflexion;
287 if (myUseTransparency) mDiff[3] = prop->trans;
288 // If the material reflects the environment scene, the second pass is needed
289 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
292 glMaterialfv(face, GL_DIFFUSE, mDiff );
297 Tfloat newDiff3 = 1.F;
299 if (NamedStatus & OPENGL_NS_2NDPASSDO)
301 newDiff3 = prop->env_reflexion;
305 if (myUseTransparency) newDiff3 = prop->trans;
306 // If the material reflects the environment scene, the second pass is needed
307 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
310 /* OCC19915: Even if diffuse reflectance is disabled,
311 still trying to update the current transparency if it
312 differs from the previous value */
313 if ( mDiff[0] != 0.F || mDiff[1] != 0.F || mDiff[2] != 0.F || fabs(mDiff[3] - newDiff3) > 0.01F )
320 glMaterialfv(face, GL_DIFFUSE, mDiff);
324 // Specular component
325 if( rm & OPENGL_SPECULAR_MASK )
327 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
329 if (mSpec[0] != prop->spec * c[0] ||
330 mSpec[1] != prop->spec * c[1] ||
331 mSpec[2] != prop->spec * c[2])
333 mSpec[0] = prop->spec * c[0];
334 mSpec[1] = prop->spec * c[1];
335 mSpec[2] = prop->spec * c[2];
338 glMaterialfv(face, GL_SPECULAR, mSpec);
343 if ( mSpec[0] != 0.F || mSpec[1] != 0.F || mSpec[2] != 0.F )
350 glMaterialfv(face, GL_SPECULAR, mSpec);
354 // Emissive component
355 if( rm & OPENGL_EMISSIVE_MASK )
357 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
359 if (mEmsv[0] != prop->emsv * c[0] ||
360 mEmsv[1] != prop->emsv * c[1] ||
361 mEmsv[2] != prop->emsv * c[2])
363 mEmsv[0] = prop->emsv * c[0];
364 mEmsv[1] = prop->emsv * c[1];
365 mEmsv[2] = prop->emsv * c[2];
368 glMaterialfv(face, GL_EMISSION, mEmsv);
373 if ( mEmsv[0] != 0.F || mEmsv[1] != 0.F || mEmsv[2] != 0.F )
380 glMaterialfv(face, GL_EMISSION, mEmsv);
384 // Shining coefficient
385 if( mShin != prop->shine )
388 glMaterialf(face, GL_SHININESS, mShin);
393 /*----------------------------------------------------------------------*/
395 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
397 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
398 AspectLine_set = AnAspect;
399 return AspectLine_old;
402 /*----------------------------------------------------------------------*/
404 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
406 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
407 AspectFace_set = AnAspect;
408 return AspectFace_old;
411 /*----------------------------------------------------------------------*/
413 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
415 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
416 AspectMarker_set = AnAspect;
417 return AspectMarker_old;
420 /*----------------------------------------------------------------------*/
422 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
424 const OpenGl_AspectText *AspectText_old = AspectText_set;
425 AspectText_set = AnAspect;
426 return AspectText_old;
429 /*----------------------------------------------------------------------*/
431 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix(const OpenGl_Matrix *AMatrix)
433 const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
434 ViewMatrix_applied = AMatrix;
437 OpenGl_Transposemat3( &lmat, StructureMatrix_applied );
439 glMatrixMode (GL_MODELVIEW);
441 if ( (NamedStatus & OPENGL_NS_ANIMATION) == 0 )
444 OpenGl_Multiplymat3( &rmat, &lmat, ViewMatrix_applied );
445 glLoadMatrixf((const GLfloat *) rmat.mat);
448 return ViewMatrix_old;
451 /*----------------------------------------------------------------------*/
453 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix(const OpenGl_Matrix *AMatrix)
455 const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
456 StructureMatrix_applied = AMatrix;
459 OpenGl_Transposemat3( &lmat, AMatrix );
461 glMatrixMode (GL_MODELVIEW);
463 if ( (NamedStatus & OPENGL_NS_ANIMATION) == 0 )
466 OpenGl_Multiplymat3( &rmat, &lmat, ViewMatrix_applied );
467 glLoadMatrixf((const GLfloat *) rmat.mat);
471 glMultMatrixf((const GLfloat *) lmat.mat);
474 return StructureMatrix_old;
477 /*----------------------------------------------------------------------*/
479 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
481 if ( WithApply && (AspectLine_set != AspectLine_applied) )
483 glColor3fv(AspectLine_set->Color().rgb);
485 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
487 myDisplay->SetTypeOfLine(AspectLine_set->Type());
490 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
492 glLineWidth( (GLfloat)AspectLine_set->Width() );
494 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
498 AspectLine_applied = AspectLine_set;
500 return AspectLine_set;
503 /*----------------------------------------------------------------------*/
505 const OpenGl_AspectFace * OpenGl_Workspace::AspectFace(const Standard_Boolean WithApply)
507 if ( WithApply && (AspectFace_set != AspectFace_applied) )
509 const Aspect_InteriorStyle intstyle = AspectFace_set->Context().InteriorStyle;
510 if ( !AspectFace_applied || AspectFace_applied->Context().InteriorStyle != intstyle )
514 case Aspect_IS_EMPTY:
515 case Aspect_IS_HOLLOW:
516 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
519 case Aspect_IS_HATCH:
520 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
521 myDisplay->SetTypeOfHatch(AspectFace_applied? AspectFace_applied->Context().Hatch : TEL_HS_SOLID);
524 case Aspect_IS_SOLID:
525 case Aspect_IS_HIDDENLINE:
526 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
527 glDisable(GL_POLYGON_STIPPLE);
530 case 5: //szvgl - no corresponding enumeration item Aspect_IS_POINT
531 glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
535 if( intstyle == Aspect_IS_HATCH )
537 const Tint hatchstyle = AspectFace_set->Context().Hatch;
538 if( !AspectFace_applied || AspectFace_applied->Context().Hatch != hatchstyle )
540 myDisplay->SetTypeOfHatch(hatchstyle);
543 if ( !ActiveView()->Backfacing() )
545 const Tint mode = AspectFace_set->Context().CullingMode;
546 if( !AspectFace_applied || AspectFace_applied->Context().CullingMode != mode )
548 switch( (TelCullMode)mode )
551 glDisable(GL_CULL_FACE);
555 glCullFace(GL_FRONT);
556 glEnable(GL_CULL_FACE);
561 glEnable(GL_CULL_FACE);
567 // Aspect_POM_None means: do not change current settings
568 if ( ( AspectFace_set->Context().PolygonOffset.mode & Aspect_POM_None ) != Aspect_POM_None )
570 if ( !PolygonOffset_applied ||
571 PolygonOffset_applied->mode != AspectFace_set->Context().PolygonOffset.mode ||
572 PolygonOffset_applied->factor != AspectFace_set->Context().PolygonOffset.factor ||
573 PolygonOffset_applied->units != AspectFace_set->Context().PolygonOffset.units )
575 PolygonOffset_applied = &AspectFace_set->Context().PolygonOffset;
576 TelUpdatePolygonOffsets( PolygonOffset_applied );
580 UpdateMaterial( TEL_FRONT_MATERIAL );
581 if (AspectFace_set->Context().DistinguishingMode == TOn)
582 UpdateMaterial( TEL_BACK_MATERIAL );
584 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
587 if (AspectFace_set->Context().doTextureMap)
589 SetCurrentTexture(AspectFace_set->Context().TexId);
594 AspectFace_applied = AspectFace_set;
596 return AspectFace_set;
599 /*----------------------------------------------------------------------*/
601 const OpenGl_AspectMarker * OpenGl_Workspace::AspectMarker(const Standard_Boolean WithApply)
603 if ( WithApply && (AspectMarker_set != AspectMarker_applied) )
605 AspectMarker_applied = AspectMarker_set;
607 return AspectMarker_set;
610 /*----------------------------------------------------------------------*/
612 const OpenGl_AspectText * OpenGl_Workspace::AspectText(const Standard_Boolean WithApply)
616 Standard_Boolean toApply = Standard_False;
617 if ( AspectText_set != AspectText_applied )
619 if ( !AspectText_applied )
620 toApply = Standard_True;
621 else if ( strcmp( AspectText_set->Font(), AspectText_applied->Font() ) ||
622 ( AspectText_set->FontAspect() != AspectText_applied->FontAspect() ) )
623 toApply = Standard_True;
625 AspectText_applied = AspectText_set;
627 if ( TextParam_set != TextParam_applied )
629 if ( !TextParam_applied )
630 toApply = Standard_True;
631 else if ( TextParam_set->Height != TextParam_applied->Height )
632 toApply = Standard_True;
634 TextParam_applied = TextParam_set;
638 FindFont(AspectText_applied->Font(), AspectText_applied->FontAspect(), TextParam_applied->Height);
641 return AspectText_set;
644 /*----------------------------------------------------------------------*/
646 //=======================================================================
647 //function : ResetAppliedAspect
649 //=======================================================================
651 void OpenGl_Workspace::ResetAppliedAspect()
653 AspectLine_applied = NULL;
654 AspectFace_applied = NULL;
655 AspectMarker_applied = NULL;
656 AspectText_applied = NULL;
657 TextParam_applied = NULL;