1 // Created on: 2011-08-05
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_GlCore11.hxx>
18 #include <OpenGl_Workspace.hxx>
20 #include <OpenGl_AspectLine.hxx>
21 #include <OpenGl_AspectFace.hxx>
22 #include <OpenGl_AspectMarker.hxx>
23 #include <OpenGl_AspectText.hxx>
24 #include <OpenGl_Context.hxx>
25 #include <OpenGl_ShaderManager.hxx>
26 #include <OpenGl_telem_util.hxx>
28 /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */
31 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
32 Pragma comment for gl2ps.lib is defined only here. */
34 #pragma comment( lib, "gl2ps.lib" )
38 #include <Aspect_PolygonOffsetMode.hxx>
39 #include <OpenGl_View.hxx>
41 /*----------------------------------------------------------------------*/
43 static void TelUpdatePolygonOffsets (const TEL_POFFSET_PARAM& theOffsetData)
45 if ((theOffsetData.mode & Aspect_POM_Fill) == Aspect_POM_Fill)
47 glEnable (GL_POLYGON_OFFSET_FILL);
51 glDisable (GL_POLYGON_OFFSET_FILL);
54 if ((theOffsetData.mode & Aspect_POM_Line) == Aspect_POM_Line)
56 glEnable (GL_POLYGON_OFFSET_LINE);
60 glDisable (GL_POLYGON_OFFSET_LINE);
63 if ((theOffsetData.mode & Aspect_POM_Point) == Aspect_POM_Point)
65 glEnable (GL_POLYGON_OFFSET_POINT);
69 glDisable (GL_POLYGON_OFFSET_POINT);
72 glPolygonOffset (theOffsetData.factor, theOffsetData.units);
75 /*----------------------------------------------------------------------*/
77 void OpenGl_Workspace::updateMaterial (const int theFlag)
79 // Case of hidden line
80 if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
82 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
83 myAspectFaceHl.ChangeIntFront().matcol = BackgroundColor();
84 myAspectFaceHl.ChangeIntFront().color_mask = 0;
85 myAspectFaceHl.ChangeIntFront().color_mask = 0;
87 AspectFace_set = &myAspectFaceHl;
91 const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
92 GLenum aFace = GL_FRONT_AND_BACK;
93 if (theFlag == TEL_BACK_MATERIAL)
96 aProps = &AspectFace_set->IntBack();
98 else if (AspectFace_set->DistinguishingMode() == TOn
99 && !(NamedStatus & OPENGL_NS_RESMAT))
104 myMatTmp.Init (*aProps);
106 // handling transparency
107 if (NamedStatus & OPENGL_NS_2NDPASSDO)
110 myMatTmp.Diffuse.a() = aProps->env_reflexion;
114 if (aProps->env_reflexion != 0.0f)
116 // if the material reflects the environment scene, the second pass is needed
117 NamedStatus |= OPENGL_NS_2NDPASSNEED;
120 if (myUseTransparency && aProps->trans != 1.0f)
122 // render transparent
123 myMatTmp.Diffuse.a() = aProps->trans;
124 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
126 glDepthMask (GL_FALSE);
131 if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
133 glBlendFunc (GL_ONE, GL_ZERO);
134 glDisable (GL_BLEND);
136 glDepthMask (GL_TRUE);
140 // do not update material properties in case of zero reflection mode,
141 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
142 if (aProps->color_mask == 0)
148 if (NamedStatus & OPENGL_NS_RESMAT)
150 glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
151 glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
152 glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
153 glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
154 glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
156 if (theFlag == TEL_FRONT_MATERIAL)
158 myMatFront = myMatTmp;
159 myMatBack = myMatTmp;
163 myMatBack = myMatTmp;
166 NamedStatus &= ~OPENGL_NS_RESMAT;
171 OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
175 if (myMatTmp.Ambient.r() != anOld.Ambient.r()
176 || myMatTmp.Ambient.g() != anOld.Ambient.g()
177 || myMatTmp.Ambient.b() != anOld.Ambient.b())
179 glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
181 if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
182 || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
183 || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
184 || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
186 glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
188 if (myMatTmp.Specular.r() != anOld.Specular.r()
189 || myMatTmp.Specular.g() != anOld.Specular.g()
190 || myMatTmp.Specular.b() != anOld.Specular.b())
192 glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
194 if (myMatTmp.Emission.r() != anOld.Emission.r()
195 || myMatTmp.Emission.g() != anOld.Emission.g()
196 || myMatTmp.Emission.b() != anOld.Emission.b())
198 glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
200 if (myMatTmp.Shine() != anOld.Shine())
202 glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
205 if (aFace == GL_FRONT_AND_BACK)
207 myMatBack = myMatTmp;
211 /*----------------------------------------------------------------------*/
213 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
215 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
216 AspectLine_set = AnAspect;
217 return AspectLine_old;
220 /*----------------------------------------------------------------------*/
222 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
224 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
225 AspectFace_set = AnAspect;
226 return AspectFace_old;
229 /*----------------------------------------------------------------------*/
231 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
233 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
234 AspectMarker_set = AnAspect;
235 return AspectMarker_old;
238 /*----------------------------------------------------------------------*/
240 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
242 const OpenGl_AspectText *AspectText_old = AspectText_set;
243 AspectText_set = AnAspect;
244 return AspectText_old;
247 /*----------------------------------------------------------------------*/
249 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix (const OpenGl_Matrix *AMatrix)
251 const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
252 ViewMatrix_applied = AMatrix;
254 // Update model-view matrix with new view matrix
255 UpdateModelViewMatrix();
257 return ViewMatrix_old;
260 /*----------------------------------------------------------------------*/
262 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix (const OpenGl_Matrix *AMatrix, bool aRevert)
264 const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
265 StructureMatrix_applied = AMatrix;
268 OpenGl_Transposemat3( &lmat, AMatrix );
270 // Update model-view matrix with new structure matrix
271 UpdateModelViewMatrix();
273 if (!myGlContext->ShaderManager()->IsEmpty())
277 myGlContext->ShaderManager()->RevertModelWorldStateTo (&lmat.mat);
281 myGlContext->ShaderManager()->UpdateModelWorldStateTo (&lmat.mat);
285 return StructureMatrix_old;
288 /*----------------------------------------------------------------------*/
290 const void OpenGl_Workspace::UpdateModelViewMatrix()
292 OpenGl_Matrix aStructureMatT;
293 OpenGl_Transposemat3( &aStructureMatT, StructureMatrix_applied);
295 glMatrixMode (GL_MODELVIEW);
296 OpenGl_Multiplymat3 (&myModelViewMatrix, &aStructureMatT, ViewMatrix_applied);
297 glLoadMatrixf ((const GLfloat* )&myModelViewMatrix.mat);
300 /*----------------------------------------------------------------------*/
302 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
304 if ( WithApply && (AspectLine_set != AspectLine_applied) )
306 glColor3fv(AspectLine_set->Color().rgb);
308 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
310 myLineAttribs->SetTypeOfLine (AspectLine_set->Type());
313 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
315 glLineWidth( (GLfloat)AspectLine_set->Width() );
317 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
321 AspectLine_applied = AspectLine_set;
323 return AspectLine_set;
326 /*----------------------------------------------------------------------*/
328 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
332 return AspectFace_set;
335 if (!ActiveView()->Backfacing())
337 // manage back face culling mode, disable culling when clipping is enabled
338 TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
339 || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
341 : (TelCullMode )AspectFace_set->CullingMode();
342 if (aCullingMode != TelCullNone
343 && myUseTransparency && !(NamedStatus & OPENGL_NS_2NDPASSDO))
345 // disable culling in case of translucent shading aspect
346 if (AspectFace_set->IntFront().trans != 1.0f)
348 aCullingMode = TelCullNone;
351 if (myCullingMode != aCullingMode)
353 myCullingMode = aCullingMode;
354 switch (myCullingMode)
357 case TelCullUndefined:
359 glDisable (GL_CULL_FACE);
364 glCullFace (GL_FRONT);
365 glEnable (GL_CULL_FACE);
370 glCullFace (GL_BACK);
371 glEnable (GL_CULL_FACE);
378 if (AspectFace_set == AspectFace_applied)
380 return AspectFace_set;
383 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
384 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
388 case Aspect_IS_EMPTY:
389 case Aspect_IS_HOLLOW:
391 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
394 case Aspect_IS_HATCH:
396 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
397 myLineAttribs->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
400 case Aspect_IS_SOLID:
401 case Aspect_IS_HIDDENLINE:
403 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
404 glDisable (GL_POLYGON_STIPPLE);
407 case Aspect_IS_POINT:
409 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
415 if (anIntstyle == Aspect_IS_HATCH)
417 const Tint hatchstyle = AspectFace_set->Hatch();
418 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
420 myLineAttribs->SetTypeOfHatch (hatchstyle);
424 // Aspect_POM_None means: do not change current settings
425 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
427 if (PolygonOffset_applied.mode != AspectFace_set->PolygonOffset().mode
428 || PolygonOffset_applied.factor != AspectFace_set->PolygonOffset().factor
429 || PolygonOffset_applied.units != AspectFace_set->PolygonOffset().units)
431 SetPolygonOffset (AspectFace_set->PolygonOffset().mode,
432 AspectFace_set->PolygonOffset().factor,
433 AspectFace_set->PolygonOffset().units);
437 updateMaterial (TEL_FRONT_MATERIAL);
438 if (AspectFace_set->DistinguishingMode() == TOn)
440 updateMaterial (TEL_BACK_MATERIAL);
443 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
445 if (AspectFace_set->DoTextureMap())
447 EnableTexture (AspectFace_set->TextureRes (this),
448 AspectFace_set->TextureParams());
456 AspectFace_applied = AspectFace_set;
457 return AspectFace_set;
460 //=======================================================================
461 //function : SetPolygonOffset
463 //=======================================================================
464 void OpenGl_Workspace::SetPolygonOffset (int theMode,
465 Standard_ShortReal theFactor,
466 Standard_ShortReal theUnits)
468 PolygonOffset_applied.mode = theMode;
469 PolygonOffset_applied.factor = theFactor;
470 PolygonOffset_applied.units = theUnits;
472 TelUpdatePolygonOffsets (PolygonOffset_applied);
475 /*----------------------------------------------------------------------*/
477 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
479 if (theToApply && (AspectMarker_set != AspectMarker_applied))
481 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
483 glPointSize (AspectMarker_set->Scale());
485 gl2psPointSize (AspectMarker_set->Scale());
488 AspectMarker_applied = AspectMarker_set;
490 return AspectMarker_set;
493 /*----------------------------------------------------------------------*/
495 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
499 AspectText_applied = AspectText_set;
500 TextParam_applied = TextParam_set;
503 return AspectText_set;