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>
34 /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */
37 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
38 Pragma comment for gl2ps.lib is defined only here. */
40 #pragma comment( lib, "gl2ps.lib" )
44 #include <Aspect_PolygonOffsetMode.hxx>
45 #include <OpenGl_View.hxx>
47 /*----------------------------------------------------------------------*/
49 static void TelUpdatePolygonOffsets( const TEL_POFFSET_PARAM *pdata )
51 if ( ( pdata->mode & Aspect_POM_Fill ) == Aspect_POM_Fill )
52 glEnable ( GL_POLYGON_OFFSET_FILL );
54 glDisable ( GL_POLYGON_OFFSET_FILL );
56 if ( ( pdata->mode & Aspect_POM_Line ) == Aspect_POM_Line )
57 glEnable ( GL_POLYGON_OFFSET_LINE );
59 glDisable( GL_POLYGON_OFFSET_LINE );
61 if ( ( pdata->mode & Aspect_POM_Point ) == Aspect_POM_Point )
62 glEnable ( GL_POLYGON_OFFSET_POINT );
64 glDisable( GL_POLYGON_OFFSET_POINT );
66 glPolygonOffset( pdata->factor, pdata->units );
69 /*----------------------------------------------------------------------*/
71 void OpenGl_Workspace::UpdateMaterial( const int flag )
74 if (AspectFace_set->InteriorStyle == Aspect_IS_HIDDENLINE)
76 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
77 myAspectFaceHl.IntFront.matcol = BackgroundColor();
78 myAspectFaceHl.IntFront.color_mask = 0;
79 myAspectFaceHl.IntBack.color_mask = 0;
81 AspectFace_set = &myAspectFaceHl;
85 const OPENGL_SURF_PROP *prop = NULL;
87 if ( flag == TEL_FRONT_MATERIAL )
89 prop = &AspectFace_set->IntFront;
90 face = GL_FRONT_AND_BACK;
94 prop = &AspectFace_set->IntBack;
98 const unsigned int rm = prop->color_mask;
102 // Handling transparency
103 if ( (NamedStatus & OPENGL_NS_2NDPASSDO) == 0 )
105 if ( myUseTransparency && prop->trans != 1.0F )
107 // Render transparent
108 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
110 glDepthMask (GL_FALSE);
115 if ( (NamedStatus & OPENGL_NS_ANTIALIASING) == 0 )
117 glBlendFunc (GL_ONE, GL_ZERO);
118 glDisable (GL_BLEND);
120 glDepthMask (GL_TRUE);
124 static float mAmb[4];
125 static float mDiff[4];
126 static float mSpec[4];
127 static float mEmsv[4];
130 static const float defspeccol[4] = { 1.F, 1.F, 1.F, 1.F };
133 if ( NamedStatus & OPENGL_NS_RESMAT )
136 if( rm & OPENGL_AMBIENT_MASK )
138 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
140 mAmb[0] = prop->amb * c[0];
141 mAmb[1] = prop->amb * c[1];
142 mAmb[2] = prop->amb * c[2];
152 // Diffusion component
153 if( rm & OPENGL_DIFFUSE_MASK )
155 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
157 mDiff[0] = prop->diff * c[0];
158 mDiff[1] = prop->diff * c[1];
159 mDiff[2] = prop->diff * c[2];
169 if (NamedStatus & OPENGL_NS_2NDPASSDO)
171 mDiff[3] = prop->env_reflexion;
175 if (myUseTransparency) mDiff[3] = prop->trans;
176 // If the material reflects the environment scene, the second pass is needed
177 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
180 // Specular component
181 if( rm & OPENGL_SPECULAR_MASK )
183 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
185 mSpec[0] = prop->spec * c[0];
186 mSpec[1] = prop->spec * c[1];
187 mSpec[2] = prop->spec * c[2];
196 // Emissive component
197 if( rm & OPENGL_EMISSIVE_MASK )
199 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
201 mEmsv[0] = prop->emsv * c[0];
202 mEmsv[1] = prop->emsv * c[1];
203 mEmsv[2] = prop->emsv * c[2];
212 /* Coeficient de brillance */
215 glMaterialfv(face, GL_AMBIENT, mAmb );
216 glMaterialfv(face, GL_DIFFUSE, mDiff );
217 glMaterialfv(face, GL_SPECULAR, mSpec);
218 glMaterialfv(face, GL_EMISSION, mEmsv);
219 glMaterialf(face, GL_SHININESS, mShin);
221 NamedStatus &= ~OPENGL_NS_RESMAT;
224 // Set Material Optimize
228 if( rm & OPENGL_AMBIENT_MASK )
230 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
232 if (mAmb[0] != prop->amb * c[0] ||
233 mAmb[1] != prop->amb * c[1] ||
234 mAmb[2] != prop->amb * c[2] )
236 mAmb[0] = prop->amb * c[0];
237 mAmb[1] = prop->amb * c[1];
238 mAmb[2] = prop->amb * c[2];
241 glMaterialfv(face, GL_AMBIENT, mAmb);
246 if ( mAmb[0] != 0.F || mAmb[1] != 0.F || mAmb[2] != 0.F )
253 glMaterialfv(face, GL_AMBIENT, mAmb);
257 // Diffusion component
258 if( rm & OPENGL_DIFFUSE_MASK )
260 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
262 if (mDiff[0] != prop->diff * c[0] ||
263 mDiff[1] != prop->diff * c[1] ||
264 mDiff[2] != prop->diff * c[2] ||
265 mDiff[3] != ((NamedStatus & OPENGL_NS_2NDPASSDO)? prop->env_reflexion : (myUseTransparency? prop->trans : 1.0F)))
267 mDiff[0] = prop->diff * c[0];
268 mDiff[1] = prop->diff * c[1];
269 mDiff[2] = prop->diff * c[2];
272 if (NamedStatus & OPENGL_NS_2NDPASSDO)
274 mDiff[3] = prop->env_reflexion;
278 if (myUseTransparency) mDiff[3] = prop->trans;
279 // If the material reflects the environment scene, the second pass is needed
280 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
283 glMaterialfv(face, GL_DIFFUSE, mDiff );
288 Tfloat newDiff3 = 1.F;
290 if (NamedStatus & OPENGL_NS_2NDPASSDO)
292 newDiff3 = prop->env_reflexion;
296 if (myUseTransparency) newDiff3 = prop->trans;
297 // If the material reflects the environment scene, the second pass is needed
298 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
301 /* OCC19915: Even if diffuse reflectance is disabled,
302 still trying to update the current transparency if it
303 differs from the previous value */
304 if ( mDiff[0] != 0.F || mDiff[1] != 0.F || mDiff[2] != 0.F || fabs(mDiff[3] - newDiff3) > 0.01F )
311 glMaterialfv(face, GL_DIFFUSE, mDiff);
315 // Specular component
316 if( rm & OPENGL_SPECULAR_MASK )
318 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
320 if (mSpec[0] != prop->spec * c[0] ||
321 mSpec[1] != prop->spec * c[1] ||
322 mSpec[2] != prop->spec * c[2])
324 mSpec[0] = prop->spec * c[0];
325 mSpec[1] = prop->spec * c[1];
326 mSpec[2] = prop->spec * c[2];
329 glMaterialfv(face, GL_SPECULAR, mSpec);
334 if ( mSpec[0] != 0.F || mSpec[1] != 0.F || mSpec[2] != 0.F )
341 glMaterialfv(face, GL_SPECULAR, mSpec);
345 // Emissive component
346 if( rm & OPENGL_EMISSIVE_MASK )
348 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
350 if (mEmsv[0] != prop->emsv * c[0] ||
351 mEmsv[1] != prop->emsv * c[1] ||
352 mEmsv[2] != prop->emsv * c[2])
354 mEmsv[0] = prop->emsv * c[0];
355 mEmsv[1] = prop->emsv * c[1];
356 mEmsv[2] = prop->emsv * c[2];
359 glMaterialfv(face, GL_EMISSION, mEmsv);
364 if ( mEmsv[0] != 0.F || mEmsv[1] != 0.F || mEmsv[2] != 0.F )
371 glMaterialfv(face, GL_EMISSION, mEmsv);
375 // Shining coefficient
376 if( mShin != prop->shine )
379 glMaterialf(face, GL_SHININESS, mShin);
384 /*----------------------------------------------------------------------*/
386 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
388 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
389 AspectLine_set = AnAspect;
390 return AspectLine_old;
393 /*----------------------------------------------------------------------*/
395 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
397 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
398 AspectFace_set = AnAspect;
399 return AspectFace_old;
402 /*----------------------------------------------------------------------*/
404 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
406 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
407 AspectMarker_set = AnAspect;
408 return AspectMarker_old;
411 /*----------------------------------------------------------------------*/
413 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
415 const OpenGl_AspectText *AspectText_old = AspectText_set;
416 AspectText_set = AnAspect;
417 return AspectText_old;
420 /*----------------------------------------------------------------------*/
422 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix(const OpenGl_Matrix *AMatrix)
424 const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
425 ViewMatrix_applied = AMatrix;
428 OpenGl_Transposemat3( &lmat, StructureMatrix_applied );
430 glMatrixMode (GL_MODELVIEW);
432 OpenGl_Multiplymat3 (&rmat, &lmat, ViewMatrix_applied);
433 glLoadMatrixf ((const GLfloat* )rmat.mat);
435 return ViewMatrix_old;
438 /*----------------------------------------------------------------------*/
440 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix(const OpenGl_Matrix *AMatrix)
442 const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
443 StructureMatrix_applied = AMatrix;
446 OpenGl_Transposemat3( &lmat, AMatrix );
448 glMatrixMode (GL_MODELVIEW);
450 OpenGl_Multiplymat3 (&rmat, &lmat, ViewMatrix_applied);
451 glLoadMatrixf ((const GLfloat* )rmat.mat);
453 return StructureMatrix_old;
456 /*----------------------------------------------------------------------*/
458 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
460 if ( WithApply && (AspectLine_set != AspectLine_applied) )
462 glColor3fv(AspectLine_set->Color().rgb);
464 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
466 myDisplay->SetTypeOfLine(AspectLine_set->Type());
469 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
471 glLineWidth( (GLfloat)AspectLine_set->Width() );
473 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
477 AspectLine_applied = AspectLine_set;
479 return AspectLine_set;
482 /*----------------------------------------------------------------------*/
484 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
486 if (!theToApply || (AspectFace_set == AspectFace_applied))
488 return AspectFace_set;
491 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle;
492 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle != anIntstyle)
496 case Aspect_IS_EMPTY:
497 case Aspect_IS_HOLLOW:
499 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
502 case Aspect_IS_HATCH:
504 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
505 myDisplay->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch : TEL_HS_SOLID);
508 case Aspect_IS_SOLID:
509 case Aspect_IS_HIDDENLINE:
511 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
512 glDisable (GL_POLYGON_STIPPLE);
515 case 5: //szvgl - no corresponding enumeration item Aspect_IS_POINT
517 glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
523 if (anIntstyle == Aspect_IS_HATCH)
525 const Tint hatchstyle = AspectFace_set->Hatch;
526 if (AspectFace_applied == NULL || AspectFace_applied->Hatch != hatchstyle)
528 myDisplay->SetTypeOfHatch(hatchstyle);
532 if (!ActiveView()->Backfacing())
534 const Tint aCullingMode = AspectFace_set->CullingMode;
535 if (AspectFace_applied == NULL || AspectFace_applied->CullingMode != aCullingMode)
537 switch ((TelCullMode )aCullingMode)
541 glDisable (GL_CULL_FACE);
546 glCullFace (GL_FRONT);
547 glEnable (GL_CULL_FACE);
552 glCullFace (GL_BACK);
553 glEnable (GL_CULL_FACE);
560 // Aspect_POM_None means: do not change current settings
561 if ((AspectFace_set->PolygonOffset.mode & Aspect_POM_None) != Aspect_POM_None)
563 if (PolygonOffset_applied == NULL
564 || PolygonOffset_applied->mode != AspectFace_set->PolygonOffset.mode
565 || PolygonOffset_applied->factor != AspectFace_set->PolygonOffset.factor
566 || PolygonOffset_applied->units != AspectFace_set->PolygonOffset.units)
568 PolygonOffset_applied = &AspectFace_set->PolygonOffset;
569 TelUpdatePolygonOffsets (PolygonOffset_applied);
573 UpdateMaterial (TEL_FRONT_MATERIAL);
574 if (AspectFace_set->DistinguishingMode == TOn)
576 UpdateMaterial (TEL_BACK_MATERIAL);
579 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
581 if (AspectFace_set->doTextureMap)
583 EnableTexture (AspectFace_set->TextureRes,
584 AspectFace_set->TextureParams);
592 AspectFace_applied = AspectFace_set;
593 return AspectFace_set;
596 /*----------------------------------------------------------------------*/
598 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
600 if (theToApply && (AspectMarker_set != AspectMarker_applied))
602 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
604 glPointSize (AspectMarker_set->Scale());
606 gl2psPointSize (AspectMarker_set->Scale());
609 AspectMarker_applied = AspectMarker_set;
611 return AspectMarker_set;
614 /*----------------------------------------------------------------------*/
616 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
620 AspectText_applied = AspectText_set;
621 TextParam_applied = TextParam_set;
624 return AspectText_set;