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>
32 /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */
35 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
36 Pragma comment for gl2ps.lib is defined only here. */
38 #pragma comment( lib, "gl2ps.lib" )
42 #include <Aspect_PolygonOffsetMode.hxx>
43 #include <OpenGl_View.hxx>
45 /*----------------------------------------------------------------------*/
47 static void TelUpdatePolygonOffsets( const TEL_POFFSET_PARAM *pdata )
49 if ( ( pdata->mode & Aspect_POM_Fill ) == Aspect_POM_Fill )
50 glEnable ( GL_POLYGON_OFFSET_FILL );
52 glDisable ( GL_POLYGON_OFFSET_FILL );
54 if ( ( pdata->mode & Aspect_POM_Line ) == Aspect_POM_Line )
55 glEnable ( GL_POLYGON_OFFSET_LINE );
57 glDisable( GL_POLYGON_OFFSET_LINE );
59 if ( ( pdata->mode & Aspect_POM_Point ) == Aspect_POM_Point )
60 glEnable ( GL_POLYGON_OFFSET_POINT );
62 glDisable( GL_POLYGON_OFFSET_POINT );
64 glPolygonOffset( pdata->factor, pdata->units );
67 /*----------------------------------------------------------------------*/
69 void OpenGl_Workspace::updateMaterial (const int theFlag)
71 // Case of hidden line
72 if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
74 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
75 myAspectFaceHl.ChangeIntFront().matcol = BackgroundColor();
76 myAspectFaceHl.ChangeIntFront().color_mask = 0;
77 myAspectFaceHl.ChangeIntFront().color_mask = 0;
79 AspectFace_set = &myAspectFaceHl;
83 const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
84 GLenum aFace = GL_FRONT_AND_BACK;
85 if (theFlag == TEL_BACK_MATERIAL)
88 aProps = &AspectFace_set->IntBack();
90 else if (AspectFace_set->DistinguishingMode() == TOn
91 && !(NamedStatus & OPENGL_NS_RESMAT))
96 myMatTmp.Init (*aProps);
98 // handling transparency
99 if (NamedStatus & OPENGL_NS_2NDPASSDO)
102 myMatTmp.Diffuse.a() = aProps->env_reflexion;
106 if (aProps->env_reflexion != 0.0f)
108 // if the material reflects the environment scene, the second pass is needed
109 NamedStatus |= OPENGL_NS_2NDPASSNEED;
112 if (myUseTransparency && aProps->trans != 1.0f)
114 // render transparent
115 myMatTmp.Diffuse.a() = aProps->trans;
116 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
118 glDepthMask (GL_FALSE);
123 if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
125 glBlendFunc (GL_ONE, GL_ZERO);
126 glDisable (GL_BLEND);
128 glDepthMask (GL_TRUE);
132 // do not update material properties in case of zero reflection mode,
133 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
134 if (aProps->color_mask == 0)
140 if (NamedStatus & OPENGL_NS_RESMAT)
142 glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
143 glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
144 glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
145 glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
146 glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
148 if (theFlag == TEL_FRONT_MATERIAL)
150 myMatFront = myMatTmp;
151 myMatBack = myMatTmp;
155 myMatBack = myMatTmp;
158 NamedStatus &= ~OPENGL_NS_RESMAT;
163 OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
167 if (myMatTmp.Ambient.r() != anOld.Ambient.r()
168 || myMatTmp.Ambient.g() != anOld.Ambient.g()
169 || myMatTmp.Ambient.b() != anOld.Ambient.b())
171 glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
173 if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
174 || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
175 || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
176 || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
178 glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
180 if (myMatTmp.Specular.r() != anOld.Specular.r()
181 || myMatTmp.Specular.g() != anOld.Specular.g()
182 || myMatTmp.Specular.b() != anOld.Specular.b())
184 glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
186 if (myMatTmp.Emission.r() != anOld.Emission.r()
187 || myMatTmp.Emission.g() != anOld.Emission.g()
188 || myMatTmp.Emission.b() != anOld.Emission.b())
190 glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
192 if (myMatTmp.Shine() != anOld.Shine())
194 glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
197 if (aFace == GL_FRONT_AND_BACK)
199 myMatBack = myMatTmp;
203 /*----------------------------------------------------------------------*/
205 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
207 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
208 AspectLine_set = AnAspect;
209 return AspectLine_old;
212 /*----------------------------------------------------------------------*/
214 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
216 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
217 AspectFace_set = AnAspect;
218 return AspectFace_old;
221 /*----------------------------------------------------------------------*/
223 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
225 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
226 AspectMarker_set = AnAspect;
227 return AspectMarker_old;
230 /*----------------------------------------------------------------------*/
232 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
234 const OpenGl_AspectText *AspectText_old = AspectText_set;
235 AspectText_set = AnAspect;
236 return AspectText_old;
239 /*----------------------------------------------------------------------*/
241 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix (const OpenGl_Matrix *AMatrix)
243 const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
244 ViewMatrix_applied = AMatrix;
246 // Update model-view matrix with new view matrix
247 UpdateModelViewMatrix();
249 return ViewMatrix_old;
252 /*----------------------------------------------------------------------*/
254 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix (const OpenGl_Matrix *AMatrix, bool aRevert)
256 const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
257 StructureMatrix_applied = AMatrix;
260 OpenGl_Transposemat3( &lmat, AMatrix );
262 // Update model-view matrix with new structure matrix
263 UpdateModelViewMatrix();
265 if (!myGlContext->ShaderManager()->IsEmpty())
269 myGlContext->ShaderManager()->RevertModelWorldStateTo (&lmat.mat);
273 myGlContext->ShaderManager()->UpdateModelWorldStateTo (&lmat.mat);
277 return StructureMatrix_old;
280 /*----------------------------------------------------------------------*/
282 const void OpenGl_Workspace::UpdateModelViewMatrix()
284 OpenGl_Matrix aStructureMatT;
285 OpenGl_Transposemat3( &aStructureMatT, StructureMatrix_applied);
287 glMatrixMode (GL_MODELVIEW);
288 OpenGl_Multiplymat3 (&myModelViewMatrix, &aStructureMatT, ViewMatrix_applied);
289 glLoadMatrixf ((const GLfloat* )&myModelViewMatrix.mat);
292 /*----------------------------------------------------------------------*/
294 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
296 if ( WithApply && (AspectLine_set != AspectLine_applied) )
298 glColor3fv(AspectLine_set->Color().rgb);
300 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
302 myDisplay->SetTypeOfLine(AspectLine_set->Type());
305 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
307 glLineWidth( (GLfloat)AspectLine_set->Width() );
309 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
313 AspectLine_applied = AspectLine_set;
315 return AspectLine_set;
318 /*----------------------------------------------------------------------*/
320 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
324 return AspectFace_set;
327 if (!ActiveView()->Backfacing())
329 // manage back face culling mode, disable culling when clipping is enabled
330 TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
331 || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
333 : (TelCullMode )AspectFace_set->CullingMode();
334 if (aCullingMode != TelCullNone
335 && myUseTransparency && !(NamedStatus & OPENGL_NS_2NDPASSDO))
337 // disable culling in case of translucent shading aspect
338 if (AspectFace_set->IntFront().trans != 1.0f)
340 aCullingMode = TelCullNone;
343 if (myCullingMode != aCullingMode)
345 myCullingMode = aCullingMode;
346 switch (myCullingMode)
349 case TelCullUndefined:
351 glDisable (GL_CULL_FACE);
356 glCullFace (GL_FRONT);
357 glEnable (GL_CULL_FACE);
362 glCullFace (GL_BACK);
363 glEnable (GL_CULL_FACE);
370 if (AspectFace_set == AspectFace_applied)
372 return AspectFace_set;
375 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
376 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
380 case Aspect_IS_EMPTY:
381 case Aspect_IS_HOLLOW:
383 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
386 case Aspect_IS_HATCH:
388 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
389 myDisplay->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
392 case Aspect_IS_SOLID:
393 case Aspect_IS_HIDDENLINE:
395 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
396 glDisable (GL_POLYGON_STIPPLE);
399 case Aspect_IS_POINT:
401 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
407 if (anIntstyle == Aspect_IS_HATCH)
409 const Tint hatchstyle = AspectFace_set->Hatch();
410 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
412 myDisplay->SetTypeOfHatch(hatchstyle);
416 // Aspect_POM_None means: do not change current settings
417 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
419 if (PolygonOffset_applied == NULL
420 || PolygonOffset_applied->mode != AspectFace_set->PolygonOffset().mode
421 || PolygonOffset_applied->factor != AspectFace_set->PolygonOffset().factor
422 || PolygonOffset_applied->units != AspectFace_set->PolygonOffset().units)
424 PolygonOffset_applied = &AspectFace_set->PolygonOffset();
425 TelUpdatePolygonOffsets (PolygonOffset_applied);
429 updateMaterial (TEL_FRONT_MATERIAL);
430 if (AspectFace_set->DistinguishingMode() == TOn)
432 updateMaterial (TEL_BACK_MATERIAL);
435 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
437 if (AspectFace_set->DoTextureMap())
439 EnableTexture (AspectFace_set->TextureRes (this),
440 AspectFace_set->TextureParams());
448 AspectFace_applied = AspectFace_set;
449 return AspectFace_set;
452 /*----------------------------------------------------------------------*/
454 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
456 if (theToApply && (AspectMarker_set != AspectMarker_applied))
458 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
460 glPointSize (AspectMarker_set->Scale());
462 gl2psPointSize (AspectMarker_set->Scale());
465 AspectMarker_applied = AspectMarker_set;
467 return AspectMarker_set;
470 /*----------------------------------------------------------------------*/
472 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
476 AspectText_applied = AspectText_set;
477 TextParam_applied = TextParam_set;
480 return AspectText_set;