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>
30 /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */
33 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
34 Pragma comment for gl2ps.lib is defined only here. */
36 #pragma comment( lib, "gl2ps.lib" )
40 #include <OpenGl_TextureBox.hxx>
41 #include <Aspect_PolygonOffsetMode.hxx>
42 #include <OpenGl_View.hxx>
44 /*----------------------------------------------------------------------*/
46 static void TelUpdatePolygonOffsets( const TEL_POFFSET_PARAM *pdata )
48 if ( ( pdata->mode & Aspect_POM_Fill ) == Aspect_POM_Fill )
49 glEnable ( GL_POLYGON_OFFSET_FILL );
51 glDisable ( GL_POLYGON_OFFSET_FILL );
53 if ( ( pdata->mode & Aspect_POM_Line ) == Aspect_POM_Line )
54 glEnable ( GL_POLYGON_OFFSET_LINE );
56 glDisable( GL_POLYGON_OFFSET_LINE );
58 if ( ( pdata->mode & Aspect_POM_Point ) == Aspect_POM_Point )
59 glEnable ( GL_POLYGON_OFFSET_POINT );
61 glDisable( GL_POLYGON_OFFSET_POINT );
63 glPolygonOffset( pdata->factor, pdata->units );
66 /*----------------------------------------------------------------------*/
68 void OpenGl_Workspace::UpdateMaterial( const int flag )
71 if (AspectFace_set->Context().InteriorStyle == Aspect_IS_HIDDENLINE)
73 /* szvgl - IMPORTANT!!! */
74 static TEL_CONTEXT_FACE hl_context_face;
75 static OpenGl_AspectFace hl_aspect_face;
77 hl_context_face = AspectFace_set->Context();
79 hl_context_face.IntFront.matcol = BackgroundColor();
80 hl_context_face.IntFront.color_mask = 0;
81 hl_context_face.IntBack.color_mask = 0;
83 hl_aspect_face.SetContext(hl_context_face);
84 hl_aspect_face.SetAspectEdge(AspectFace_set->AspectEdge());
86 AspectFace_set = &hl_aspect_face;
90 const OPENGL_SURF_PROP *prop = NULL;
92 if ( flag == TEL_FRONT_MATERIAL )
94 prop = &AspectFace_set->Context().IntFront;
95 face = GL_FRONT_AND_BACK;
99 prop = &AspectFace_set->Context().IntBack;
103 const unsigned int rm = prop->color_mask;
107 // Handling transparency
108 if ( (NamedStatus & OPENGL_NS_2NDPASSDO) == 0 )
110 if ( myUseTransparency && prop->trans != 1.0F )
112 // Render transparent
113 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
115 glDepthMask (GL_FALSE);
120 if ( (NamedStatus & OPENGL_NS_ANTIALIASING) == 0 )
122 glBlendFunc (GL_ONE, GL_ZERO);
123 glDisable (GL_BLEND);
125 glDepthMask (GL_TRUE);
129 static float mAmb[4];
130 static float mDiff[4];
131 static float mSpec[4];
132 static float mEmsv[4];
135 static const float defspeccol[4] = { 1.F, 1.F, 1.F, 1.F };
138 if ( NamedStatus & OPENGL_NS_RESMAT )
141 if( rm & OPENGL_AMBIENT_MASK )
143 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
145 mAmb[0] = prop->amb * c[0];
146 mAmb[1] = prop->amb * c[1];
147 mAmb[2] = prop->amb * c[2];
157 // Diffusion component
158 if( rm & OPENGL_DIFFUSE_MASK )
160 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
162 mDiff[0] = prop->diff * c[0];
163 mDiff[1] = prop->diff * c[1];
164 mDiff[2] = prop->diff * c[2];
174 if (NamedStatus & OPENGL_NS_2NDPASSDO)
176 mDiff[3] = prop->env_reflexion;
180 if (myUseTransparency) mDiff[3] = prop->trans;
181 // If the material reflects the environment scene, the second pass is needed
182 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
185 // Specular component
186 if( rm & OPENGL_SPECULAR_MASK )
188 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
190 mSpec[0] = prop->spec * c[0];
191 mSpec[1] = prop->spec * c[1];
192 mSpec[2] = prop->spec * c[2];
201 // Emissive component
202 if( rm & OPENGL_EMISSIVE_MASK )
204 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
206 mEmsv[0] = prop->emsv * c[0];
207 mEmsv[1] = prop->emsv * c[1];
208 mEmsv[2] = prop->emsv * c[2];
217 /* Coeficient de brillance */
220 glMaterialfv(face, GL_AMBIENT, mAmb );
221 glMaterialfv(face, GL_DIFFUSE, mDiff );
222 glMaterialfv(face, GL_SPECULAR, mSpec);
223 glMaterialfv(face, GL_EMISSION, mEmsv);
224 glMaterialf(face, GL_SHININESS, mShin);
226 NamedStatus &= ~OPENGL_NS_RESMAT;
229 // Set Material Optimize
233 if( rm & OPENGL_AMBIENT_MASK )
235 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
237 if (mAmb[0] != prop->amb * c[0] ||
238 mAmb[1] != prop->amb * c[1] ||
239 mAmb[2] != prop->amb * c[2] )
241 mAmb[0] = prop->amb * c[0];
242 mAmb[1] = prop->amb * c[1];
243 mAmb[2] = prop->amb * c[2];
246 glMaterialfv(face, GL_AMBIENT, mAmb);
251 if ( mAmb[0] != 0.F || mAmb[1] != 0.F || mAmb[2] != 0.F )
258 glMaterialfv(face, GL_AMBIENT, mAmb);
262 // Diffusion component
263 if( rm & OPENGL_DIFFUSE_MASK )
265 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
267 if (mDiff[0] != prop->diff * c[0] ||
268 mDiff[1] != prop->diff * c[1] ||
269 mDiff[2] != prop->diff * c[2] ||
270 mDiff[3] != ((NamedStatus & OPENGL_NS_2NDPASSDO)? prop->env_reflexion : (myUseTransparency? prop->trans : 1.0F)))
272 mDiff[0] = prop->diff * c[0];
273 mDiff[1] = prop->diff * c[1];
274 mDiff[2] = prop->diff * c[2];
277 if (NamedStatus & OPENGL_NS_2NDPASSDO)
279 mDiff[3] = prop->env_reflexion;
283 if (myUseTransparency) mDiff[3] = prop->trans;
284 // If the material reflects the environment scene, the second pass is needed
285 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
288 glMaterialfv(face, GL_DIFFUSE, mDiff );
293 Tfloat newDiff3 = 1.F;
295 if (NamedStatus & OPENGL_NS_2NDPASSDO)
297 newDiff3 = prop->env_reflexion;
301 if (myUseTransparency) newDiff3 = prop->trans;
302 // If the material reflects the environment scene, the second pass is needed
303 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
306 /* OCC19915: Even if diffuse reflectance is disabled,
307 still trying to update the current transparency if it
308 differs from the previous value */
309 if ( mDiff[0] != 0.F || mDiff[1] != 0.F || mDiff[2] != 0.F || fabs(mDiff[3] - newDiff3) > 0.01F )
316 glMaterialfv(face, GL_DIFFUSE, mDiff);
320 // Specular component
321 if( rm & OPENGL_SPECULAR_MASK )
323 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
325 if (mSpec[0] != prop->spec * c[0] ||
326 mSpec[1] != prop->spec * c[1] ||
327 mSpec[2] != prop->spec * c[2])
329 mSpec[0] = prop->spec * c[0];
330 mSpec[1] = prop->spec * c[1];
331 mSpec[2] = prop->spec * c[2];
334 glMaterialfv(face, GL_SPECULAR, mSpec);
339 if ( mSpec[0] != 0.F || mSpec[1] != 0.F || mSpec[2] != 0.F )
346 glMaterialfv(face, GL_SPECULAR, mSpec);
350 // Emissive component
351 if( rm & OPENGL_EMISSIVE_MASK )
353 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
355 if (mEmsv[0] != prop->emsv * c[0] ||
356 mEmsv[1] != prop->emsv * c[1] ||
357 mEmsv[2] != prop->emsv * c[2])
359 mEmsv[0] = prop->emsv * c[0];
360 mEmsv[1] = prop->emsv * c[1];
361 mEmsv[2] = prop->emsv * c[2];
364 glMaterialfv(face, GL_EMISSION, mEmsv);
369 if ( mEmsv[0] != 0.F || mEmsv[1] != 0.F || mEmsv[2] != 0.F )
376 glMaterialfv(face, GL_EMISSION, mEmsv);
380 // Shining coefficient
381 if( mShin != prop->shine )
384 glMaterialf(face, GL_SHININESS, mShin);
389 /*----------------------------------------------------------------------*/
391 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
393 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
394 AspectLine_set = AnAspect;
395 return AspectLine_old;
398 /*----------------------------------------------------------------------*/
400 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
402 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
403 AspectFace_set = AnAspect;
404 return AspectFace_old;
407 /*----------------------------------------------------------------------*/
409 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
411 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
412 AspectMarker_set = AnAspect;
413 return AspectMarker_old;
416 /*----------------------------------------------------------------------*/
418 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
420 const OpenGl_AspectText *AspectText_old = AspectText_set;
421 AspectText_set = AnAspect;
422 return AspectText_old;
425 /*----------------------------------------------------------------------*/
427 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix(const OpenGl_Matrix *AMatrix)
429 const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
430 ViewMatrix_applied = AMatrix;
433 OpenGl_Transposemat3( &lmat, StructureMatrix_applied );
435 glMatrixMode (GL_MODELVIEW);
437 if ( (NamedStatus & OPENGL_NS_ANIMATION) == 0 )
440 OpenGl_Multiplymat3( &rmat, &lmat, ViewMatrix_applied );
441 glLoadMatrixf((const GLfloat *) rmat.mat);
444 return ViewMatrix_old;
447 /*----------------------------------------------------------------------*/
449 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix(const OpenGl_Matrix *AMatrix)
451 const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
452 StructureMatrix_applied = AMatrix;
455 OpenGl_Transposemat3( &lmat, AMatrix );
457 glMatrixMode (GL_MODELVIEW);
459 if ( (NamedStatus & OPENGL_NS_ANIMATION) == 0 )
462 OpenGl_Multiplymat3( &rmat, &lmat, ViewMatrix_applied );
463 glLoadMatrixf((const GLfloat *) rmat.mat);
467 glMultMatrixf((const GLfloat *) lmat.mat);
470 return StructureMatrix_old;
473 /*----------------------------------------------------------------------*/
475 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
477 if ( WithApply && (AspectLine_set != AspectLine_applied) )
479 glColor3fv(AspectLine_set->Color().rgb);
481 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
483 myDisplay->SetTypeOfLine(AspectLine_set->Type());
486 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
488 glLineWidth( (GLfloat)AspectLine_set->Width() );
490 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
494 AspectLine_applied = AspectLine_set;
496 return AspectLine_set;
499 /*----------------------------------------------------------------------*/
501 const OpenGl_AspectFace * OpenGl_Workspace::AspectFace(const Standard_Boolean WithApply)
503 if ( WithApply && (AspectFace_set != AspectFace_applied) )
505 const Aspect_InteriorStyle intstyle = AspectFace_set->Context().InteriorStyle;
506 if ( !AspectFace_applied || AspectFace_applied->Context().InteriorStyle != intstyle )
510 case Aspect_IS_EMPTY:
511 case Aspect_IS_HOLLOW:
512 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
515 case Aspect_IS_HATCH:
516 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
517 myDisplay->SetTypeOfHatch(AspectFace_applied? AspectFace_applied->Context().Hatch : TEL_HS_SOLID);
520 case Aspect_IS_SOLID:
521 case Aspect_IS_HIDDENLINE:
522 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
523 glDisable(GL_POLYGON_STIPPLE);
526 case 5: //szvgl - no corresponding enumeration item Aspect_IS_POINT
527 glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
531 if( intstyle == Aspect_IS_HATCH )
533 const Tint hatchstyle = AspectFace_set->Context().Hatch;
534 if( !AspectFace_applied || AspectFace_applied->Context().Hatch != hatchstyle )
536 myDisplay->SetTypeOfHatch(hatchstyle);
539 if ( !ActiveView()->Backfacing() )
541 const Tint mode = AspectFace_set->Context().CullingMode;
542 if( !AspectFace_applied || AspectFace_applied->Context().CullingMode != mode )
544 switch( (TelCullMode)mode )
547 glDisable(GL_CULL_FACE);
551 glCullFace(GL_FRONT);
552 glEnable(GL_CULL_FACE);
557 glEnable(GL_CULL_FACE);
563 // Aspect_POM_None means: do not change current settings
564 if ( ( AspectFace_set->Context().PolygonOffset.mode & Aspect_POM_None ) != Aspect_POM_None )
566 if ( !PolygonOffset_applied ||
567 PolygonOffset_applied->mode != AspectFace_set->Context().PolygonOffset.mode ||
568 PolygonOffset_applied->factor != AspectFace_set->Context().PolygonOffset.factor ||
569 PolygonOffset_applied->units != AspectFace_set->Context().PolygonOffset.units )
571 PolygonOffset_applied = &AspectFace_set->Context().PolygonOffset;
572 TelUpdatePolygonOffsets( PolygonOffset_applied );
576 UpdateMaterial( TEL_FRONT_MATERIAL );
577 if (AspectFace_set->Context().DistinguishingMode == TOn)
578 UpdateMaterial( TEL_BACK_MATERIAL );
580 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
583 if (AspectFace_set->Context().doTextureMap)
585 SetCurrentTexture(AspectFace_set->Context().TexId);
590 AspectFace_applied = AspectFace_set;
592 return AspectFace_set;
595 /*----------------------------------------------------------------------*/
597 const OpenGl_AspectMarker * OpenGl_Workspace::AspectMarker(const Standard_Boolean WithApply)
599 if ( WithApply && (AspectMarker_set != AspectMarker_applied) )
601 AspectMarker_applied = AspectMarker_set;
603 return AspectMarker_set;
606 /*----------------------------------------------------------------------*/
608 const OpenGl_AspectText * OpenGl_Workspace::AspectText(const Standard_Boolean WithApply)
612 Standard_Boolean toApply = Standard_False;
613 if ( AspectText_set != AspectText_applied )
615 if ( !AspectText_applied )
616 toApply = Standard_True;
617 else if ( strcmp( AspectText_set->Font(), AspectText_applied->Font() ) ||
618 ( AspectText_set->FontAspect() != AspectText_applied->FontAspect() ) )
619 toApply = Standard_True;
621 AspectText_applied = AspectText_set;
623 if ( TextParam_set != TextParam_applied )
625 if ( !TextParam_applied )
626 toApply = Standard_True;
627 else if ( TextParam_set->Height != TextParam_applied->Height )
628 toApply = Standard_True;
630 TextParam_applied = TextParam_set;
634 FindFont(AspectText_applied->Font(), AspectText_applied->FontAspect(), TextParam_applied->Height);
637 return AspectText_set;
640 /*----------------------------------------------------------------------*/
642 //=======================================================================
643 //function : ResetAppliedAspect
645 //=======================================================================
647 void OpenGl_Workspace::ResetAppliedAspect()
649 AspectLine_applied = NULL;
650 AspectFace_applied = NULL;
651 AspectMarker_applied = NULL;
652 AspectText_applied = NULL;
653 TextParam_applied = NULL;