1 // File: OpenGl_View.cxx
2 // Created: 20 September 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_GlCore11.hxx>
8 #include <OpenGl_View.hxx>
10 #include <OpenGl_Workspace.hxx>
11 #include <OpenGl_Display.hxx>
13 #include <OpenGl_Display.hxx>
14 #include <OpenGl_Trihedron.hxx>
15 #include <OpenGl_GraduatedTrihedron.hxx>
17 #include <OpenGl_transform_persistence.hxx>
19 #include <GL/glu.h> // gluUnProject()
21 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
22 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
24 /*----------------------------------------------------------------------*/
26 static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
27 static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE };
28 static const Tmatrix3 myDefaultMatrix = { { 1.F, 0.F, 0.F, 0.F }, { 0.F, 1.F, 0.F, 0.F }, { 0.F, 0.F, 1.F, 0.F }, { 0.F, 0.F, 0.F, 1.F } };
29 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
30 static const OPENGL_EXTRA_REP myDefaultExtra =
41 { 0.F, 0.F, 1.F, 1.F },
43 { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F },
59 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
60 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
62 /*----------------------------------------------------------------------*/
64 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
66 mySurfaceDetail(Visual3d_TOD_NONE),
68 myBgTexture(myDefaultBgTexture),
69 myBgGradient(myDefaultBgGradient),
70 //myOrientationMatrix(myDefaultMatrix),
71 //myMappingMatrix(myDefaultMatrix),
72 //shield_indicator = TOn,
73 //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
74 //border_indicator = TOff,
75 //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
76 //active_status = TOn,
77 myZClip(myDefaultZClip),
78 myExtra(myDefaultExtra),
80 myVisualization(AContext.Visualization),
81 myIntShadingMethod(TEL_SM_GOURAUD),
82 myAntiAliasing(Standard_False),
83 myAnimationListIndex(0),
84 myAnimationListReady(Standard_False),
85 myTransPers(&myDefaultTransPers),
86 myIsTransPers(Standard_False),
87 myResetFLIST(Standard_False)
89 // Initialize matrices
90 memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
91 memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3));
94 switch (AContext.Model)
96 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
97 case 3 : /* VISUAL3D_TOM_VERTEX */
98 myIntShadingMethod = TEL_SM_GOURAUD;
101 myIntShadingMethod = TEL_SM_FLAT;
106 /*----------------------------------------------------------------------*/
108 OpenGl_View::~OpenGl_View ()
110 if (myAnimationListIndex)
111 glDeleteLists((GLuint)myAnimationListIndex,1);
113 if ( myBgTexture.TexId != 0 )
114 glDeleteTextures( 1, (GLuint*)&(myBgTexture.TexId) );
117 /*----------------------------------------------------------------------*/
119 void OpenGl_View::SetBackfacing (const Standard_Integer AMode)
121 myBackfacing = AMode;
122 myResetFLIST = Standard_True;
125 /*----------------------------------------------------------------------*/
128 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
132 const int nb_lights = AContext.NbActiveLight;
135 const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]);
136 for ( ; i < nb_lights; i++, alight++ )
140 switch( alight->LightType )
142 case 0 : /* TOLS_AMBIENT */
143 rep.type = TLightAmbient;
144 rep.col.rgb[0] = alight->Color.r;
145 rep.col.rgb[1] = alight->Color.g;
146 rep.col.rgb[2] = alight->Color.b;
149 case 1 : /* TOLS_DIRECTIONAL */
150 rep.type = TLightDirectional;
151 rep.col.rgb[0] = alight->Color.r;
152 rep.col.rgb[1] = alight->Color.g;
153 rep.col.rgb[2] = alight->Color.b;
154 rep.dir[0] = alight->Direction.x;
155 rep.dir[1] = alight->Direction.y;
156 rep.dir[2] = alight->Direction.z;
159 case 2 : /* TOLS_POSITIONAL */
160 rep.type = TLightPositional;
161 rep.col.rgb[0] = alight->Color.r;
162 rep.col.rgb[1] = alight->Color.g;
163 rep.col.rgb[2] = alight->Color.b;
164 rep.pos[0] = alight->Position.x;
165 rep.pos[1] = alight->Position.y;
166 rep.pos[2] = alight->Position.z;
167 rep.atten[0] = alight->Attenuation[0];
168 rep.atten[1] = alight->Attenuation[1];
171 case 3 : /* TOLS_SPOT */
172 rep.type = TLightSpot;
173 rep.col.rgb[0] = alight->Color.r;
174 rep.col.rgb[1] = alight->Color.g;
175 rep.col.rgb[2] = alight->Color.b;
176 rep.pos[0] = alight->Position.x;
177 rep.pos[1] = alight->Position.y;
178 rep.pos[2] = alight->Position.z;
179 rep.dir[0] = alight->Direction.x;
180 rep.dir[1] = alight->Direction.y;
181 rep.dir[2] = alight->Direction.z;
182 rep.shine = alight->Concentration;
183 rep.atten[0] = alight->Attenuation[0];
184 rep.atten[1] = alight->Attenuation[1];
185 rep.angle = alight->Angle;
189 rep.HeadLight = alight->Headlight;
191 myLights.Append(rep);
195 /*----------------------------------------------------------------------*/
198 void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext)
200 // clear clipping planes information
201 myClippingPlanes.Clear();
202 // update information
204 for (; i < AContext.NbActivePlane; i++)
206 const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i];
207 if ( aCPlane.Active && aCPlane.PlaneId > 0 )
209 OPENGL_CLIP_REP aPlane;
210 aPlane.equation[0] = aCPlane.CoefA;
211 aPlane.equation[1] = aCPlane.CoefB;
212 aPlane.equation[2] = aCPlane.CoefC;
213 aPlane.equation[3] = aCPlane.CoefD;
214 myClippingPlanes.Append( aPlane );
219 /*----------------------------------------------------------------------*/
221 //call_togl_setvisualisation
222 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
224 myVisualization = AContext.Visualization;
226 switch (AContext.Model)
228 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
229 case 3 : /* VISUAL3D_TOM_VERTEX */
230 myIntShadingMethod = TEL_SM_GOURAUD;
233 myIntShadingMethod = TEL_SM_FLAT;
238 /*----------------------------------------------------------------------*/
240 //call_togl_cliplimit
241 void OpenGl_View::SetClipLimit (const CALL_DEF_VIEW &ACView)
244 ( ACView.Context.ZClipBackPlane - ACView.Mapping.BackPlaneDistance ) /
245 ( ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance );
246 myZClip.Front.Limit =
247 ( ACView.Context.ZClipFrontPlane - ACView.Mapping.BackPlaneDistance ) /
248 ( ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance );
249 if ( myZClip.Back.Limit < 0.F )
250 myZClip.Back.Limit = 0.F;
251 if ( myZClip.Front.Limit > 1.F )
252 myZClip.Front.Limit = 1.F;
253 if ( myZClip.Back.Limit > myZClip.Front.Limit )
255 myZClip.Back.Limit = 0.F;
256 myZClip.Front.Limit = 1.F;
259 myZClip.Back.IsOn = (ACView.Context.BackZClipping != 0);
260 myZClip.Front.IsOn = (ACView.Context.FrontZClipping != 0);
263 /*----------------------------------------------------------------------*/
265 //call_togl_viewmapping
266 void OpenGl_View::SetMapping (const CALL_DEF_VIEW &ACView)
268 const float ratio = ACView.DefWindow.dy / ACView.DefWindow.dx;
269 const float r_ratio = ACView.DefWindow.dx / ACView.DefWindow.dy;
271 TEL_VIEW_MAPPING Map;
273 Map.window.xmin = ACView.Mapping.WindowLimit.um;
274 Map.window.ymin = ACView.Mapping.WindowLimit.vm;
275 Map.window.xmax = ACView.Mapping.WindowLimit.uM;
276 Map.window.ymax = ACView.Mapping.WindowLimit.vM;
278 Map.viewport.xmin = 0.F;
279 Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio );
280 Map.viewport.ymin = 0.F;
281 Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio );
282 Map.viewport.zmin = 0.F;
283 Map.viewport.zmax = 1.F;
285 /* projection type */
286 switch( ACView.Mapping.Projection )
289 Map.proj = TelPerspective;
292 Map.proj = TelParallel;
296 /* projection reference point */
297 Map.prp[0] = ACView.Mapping.ProjectionReferencePoint.x;
298 Map.prp[1] = ACView.Mapping.ProjectionReferencePoint.y;
299 Map.prp[2] = ACView.Mapping.ProjectionReferencePoint.z;
300 if (!openglDisplay.IsNull() && !openglDisplay->Walkthrough())
301 Map.prp[2] += ACView.Mapping.FrontPlaneDistance;
303 /* view plane distance */
304 Map.vpd = ACView.Mapping.ViewPlaneDistance;
306 /* back plane distance */
307 Map.bpd = ACView.Mapping.BackPlaneDistance;
309 /* front plane distance */
310 Map.fpd = ACView.Mapping.FrontPlaneDistance;
314 /* use user-defined matrix */
315 if ( ACView.Mapping.IsCustomMatrix )
318 for( i = 0; i < 4; i++ )
319 for( j = 0; j < 4; j++ )
320 myMappingMatrix[i][j] = ACView.Mapping.ProjectionMatrix[i][j];
323 TelEvalViewMappingMatrix( &Map, &err_ind, myMappingMatrix );
329 /*----------------------------------------------------------------------*/
331 //call_togl_vieworientation
332 void OpenGl_View::SetOrientation (const CALL_DEF_VIEW &ACView)
337 Tfloat ScaleFactors[3];
339 Vrp[0] = ACView.Orientation.ViewReferencePoint.x;
340 Vrp[1] = ACView.Orientation.ViewReferencePoint.y;
341 Vrp[2] = ACView.Orientation.ViewReferencePoint.z;
343 Vpn[0] = ACView.Orientation.ViewReferencePlane.x;
344 Vpn[1] = ACView.Orientation.ViewReferencePlane.y;
345 Vpn[2] = ACView.Orientation.ViewReferencePlane.z;
347 Vup[0] = ACView.Orientation.ViewReferenceUp.x;
348 Vup[1] = ACView.Orientation.ViewReferenceUp.y;
349 Vup[2] = ACView.Orientation.ViewReferenceUp.z;
351 ScaleFactors[0] = ACView.Orientation.ViewScaleX;
352 ScaleFactors[1] = ACView.Orientation.ViewScaleY;
353 ScaleFactors[2] = ACView.Orientation.ViewScaleZ;
357 // use user-defined matrix
358 if ( ACView.Orientation.IsCustomMatrix )
361 for( i = 0; i < 4; i++ )
362 for( j = 0; j < 4; j++ )
363 myOrientationMatrix[i][j] = ACView.Orientation.ModelViewMatrix[i][j];
366 TelEvalViewOrientationMatrix( Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix );
370 myExtra.vrp[0] = Vrp[0];
371 myExtra.vrp[1] = Vrp[1];
372 myExtra.vrp[2] = Vrp[2];
374 myExtra.vpn[0] = Vpn[0];
375 myExtra.vpn[1] = Vpn[1];
376 myExtra.vpn[2] = Vpn[2];
378 myExtra.vup[0] = Vup[0];
379 myExtra.vup[1] = Vup[1];
380 myExtra.vup[2] = Vup[2];
382 myExtra.scaleFactors[0] = ScaleFactors[0],
383 myExtra.scaleFactors[1] = ScaleFactors[1],
384 myExtra.scaleFactors[2] = ScaleFactors[2];
388 /*----------------------------------------------------------------------*/
390 void OpenGl_View::SetFog (const CALL_DEF_VIEW &ACView, const Standard_Boolean AFlag)
394 myFog.IsOn = Standard_False;
398 myFog.IsOn = Standard_True;
401 (ACView.Context.DepthFrontPlane - ACView.Mapping.BackPlaneDistance) /
402 (ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance);
405 (ACView.Context.DepthBackPlane - ACView.Mapping.BackPlaneDistance) /
406 (ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance);
408 if (myFog.Front < 0.F)
410 else if (myFog.Front > 1.F)
413 if (myFog.Back < 0.F)
415 else if (myFog.Back > 1.F)
418 if (myFog.Back > myFog.Front)
424 myFog.Color.rgb[0] = ACView.DefWindow.Background.r;
425 myFog.Color.rgb[1] = ACView.DefWindow.Background.g;
426 myFog.Color.rgb[2] = ACView.DefWindow.Background.b;
427 myFog.Color.rgb[3] = 1.F;
431 /*----------------------------------------------------------------------*/
433 void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
434 const Standard_Real AScale, const Standard_Boolean AsWireframe)
436 myTrihedron = new OpenGl_Trihedron (APosition, AColor, AScale, AsWireframe);
439 /*----------------------------------------------------------------------*/
441 void OpenGl_View::TriedronErase ()
443 myTrihedron.Nullify();
446 /*----------------------------------------------------------------------*/
448 void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_CGraduatedTrihedron &data)
450 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron(data);
453 /*----------------------------------------------------------------------*/
455 void OpenGl_View::GraduatedTrihedronErase ()
457 myGraduatedTrihedron.Nullify();
460 /*----------------------------------------------------------------------*/
462 //transform_persistence_end
463 void OpenGl_View::EndTransformPersistence ()
468 glMatrixMode (GL_PROJECTION);
470 glMatrixMode (GL_MODELVIEW);
472 myIsTransPers = Standard_False;
476 /*----------------------------------------------------------------------*/
478 //transform_persistence_begin
479 const TEL_TRANSFORM_PERSISTENCE * OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE *ATransPers)
481 const TEL_TRANSFORM_PERSISTENCE *TransPers_old = myTransPers;
483 if ( ATransPers->mode == 0 )
485 EndTransformPersistence();
486 return TransPers_old;
489 myTransPers = ATransPers;
492 glGetIntegerv (GL_VIEWPORT, viewport);
493 GLdouble modelMatrix[4][4];
494 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix );
495 GLdouble projMatrix[4][4];
496 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
498 double W = viewport[2];
499 double H = viewport[3];
504 glMatrixMode (GL_PROJECTION);
506 glMatrixMode (GL_MODELVIEW);
510 myIsTransPers = Standard_True;
512 glMatrixMode( GL_MODELVIEW );
516 glMatrixMode( GL_PROJECTION );
520 /*pre loading matrix*/
521 if( ATransPers->mode & TPF_PAN )
522 /* Annulate translate matrix */
524 modelMatrix[3][0] = 0.;
525 modelMatrix[3][1] = 0.;
526 modelMatrix[3][2] = 0.;
527 projMatrix[3][0] = 0.;
528 projMatrix[3][1] = 0.;
529 projMatrix[3][2] = 0.;
532 if( ATransPers->mode & TPF_ZOOM )
533 /* Annulate zoom matrix */
535 const double scaleX = myExtra.scaleFactors[0];
536 const double scaleY = myExtra.scaleFactors[1];
537 const double scaleZ = myExtra.scaleFactors[2];
539 for (int i = 0; i < 3; ++i)
541 modelMatrix[0][i] /= scaleX;
542 modelMatrix[1][i] /= scaleY;
543 modelMatrix[2][i] /= scaleZ;
546 const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]);
547 projMatrix[0][0] *= det2;
548 projMatrix[1][1] *= det2;
551 if( ATransPers->mode & TPF_ROTATE )
552 /* Annulate rotate matrix */
554 modelMatrix[0][0] = 1.;
555 modelMatrix[1][1] = 1.;
556 modelMatrix[2][2] = 1.;
558 modelMatrix[1][0] = 0.;
559 modelMatrix[2][0] = 0.;
560 modelMatrix[0][1] = 0.;
561 modelMatrix[2][1] = 0.;
562 modelMatrix[0][2] = 0.;
563 modelMatrix[1][2] = 0.;
565 else if( ATransPers->mode & TPF_RELATIVE_ROTATE )
566 /* Initialize relative rotate matrix*/
568 modelMatrix[3][0] = 0.;
569 modelMatrix[3][1] = 0.;
570 modelMatrix[3][2] = 0.;
572 glMatrixMode( GL_MODELVIEW );
574 glTranslated( ATransPers->pointX, ATransPers->pointY, ATransPers->pointZ );
577 if( ATransPers->mode == TPF_TRIEDRON )
579 /* Annulate translation matrix */
580 modelMatrix[3][0] = 0.;
581 modelMatrix[3][1] = 0.;
582 modelMatrix[3][2] = 0.;
584 projMatrix[3][0] = 0.;
585 projMatrix[3][1] = 0.;
586 projMatrix[3][2] = 0.;
588 const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]);
589 projMatrix[0][0] *= det2;
590 projMatrix[1][1] *= det2;
594 glMatrixMode (GL_MODELVIEW);
595 glMultMatrixd ((GLdouble *) modelMatrix);
597 glMatrixMode (GL_PROJECTION);
598 glMultMatrixd ((GLdouble *) projMatrix);
600 /*post loading matrix*/
601 if( ATransPers->mode == TPF_TRIEDRON )
603 glMatrixMode( GL_PROJECTION );
605 double winx, winy, winz;
606 const GLdouble idenMatrix[4][4] = { {1.,0.,0.,0.}, {0.,1.,0.,0.}, {0.,0.,1.,0.}, {0.,0.,0.,1.} };
608 gluUnProject( W/2., H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz);
612 gluUnProject( -W/2., -H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz);
617 if( ATransPers->pointX == 0. && ATransPers->pointY == 0. )
621 else if( ATransPers->pointX > 0. && ATransPers->pointY > 0. )
624 glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. );
626 else if( ATransPers->pointX > 0. && ATransPers->pointY < 0. )
629 glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H2 - H1 + ATransPers->pointZ), 0. );
631 else if( ATransPers->pointX < 0. && ATransPers->pointY > 0. )
634 glTranslated( 0.5*(W2 - W1 + ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. );
636 else if( ATransPers->pointX < 0 && ATransPers->pointY < 0 )
639 glTranslated( -(W1 - W2)/2. + ATransPers->pointZ/2., -(H1-H2)/2. + ATransPers->pointZ/2., 0. );
643 return TransPers_old;
646 /*----------------------------------------------------------------------*/