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>
29 #include <OpenGl_Context.hxx>
30 #include <OpenGl_ShaderManager.hxx>
36 /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */
39 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
40 Pragma comment for gl2ps.lib is defined only here. */
42 #pragma comment( lib, "gl2ps.lib" )
46 #include <Aspect_PolygonOffsetMode.hxx>
47 #include <OpenGl_View.hxx>
49 /*----------------------------------------------------------------------*/
51 static void TelUpdatePolygonOffsets( const TEL_POFFSET_PARAM *pdata )
53 if ( ( pdata->mode & Aspect_POM_Fill ) == Aspect_POM_Fill )
54 glEnable ( GL_POLYGON_OFFSET_FILL );
56 glDisable ( GL_POLYGON_OFFSET_FILL );
58 if ( ( pdata->mode & Aspect_POM_Line ) == Aspect_POM_Line )
59 glEnable ( GL_POLYGON_OFFSET_LINE );
61 glDisable( GL_POLYGON_OFFSET_LINE );
63 if ( ( pdata->mode & Aspect_POM_Point ) == Aspect_POM_Point )
64 glEnable ( GL_POLYGON_OFFSET_POINT );
66 glDisable( GL_POLYGON_OFFSET_POINT );
68 glPolygonOffset( pdata->factor, pdata->units );
71 /*----------------------------------------------------------------------*/
73 void OpenGl_Workspace::UpdateMaterial( const int flag )
75 // Case of hidden line
76 if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
78 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
79 myAspectFaceHl.ChangeIntFront().matcol = BackgroundColor();
80 myAspectFaceHl.ChangeIntFront().color_mask = 0;
81 myAspectFaceHl.ChangeIntFront().color_mask = 0;
83 AspectFace_set = &myAspectFaceHl;
87 const OPENGL_SURF_PROP *prop = NULL;
89 if ( flag == TEL_FRONT_MATERIAL )
91 prop = &AspectFace_set->IntFront();
92 face = GL_FRONT_AND_BACK;
96 prop = &AspectFace_set->IntBack();
100 // Handling transparency
101 if ( (NamedStatus & OPENGL_NS_2NDPASSDO) == 0 )
103 if ( myUseTransparency && prop->trans != 1.0F )
105 // Render transparent
106 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
108 glDepthMask (GL_FALSE);
113 if ( (NamedStatus & OPENGL_NS_ANTIALIASING) == 0 )
115 glBlendFunc (GL_ONE, GL_ZERO);
116 glDisable (GL_BLEND);
118 glDepthMask (GL_TRUE);
122 // Obtaining reflection mode flags to update GL material properties
123 const unsigned int aReflectionMode = prop->color_mask;
125 // Do not update material properties in case of zero reflection mode,
126 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray()
128 if ( !aReflectionMode ) return;
130 static float mAmb[4];
131 static float mDiff[4];
132 static float mSpec[4];
133 static float mEmsv[4];
136 static const float defspeccol[4] = { 1.F, 1.F, 1.F, 1.F };
139 if ( NamedStatus & OPENGL_NS_RESMAT )
142 if( aReflectionMode & OPENGL_AMBIENT_MASK )
144 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
146 mAmb[0] = prop->amb * c[0];
147 mAmb[1] = prop->amb * c[1];
148 mAmb[2] = prop->amb * c[2];
158 // Diffusion component
159 if( aReflectionMode & OPENGL_DIFFUSE_MASK )
161 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
163 mDiff[0] = prop->diff * c[0];
164 mDiff[1] = prop->diff * c[1];
165 mDiff[2] = prop->diff * c[2];
175 if (NamedStatus & OPENGL_NS_2NDPASSDO)
177 mDiff[3] = prop->env_reflexion;
181 if (myUseTransparency) mDiff[3] = prop->trans;
182 // If the material reflects the environment scene, the second pass is needed
183 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
186 // Specular component
187 if( aReflectionMode & OPENGL_SPECULAR_MASK )
189 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
191 mSpec[0] = prop->spec * c[0];
192 mSpec[1] = prop->spec * c[1];
193 mSpec[2] = prop->spec * c[2];
202 // Emissive component
203 if( aReflectionMode & OPENGL_EMISSIVE_MASK )
205 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
207 mEmsv[0] = prop->emsv * c[0];
208 mEmsv[1] = prop->emsv * c[1];
209 mEmsv[2] = prop->emsv * c[2];
218 /* Coeficient de brillance */
221 glMaterialfv(face, GL_AMBIENT, mAmb );
222 glMaterialfv(face, GL_DIFFUSE, mDiff );
223 glMaterialfv(face, GL_SPECULAR, mSpec);
224 glMaterialfv(face, GL_EMISSION, mEmsv);
225 glMaterialf(face, GL_SHININESS, mShin);
227 NamedStatus &= ~OPENGL_NS_RESMAT;
230 // Set Material Optimize
234 if( aReflectionMode & OPENGL_AMBIENT_MASK )
236 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
238 if (mAmb[0] != prop->amb * c[0] ||
239 mAmb[1] != prop->amb * c[1] ||
240 mAmb[2] != prop->amb * c[2] )
242 mAmb[0] = prop->amb * c[0];
243 mAmb[1] = prop->amb * c[1];
244 mAmb[2] = prop->amb * c[2];
247 glMaterialfv(face, GL_AMBIENT, mAmb);
252 if ( mAmb[0] != 0.F || mAmb[1] != 0.F || mAmb[2] != 0.F )
259 glMaterialfv(face, GL_AMBIENT, mAmb);
263 // Diffusion component
264 if( aReflectionMode & OPENGL_DIFFUSE_MASK )
266 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
268 if (mDiff[0] != prop->diff * c[0] ||
269 mDiff[1] != prop->diff * c[1] ||
270 mDiff[2] != prop->diff * c[2] ||
271 mDiff[3] != ((NamedStatus & OPENGL_NS_2NDPASSDO)? prop->env_reflexion : (myUseTransparency? prop->trans : 1.0F)))
273 mDiff[0] = prop->diff * c[0];
274 mDiff[1] = prop->diff * c[1];
275 mDiff[2] = prop->diff * c[2];
278 if (NamedStatus & OPENGL_NS_2NDPASSDO)
280 mDiff[3] = prop->env_reflexion;
284 if (myUseTransparency) mDiff[3] = prop->trans;
285 // If the material reflects the environment scene, the second pass is needed
286 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
289 glMaterialfv(face, GL_DIFFUSE, mDiff );
294 Tfloat newDiff3 = 1.F;
296 if (NamedStatus & OPENGL_NS_2NDPASSDO)
298 newDiff3 = prop->env_reflexion;
302 if (myUseTransparency) newDiff3 = prop->trans;
303 // If the material reflects the environment scene, the second pass is needed
304 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
307 /* OCC19915: Even if diffuse reflectance is disabled,
308 still trying to update the current transparency if it
309 differs from the previous value */
310 if ( mDiff[0] != 0.F || mDiff[1] != 0.F || mDiff[2] != 0.F || fabs(mDiff[3] - newDiff3) > 0.01F )
317 glMaterialfv(face, GL_DIFFUSE, mDiff);
321 // Specular component
322 if( aReflectionMode & OPENGL_SPECULAR_MASK )
324 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
326 if (mSpec[0] != prop->spec * c[0] ||
327 mSpec[1] != prop->spec * c[1] ||
328 mSpec[2] != prop->spec * c[2])
330 mSpec[0] = prop->spec * c[0];
331 mSpec[1] = prop->spec * c[1];
332 mSpec[2] = prop->spec * c[2];
335 glMaterialfv(face, GL_SPECULAR, mSpec);
340 if ( mSpec[0] != 0.F || mSpec[1] != 0.F || mSpec[2] != 0.F )
347 glMaterialfv(face, GL_SPECULAR, mSpec);
351 // Emissive component
352 if( aReflectionMode & OPENGL_EMISSIVE_MASK )
354 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
356 if (mEmsv[0] != prop->emsv * c[0] ||
357 mEmsv[1] != prop->emsv * c[1] ||
358 mEmsv[2] != prop->emsv * c[2])
360 mEmsv[0] = prop->emsv * c[0];
361 mEmsv[1] = prop->emsv * c[1];
362 mEmsv[2] = prop->emsv * c[2];
365 glMaterialfv(face, GL_EMISSION, mEmsv);
370 if ( mEmsv[0] != 0.F || mEmsv[1] != 0.F || mEmsv[2] != 0.F )
377 glMaterialfv(face, GL_EMISSION, mEmsv);
381 // Shining coefficient
382 if( mShin != prop->shine )
385 glMaterialf(face, GL_SHININESS, mShin);
390 /*----------------------------------------------------------------------*/
392 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
394 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
395 AspectLine_set = AnAspect;
396 return AspectLine_old;
399 /*----------------------------------------------------------------------*/
401 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
403 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
404 AspectFace_set = AnAspect;
405 return AspectFace_old;
408 /*----------------------------------------------------------------------*/
410 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
412 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
413 AspectMarker_set = AnAspect;
414 return AspectMarker_old;
417 /*----------------------------------------------------------------------*/
419 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
421 const OpenGl_AspectText *AspectText_old = AspectText_set;
422 AspectText_set = AnAspect;
423 return AspectText_old;
426 /*----------------------------------------------------------------------*/
428 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix(const OpenGl_Matrix *AMatrix)
430 const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
431 ViewMatrix_applied = AMatrix;
434 OpenGl_Transposemat3( &lmat, StructureMatrix_applied );
436 glMatrixMode (GL_MODELVIEW);
438 OpenGl_Multiplymat3 (&rmat, &lmat, ViewMatrix_applied);
439 glLoadMatrixf ((const GLfloat* )rmat.mat);
441 return ViewMatrix_old;
444 /*----------------------------------------------------------------------*/
446 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix (const OpenGl_Matrix *AMatrix, bool aRevert)
448 const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
449 StructureMatrix_applied = AMatrix;
452 OpenGl_Transposemat3( &lmat, AMatrix );
454 glMatrixMode (GL_MODELVIEW);
456 OpenGl_Multiplymat3 (&rmat, &lmat, ViewMatrix_applied);
457 glLoadMatrixf ((const GLfloat* )rmat.mat);
459 if (!myGlContext->ShaderManager()->IsEmpty())
462 myGlContext->ShaderManager()->UpdateModelWorldStateTo (lmat.mat);
464 myGlContext->ShaderManager()->RevertModelWorldStateTo (lmat.mat);
467 return StructureMatrix_old;
470 /*----------------------------------------------------------------------*/
472 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
474 if ( WithApply && (AspectLine_set != AspectLine_applied) )
476 glColor3fv(AspectLine_set->Color().rgb);
478 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
480 myDisplay->SetTypeOfLine(AspectLine_set->Type());
483 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
485 glLineWidth( (GLfloat)AspectLine_set->Width() );
487 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
491 AspectLine_applied = AspectLine_set;
493 return AspectLine_set;
496 /*----------------------------------------------------------------------*/
498 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
500 if (!theToApply || (AspectFace_set == AspectFace_applied))
502 return AspectFace_set;
505 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
506 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
510 case Aspect_IS_EMPTY:
511 case Aspect_IS_HOLLOW:
513 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
516 case Aspect_IS_HATCH:
518 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
519 myDisplay->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
522 case Aspect_IS_SOLID:
523 case Aspect_IS_HIDDENLINE:
525 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
526 glDisable (GL_POLYGON_STIPPLE);
529 case Aspect_IS_POINT: //szvgl - no corresponding enumeration item Aspect_IS_POINT // = 5
531 glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
537 if (anIntstyle == Aspect_IS_HATCH)
539 const Tint hatchstyle = AspectFace_set->Hatch();
540 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
542 myDisplay->SetTypeOfHatch(hatchstyle);
546 if (!ActiveView()->Backfacing())
548 const Tint aCullingMode = AspectFace_set->CullingMode();
549 if (AspectFace_applied == NULL || AspectFace_applied->CullingMode() != aCullingMode)
551 switch ((TelCullMode )aCullingMode)
555 glDisable (GL_CULL_FACE);
560 glCullFace (GL_FRONT);
561 glEnable (GL_CULL_FACE);
566 glCullFace (GL_BACK);
567 glEnable (GL_CULL_FACE);
574 // Aspect_POM_None means: do not change current settings
575 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
577 if (PolygonOffset_applied == NULL
578 || PolygonOffset_applied->mode != AspectFace_set->PolygonOffset().mode
579 || PolygonOffset_applied->factor != AspectFace_set->PolygonOffset().factor
580 || PolygonOffset_applied->units != AspectFace_set->PolygonOffset().units)
582 PolygonOffset_applied = &AspectFace_set->PolygonOffset();
583 TelUpdatePolygonOffsets (PolygonOffset_applied);
587 UpdateMaterial (TEL_FRONT_MATERIAL);
588 if (AspectFace_set->DistinguishingMode() == TOn)
590 UpdateMaterial (TEL_BACK_MATERIAL);
593 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
595 if (AspectFace_set->DoTextureMap())
597 EnableTexture (AspectFace_set->TextureRes (this),
598 AspectFace_set->TextureParams());
606 AspectFace_applied = AspectFace_set;
607 return AspectFace_set;
610 /*----------------------------------------------------------------------*/
612 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
614 if (theToApply && (AspectMarker_set != AspectMarker_applied))
616 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
618 glPointSize (AspectMarker_set->Scale());
620 gl2psPointSize (AspectMarker_set->Scale());
623 AspectMarker_applied = AspectMarker_set;
625 return AspectMarker_set;
628 /*----------------------------------------------------------------------*/
630 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
634 AspectText_applied = AspectText_set;
635 TextParam_applied = TextParam_set;
638 return AspectText_set;