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 !defined(GL_ES_VERSION_2_0)
55 if ((theOffsetData.mode & Aspect_POM_Line) == Aspect_POM_Line)
57 glEnable (GL_POLYGON_OFFSET_LINE);
61 glDisable (GL_POLYGON_OFFSET_LINE);
64 if ((theOffsetData.mode & Aspect_POM_Point) == Aspect_POM_Point)
66 glEnable (GL_POLYGON_OFFSET_POINT);
70 glDisable (GL_POLYGON_OFFSET_POINT);
74 glPolygonOffset (theOffsetData.factor, theOffsetData.units);
77 /*----------------------------------------------------------------------*/
79 void OpenGl_Workspace::updateMaterial (const int theFlag)
81 // Case of hidden line
82 if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
84 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
85 myAspectFaceHl.ChangeIntFront().matcol = BackgroundColor();
86 myAspectFaceHl.ChangeIntFront().color_mask = 0;
87 myAspectFaceHl.ChangeIntFront().color_mask = 0;
89 AspectFace_set = &myAspectFaceHl;
93 const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
94 GLenum aFace = GL_FRONT_AND_BACK;
95 if (theFlag == TEL_BACK_MATERIAL)
98 aProps = &AspectFace_set->IntBack();
100 else if (AspectFace_set->DistinguishingMode() == TOn
101 && !(NamedStatus & OPENGL_NS_RESMAT))
106 myMatTmp.Init (*aProps);
108 // handling transparency
109 if (NamedStatus & OPENGL_NS_2NDPASSDO)
112 myMatTmp.Diffuse.a() = aProps->env_reflexion;
116 if (aProps->env_reflexion != 0.0f)
118 // if the material reflects the environment scene, the second pass is needed
119 NamedStatus |= OPENGL_NS_2NDPASSNEED;
122 if (myUseTransparency && aProps->trans != 1.0f)
124 // render transparent
125 myMatTmp.Diffuse.a() = aProps->trans;
126 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
128 glDepthMask (GL_FALSE);
133 if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
135 glBlendFunc (GL_ONE, GL_ZERO);
136 glDisable (GL_BLEND);
138 glDepthMask (GL_TRUE);
142 // do not update material properties in case of zero reflection mode,
143 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
144 if (aProps->color_mask == 0)
150 if (NamedStatus & OPENGL_NS_RESMAT)
152 #if !defined(GL_ES_VERSION_2_0)
153 glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
154 glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
155 glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
156 glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
157 glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
160 if (theFlag == TEL_FRONT_MATERIAL)
162 myMatFront = myMatTmp;
163 myMatBack = myMatTmp;
167 myMatBack = myMatTmp;
170 NamedStatus &= ~OPENGL_NS_RESMAT;
175 OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
178 #if !defined(GL_ES_VERSION_2_0)
179 if (myMatTmp.Ambient.r() != anOld.Ambient.r()
180 || myMatTmp.Ambient.g() != anOld.Ambient.g()
181 || myMatTmp.Ambient.b() != anOld.Ambient.b())
183 glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
185 if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
186 || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
187 || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
188 || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
190 glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
192 if (myMatTmp.Specular.r() != anOld.Specular.r()
193 || myMatTmp.Specular.g() != anOld.Specular.g()
194 || myMatTmp.Specular.b() != anOld.Specular.b())
196 glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
198 if (myMatTmp.Emission.r() != anOld.Emission.r()
199 || myMatTmp.Emission.g() != anOld.Emission.g()
200 || myMatTmp.Emission.b() != anOld.Emission.b())
202 glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
204 if (myMatTmp.Shine() != anOld.Shine())
206 glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
210 if (aFace == GL_FRONT_AND_BACK)
212 myMatBack = myMatTmp;
216 /*----------------------------------------------------------------------*/
218 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
220 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
221 AspectLine_set = AnAspect;
222 return AspectLine_old;
225 /*----------------------------------------------------------------------*/
227 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
229 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
230 AspectFace_set = AnAspect;
231 return AspectFace_old;
234 /*----------------------------------------------------------------------*/
236 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
238 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
239 AspectMarker_set = AnAspect;
240 return AspectMarker_old;
243 /*----------------------------------------------------------------------*/
245 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
247 const OpenGl_AspectText *AspectText_old = AspectText_set;
248 AspectText_set = AnAspect;
249 return AspectText_old;
252 /*----------------------------------------------------------------------*/
254 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix (const OpenGl_Matrix *AMatrix)
256 const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
257 ViewMatrix_applied = AMatrix;
259 // Update model-view matrix with new view matrix
260 UpdateModelViewMatrix();
262 return ViewMatrix_old;
265 /*----------------------------------------------------------------------*/
267 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix (const OpenGl_Matrix *AMatrix, bool aRevert)
269 const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
270 StructureMatrix_applied = AMatrix;
273 OpenGl_Transposemat3( &lmat, AMatrix );
275 // Update model-view matrix with new structure matrix
276 UpdateModelViewMatrix();
278 if (!myGlContext->ShaderManager()->IsEmpty())
282 myGlContext->ShaderManager()->RevertModelWorldStateTo (OpenGl_Mat4::Map (*lmat.mat));
286 myGlContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4::Map (*lmat.mat));
290 return StructureMatrix_old;
293 /*----------------------------------------------------------------------*/
295 const void OpenGl_Workspace::UpdateModelViewMatrix()
297 OpenGl_Matrix aStructureMatT;
298 OpenGl_Transposemat3( &aStructureMatT, StructureMatrix_applied);
299 OpenGl_Multiplymat3 (&myModelViewMatrix, &aStructureMatT, ViewMatrix_applied);
300 #if !defined(GL_ES_VERSION_2_0)
301 glMatrixMode (GL_MODELVIEW);
302 glLoadMatrixf ((const GLfloat* )&myModelViewMatrix.mat);
306 /*----------------------------------------------------------------------*/
308 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
310 if ( WithApply && (AspectLine_set != AspectLine_applied) )
312 const GLfloat* anRgb = AspectLine_set->Color().rgb;
313 #if !defined(GL_ES_VERSION_2_0)
317 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
319 myLineAttribs->SetTypeOfLine (AspectLine_set->Type());
322 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
324 glLineWidth( (GLfloat)AspectLine_set->Width() );
326 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
330 AspectLine_applied = AspectLine_set;
332 return AspectLine_set;
335 /*----------------------------------------------------------------------*/
337 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
341 return AspectFace_set;
344 if (!ActiveView()->Backfacing())
346 // manage back face culling mode, disable culling when clipping is enabled
347 TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
348 || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
350 : (TelCullMode )AspectFace_set->CullingMode();
351 if (aCullingMode != TelCullNone
352 && myUseTransparency && !(NamedStatus & OPENGL_NS_2NDPASSDO))
354 // disable culling in case of translucent shading aspect
355 if (AspectFace_set->IntFront().trans != 1.0f)
357 aCullingMode = TelCullNone;
360 if (myCullingMode != aCullingMode)
362 myCullingMode = aCullingMode;
363 switch (myCullingMode)
366 case TelCullUndefined:
368 glDisable (GL_CULL_FACE);
373 glCullFace (GL_FRONT);
374 glEnable (GL_CULL_FACE);
379 glCullFace (GL_BACK);
380 glEnable (GL_CULL_FACE);
387 if (AspectFace_set == AspectFace_applied)
389 return AspectFace_set;
392 #if !defined(GL_ES_VERSION_2_0)
393 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
394 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
398 case Aspect_IS_EMPTY:
399 case Aspect_IS_HOLLOW:
401 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
404 case Aspect_IS_HATCH:
406 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
407 myLineAttribs->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
410 case Aspect_IS_SOLID:
411 case Aspect_IS_HIDDENLINE:
413 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
414 glDisable (GL_POLYGON_STIPPLE);
417 case Aspect_IS_POINT:
419 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
425 if (anIntstyle == Aspect_IS_HATCH)
427 const Tint hatchstyle = AspectFace_set->Hatch();
428 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
430 myLineAttribs->SetTypeOfHatch (hatchstyle);
435 // Aspect_POM_None means: do not change current settings
436 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
438 if (PolygonOffset_applied.mode != AspectFace_set->PolygonOffset().mode
439 || PolygonOffset_applied.factor != AspectFace_set->PolygonOffset().factor
440 || PolygonOffset_applied.units != AspectFace_set->PolygonOffset().units)
442 SetPolygonOffset (AspectFace_set->PolygonOffset().mode,
443 AspectFace_set->PolygonOffset().factor,
444 AspectFace_set->PolygonOffset().units);
448 updateMaterial (TEL_FRONT_MATERIAL);
449 if (AspectFace_set->DistinguishingMode() == TOn)
451 updateMaterial (TEL_BACK_MATERIAL);
454 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
456 if (AspectFace_set->DoTextureMap())
458 EnableTexture (AspectFace_set->TextureRes (myGlContext),
459 AspectFace_set->TextureParams());
467 AspectFace_applied = AspectFace_set;
468 return AspectFace_set;
471 //=======================================================================
472 //function : SetPolygonOffset
474 //=======================================================================
475 void OpenGl_Workspace::SetPolygonOffset (int theMode,
476 Standard_ShortReal theFactor,
477 Standard_ShortReal theUnits)
479 PolygonOffset_applied.mode = theMode;
480 PolygonOffset_applied.factor = theFactor;
481 PolygonOffset_applied.units = theUnits;
483 TelUpdatePolygonOffsets (PolygonOffset_applied);
486 /*----------------------------------------------------------------------*/
488 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
490 if (theToApply && (AspectMarker_set != AspectMarker_applied))
492 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
494 #if !defined(GL_ES_VERSION_2_0)
495 glPointSize (AspectMarker_set->Scale());
497 gl2psPointSize (AspectMarker_set->Scale());
501 AspectMarker_applied = AspectMarker_set;
503 return AspectMarker_set;
506 /*----------------------------------------------------------------------*/
508 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
512 AspectText_applied = AspectText_set;
513 TextParam_applied = TextParam_set;
516 return AspectText_set;