1 // File: OpenGl_Workspace_5.cxx
2 // Created: 5 August 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_Workspace.hxx>
8 #include <OpenGl_AspectLine.hxx>
9 #include <OpenGl_AspectFace.hxx>
10 #include <OpenGl_AspectMarker.hxx>
11 #include <OpenGl_AspectText.hxx>
13 /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */
16 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
17 Pragma comment for gl2ps.lib is defined only here. */
19 #pragma comment( lib, "gl2ps.lib" )
23 #include <OpenGl_tgl_all.hxx>
26 #include <OpenGl_TextureBox.hxx>
28 #include <Aspect_PolygonOffsetMode.hxx>
30 #include <OpenGl_View.hxx>
32 /*----------------------------------------------------------------------*/
34 static void TelUpdatePolygonOffsets( const TEL_POFFSET_PARAM *pdata )
36 if ( ( pdata->mode & Aspect_POM_Fill ) == Aspect_POM_Fill )
37 glEnable ( GL_POLYGON_OFFSET_FILL );
39 glDisable ( GL_POLYGON_OFFSET_FILL );
41 if ( ( pdata->mode & Aspect_POM_Line ) == Aspect_POM_Line )
42 glEnable ( GL_POLYGON_OFFSET_LINE );
44 glDisable( GL_POLYGON_OFFSET_LINE );
46 if ( ( pdata->mode & Aspect_POM_Point ) == Aspect_POM_Point )
47 glEnable ( GL_POLYGON_OFFSET_POINT );
49 glDisable( GL_POLYGON_OFFSET_POINT );
51 glPolygonOffset( pdata->factor, pdata->units );
54 /*----------------------------------------------------------------------*/
56 void OpenGl_Workspace::UpdateMaterial( const int flag )
59 if (AspectFace_set->Context().InteriorStyle == Aspect_IS_HIDDENLINE)
61 /* szvgl - IMPORTANT!!! */
62 static TEL_CONTEXT_FACE hl_context_face;
63 static OpenGl_AspectFace hl_aspect_face;
65 hl_context_face = AspectFace_set->Context();
67 hl_context_face.IntFront.matcol = BackgroundColor();
68 hl_context_face.IntFront.color_mask = 0;
69 hl_context_face.IntBack.color_mask = 0;
71 hl_aspect_face.SetContext(hl_context_face);
72 hl_aspect_face.SetAspectEdge(AspectFace_set->AspectEdge());
74 AspectFace_set = &hl_aspect_face;
78 const OPENGL_SURF_PROP *prop = NULL;
80 if ( flag == TEL_FRONT_MATERIAL )
82 prop = &AspectFace_set->Context().IntFront;
83 face = GL_FRONT_AND_BACK;
87 prop = &AspectFace_set->Context().IntBack;
91 const unsigned int rm = prop->color_mask;
95 // Handling transparency
96 if ( (NamedStatus & OPENGL_NS_2NDPASSDO) == 0 )
98 if ( myUseTransparency && prop->trans != 1.0F )
100 // Render transparent
101 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
103 glDepthMask (GL_FALSE);
108 if ( (NamedStatus & OPENGL_NS_ANTIALIASING) == 0 )
110 glBlendFunc (GL_ONE, GL_ZERO);
111 glDisable (GL_BLEND);
113 glDepthMask (GL_TRUE);
117 static float mAmb[4];
118 static float mDiff[4];
119 static float mSpec[4];
120 static float mEmsv[4];
123 static const float defspeccol[4] = { 1.F, 1.F, 1.F, 1.F };
126 if ( NamedStatus & OPENGL_NS_RESMAT )
129 if( rm & OPENGL_AMBIENT_MASK )
131 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
133 mAmb[0] = prop->amb * c[0];
134 mAmb[1] = prop->amb * c[1];
135 mAmb[2] = prop->amb * c[2];
145 // Diffusion component
146 if( rm & OPENGL_DIFFUSE_MASK )
148 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
150 mDiff[0] = prop->diff * c[0];
151 mDiff[1] = prop->diff * c[1];
152 mDiff[2] = prop->diff * c[2];
162 if (NamedStatus & OPENGL_NS_2NDPASSDO)
164 mDiff[3] = prop->env_reflexion;
168 if (myUseTransparency) mDiff[3] = prop->trans;
169 // If the material reflects the environment scene, the second pass is needed
170 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
173 // Specular component
174 if( rm & OPENGL_SPECULAR_MASK )
176 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
178 mSpec[0] = prop->spec * c[0];
179 mSpec[1] = prop->spec * c[1];
180 mSpec[2] = prop->spec * c[2];
189 // Emissive component
190 if( rm & OPENGL_EMISSIVE_MASK )
192 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
194 mEmsv[0] = prop->emsv * c[0];
195 mEmsv[1] = prop->emsv * c[1];
196 mEmsv[2] = prop->emsv * c[2];
205 /* Coeficient de brillance */
208 glMaterialfv(face, GL_AMBIENT, mAmb );
209 glMaterialfv(face, GL_DIFFUSE, mDiff );
210 glMaterialfv(face, GL_SPECULAR, mSpec);
211 glMaterialfv(face, GL_EMISSION, mEmsv);
212 glMaterialf(face, GL_SHININESS, mShin);
214 NamedStatus &= ~OPENGL_NS_RESMAT;
217 // Set Material Optimize
221 if( rm & OPENGL_AMBIENT_MASK )
223 const float *c = prop->isphysic? prop->ambcol.rgb : prop->matcol.rgb;
225 if (mAmb[0] != prop->amb * c[0] ||
226 mAmb[1] != prop->amb * c[1] ||
227 mAmb[2] != prop->amb * c[2] )
229 mAmb[0] = prop->amb * c[0];
230 mAmb[1] = prop->amb * c[1];
231 mAmb[2] = prop->amb * c[2];
234 glMaterialfv(face, GL_AMBIENT, mAmb);
239 if ( mAmb[0] != 0.F || mAmb[1] != 0.F || mAmb[2] != 0.F )
246 glMaterialfv(face, GL_AMBIENT, mAmb);
250 // Diffusion component
251 if( rm & OPENGL_DIFFUSE_MASK )
253 const float *c = prop->isphysic? prop->difcol.rgb : prop->matcol.rgb;
255 if (mDiff[0] != prop->diff * c[0] ||
256 mDiff[1] != prop->diff * c[1] ||
257 mDiff[2] != prop->diff * c[2] ||
258 mDiff[3] != ((NamedStatus & OPENGL_NS_2NDPASSDO)? prop->env_reflexion : (myUseTransparency? prop->trans : 1.0F)))
260 mDiff[0] = prop->diff * c[0];
261 mDiff[1] = prop->diff * c[1];
262 mDiff[2] = prop->diff * c[2];
265 if (NamedStatus & OPENGL_NS_2NDPASSDO)
267 mDiff[3] = prop->env_reflexion;
271 if (myUseTransparency) mDiff[3] = prop->trans;
272 // If the material reflects the environment scene, the second pass is needed
273 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
276 glMaterialfv(face, GL_DIFFUSE, mDiff );
281 Tfloat newDiff3 = 1.F;
283 if (NamedStatus & OPENGL_NS_2NDPASSDO)
285 newDiff3 = prop->env_reflexion;
289 if (myUseTransparency) newDiff3 = prop->trans;
290 // If the material reflects the environment scene, the second pass is needed
291 if (prop->env_reflexion != 0.0) NamedStatus |= OPENGL_NS_2NDPASSNEED;
294 /* OCC19915: Even if diffuse reflectance is disabled,
295 still trying to update the current transparency if it
296 differs from the previous value */
297 if ( mDiff[0] != 0.F || mDiff[1] != 0.F || mDiff[2] != 0.F || fabs(mDiff[3] - newDiff3) > 0.01F )
304 glMaterialfv(face, GL_DIFFUSE, mDiff);
308 // Specular component
309 if( rm & OPENGL_SPECULAR_MASK )
311 const float *c = prop->isphysic? prop->speccol.rgb : defspeccol;
313 if (mSpec[0] != prop->spec * c[0] ||
314 mSpec[1] != prop->spec * c[1] ||
315 mSpec[2] != prop->spec * c[2])
317 mSpec[0] = prop->spec * c[0];
318 mSpec[1] = prop->spec * c[1];
319 mSpec[2] = prop->spec * c[2];
322 glMaterialfv(face, GL_SPECULAR, mSpec);
327 if ( mSpec[0] != 0.F || mSpec[1] != 0.F || mSpec[2] != 0.F )
334 glMaterialfv(face, GL_SPECULAR, mSpec);
338 // Emissive component
339 if( rm & OPENGL_EMISSIVE_MASK )
341 const float *c = prop->isphysic? prop->emscol.rgb : prop->matcol.rgb;
343 if (mEmsv[0] != prop->emsv * c[0] ||
344 mEmsv[1] != prop->emsv * c[1] ||
345 mEmsv[2] != prop->emsv * c[2])
347 mEmsv[0] = prop->emsv * c[0];
348 mEmsv[1] = prop->emsv * c[1];
349 mEmsv[2] = prop->emsv * c[2];
352 glMaterialfv(face, GL_EMISSION, mEmsv);
357 if ( mEmsv[0] != 0.F || mEmsv[1] != 0.F || mEmsv[2] != 0.F )
364 glMaterialfv(face, GL_EMISSION, mEmsv);
368 // Shining coefficient
369 if( mShin != prop->shine )
372 glMaterialf(face, GL_SHININESS, mShin);
377 /*----------------------------------------------------------------------*/
379 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
381 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
382 AspectLine_set = AnAspect;
383 return AspectLine_old;
386 /*----------------------------------------------------------------------*/
388 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
390 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
391 AspectFace_set = AnAspect;
392 return AspectFace_old;
395 /*----------------------------------------------------------------------*/
397 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
399 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
400 AspectMarker_set = AnAspect;
401 return AspectMarker_old;
404 /*----------------------------------------------------------------------*/
406 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
408 const OpenGl_AspectText *AspectText_old = AspectText_set;
409 AspectText_set = AnAspect;
410 return AspectText_old;
413 /*----------------------------------------------------------------------*/
415 const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix(const OpenGl_Matrix *AMatrix)
417 const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied;
418 ViewMatrix_applied = AMatrix;
421 OpenGl_Transposemat3( &lmat, StructureMatrix_applied );
423 glMatrixMode (GL_MODELVIEW);
425 if ( (NamedStatus & OPENGL_NS_ANIMATION) == 0 )
428 OpenGl_Multiplymat3( &rmat, &lmat, ViewMatrix_applied );
429 glLoadMatrixf((const GLfloat *) rmat.mat);
432 return ViewMatrix_old;
435 /*----------------------------------------------------------------------*/
437 const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix(const OpenGl_Matrix *AMatrix)
439 const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
440 StructureMatrix_applied = AMatrix;
443 OpenGl_Transposemat3( &lmat, AMatrix );
445 glMatrixMode (GL_MODELVIEW);
447 if ( (NamedStatus & OPENGL_NS_ANIMATION) == 0 )
450 OpenGl_Multiplymat3( &rmat, &lmat, ViewMatrix_applied );
451 glLoadMatrixf((const GLfloat *) rmat.mat);
455 glMultMatrixf((const GLfloat *) lmat.mat);
458 return StructureMatrix_old;
461 /*----------------------------------------------------------------------*/
463 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
465 if ( WithApply && (AspectLine_set != AspectLine_applied) )
467 glColor3fv(AspectLine_set->Color().rgb);
469 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
471 myDisplay->SetTypeOfLine(AspectLine_set->Type());
474 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
476 glLineWidth( (GLfloat)AspectLine_set->Width() );
478 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
482 AspectLine_applied = AspectLine_set;
484 return AspectLine_set;
487 /*----------------------------------------------------------------------*/
489 const OpenGl_AspectFace * OpenGl_Workspace::AspectFace(const Standard_Boolean WithApply)
491 if ( WithApply && (AspectFace_set != AspectFace_applied) )
493 const Aspect_InteriorStyle intstyle = AspectFace_set->Context().InteriorStyle;
494 if ( !AspectFace_applied || AspectFace_applied->Context().InteriorStyle != intstyle )
498 case Aspect_IS_EMPTY:
499 case Aspect_IS_HOLLOW:
500 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
503 case Aspect_IS_HATCH:
504 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
505 myDisplay->SetTypeOfHatch(AspectFace_applied? AspectFace_applied->Context().Hatch : TEL_HS_SOLID);
508 case Aspect_IS_SOLID:
509 case Aspect_IS_HIDDENLINE:
510 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
511 glDisable(GL_POLYGON_STIPPLE);
514 case 5: //szvgl - no corresponding enumeration item Aspect_IS_POINT
515 glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
519 if( intstyle == Aspect_IS_HATCH )
521 const Tint hatchstyle = AspectFace_set->Context().Hatch;
522 if( !AspectFace_applied || AspectFace_applied->Context().Hatch != hatchstyle )
524 myDisplay->SetTypeOfHatch(hatchstyle);
527 if ( !ActiveView()->Backfacing() )
529 const Tint mode = AspectFace_set->Context().CullingMode;
530 if( !AspectFace_applied || AspectFace_applied->Context().CullingMode != mode )
532 switch( (TelCullMode)mode )
535 glDisable(GL_CULL_FACE);
539 glCullFace(GL_FRONT);
540 glEnable(GL_CULL_FACE);
545 glEnable(GL_CULL_FACE);
551 // Aspect_POM_None means: do not change current settings
552 if ( ( AspectFace_set->Context().PolygonOffset.mode & Aspect_POM_None ) != Aspect_POM_None )
554 if ( !PolygonOffset_applied ||
555 PolygonOffset_applied->mode != AspectFace_set->Context().PolygonOffset.mode ||
556 PolygonOffset_applied->factor != AspectFace_set->Context().PolygonOffset.factor ||
557 PolygonOffset_applied->units != AspectFace_set->Context().PolygonOffset.units )
559 PolygonOffset_applied = &AspectFace_set->Context().PolygonOffset;
560 TelUpdatePolygonOffsets( PolygonOffset_applied );
564 UpdateMaterial( TEL_FRONT_MATERIAL );
565 if (AspectFace_set->Context().DistinguishingMode == TOn)
566 UpdateMaterial( TEL_BACK_MATERIAL );
568 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
571 if (AspectFace_set->Context().doTextureMap)
573 SetCurrentTexture(AspectFace_set->Context().TexId);
578 AspectFace_applied = AspectFace_set;
580 return AspectFace_set;
583 /*----------------------------------------------------------------------*/
585 const OpenGl_AspectMarker * OpenGl_Workspace::AspectMarker(const Standard_Boolean WithApply)
587 if ( WithApply && (AspectMarker_set != AspectMarker_applied) )
589 AspectMarker_applied = AspectMarker_set;
591 return AspectMarker_set;
594 /*----------------------------------------------------------------------*/
596 const OpenGl_AspectText * OpenGl_Workspace::AspectText(const Standard_Boolean WithApply)
600 Standard_Boolean toApply = Standard_False;
601 if ( AspectText_set != AspectText_applied )
603 if ( !AspectText_applied )
604 toApply = Standard_True;
605 else if ( strcmp( AspectText_set->Font(), AspectText_applied->Font() ) ||
606 ( AspectText_set->FontAspect() != AspectText_applied->FontAspect() ) )
607 toApply = Standard_True;
609 AspectText_applied = AspectText_set;
611 if ( TextParam_set != TextParam_applied )
613 if ( !TextParam_applied )
614 toApply = Standard_True;
615 else if ( TextParam_set->Height != TextParam_applied->Height )
616 toApply = Standard_True;
618 TextParam_applied = TextParam_set;
622 FindFont(AspectText_applied->Font(), AspectText_applied->FontAspect(), TextParam_applied->Height);
625 return AspectText_set;
628 /*----------------------------------------------------------------------*/