1 // Created on: 2011-09-20
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.
20 #include <OpenGl_GlCore11.hxx>
22 #include <OpenGl_View.hxx>
23 #include <OpenGl_Context.hxx>
24 #include <OpenGl_Workspace.hxx>
25 #include <OpenGl_Display.hxx>
27 #include <OpenGl_Texture.hxx>
28 #include <OpenGl_Trihedron.hxx>
29 #include <OpenGl_GraduatedTrihedron.hxx>
31 #include <OpenGl_transform_persistence.hxx>
33 #include <Graphic3d_TextureEnv.hxx>
35 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
36 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
38 /*----------------------------------------------------------------------*/
40 static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
41 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 };
42 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 } };
43 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
44 static const OPENGL_EXTRA_REP myDefaultExtra =
55 { 0.F, 0.F, 1.F, 1.F },
57 { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F },
73 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
74 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
75 static const GLdouble THE_IDENTITY_MATRIX[4][4] =
83 /*----------------------------------------------------------------------*/
85 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
86 : mySurfaceDetail(Visual3d_TOD_NONE),
88 myBgTexture(myDefaultBgTexture),
89 myBgGradient(myDefaultBgGradient),
90 //myOrientationMatrix(myDefaultMatrix),
91 //myMappingMatrix(myDefaultMatrix),
92 //shield_indicator = TOn,
93 //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
94 //border_indicator = TOff,
95 //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
96 //active_status = TOn,
97 myZClip(myDefaultZClip),
98 myExtra(myDefaultExtra),
100 myVisualization(AContext.Visualization),
101 myIntShadingMethod(TEL_SM_GOURAUD),
102 myAntiAliasing(Standard_False),
103 myTransPers(&myDefaultTransPers),
104 myIsTransPers(Standard_False),
106 myGraduatedTrihedron(NULL)
108 // Initialize matrices
109 memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
110 memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3));
113 switch (AContext.Model)
115 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
116 case 3 : /* VISUAL3D_TOM_VERTEX */
117 myIntShadingMethod = TEL_SM_GOURAUD;
120 myIntShadingMethod = TEL_SM_FLAT;
125 /*----------------------------------------------------------------------*/
127 OpenGl_View::~OpenGl_View ()
129 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
132 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
134 OpenGl_Element::Destroy (theCtx, myTrihedron);
135 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
137 if (!myTextureEnv.IsNull())
139 theCtx->DelayedRelease (myTextureEnv);
140 myTextureEnv.Nullify();
142 if (myBgTexture.TexId != 0)
144 glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
145 myBgTexture.TexId = 0;
149 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
150 const Handle(Graphic3d_TextureEnv)& theTexture)
152 if (!myTextureEnv.IsNull())
154 theCtx->DelayedRelease (myTextureEnv);
155 myTextureEnv.Nullify();
158 if (theTexture.IsNull())
163 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
164 Handle(Image_PixMap) anImage = theTexture->GetImage();
165 if( !anImage.IsNull())
166 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
169 /*----------------------------------------------------------------------*/
171 void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
173 myBackfacing = theMode;
176 /*----------------------------------------------------------------------*/
179 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
183 const int nb_lights = AContext.NbActiveLight;
186 const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]);
187 for ( ; i < nb_lights; i++, alight++ )
191 switch( alight->LightType )
193 case 0 : /* TOLS_AMBIENT */
194 rep.type = TLightAmbient;
195 rep.col.rgb[0] = alight->Color.r;
196 rep.col.rgb[1] = alight->Color.g;
197 rep.col.rgb[2] = alight->Color.b;
200 case 1 : /* TOLS_DIRECTIONAL */
201 rep.type = TLightDirectional;
202 rep.col.rgb[0] = alight->Color.r;
203 rep.col.rgb[1] = alight->Color.g;
204 rep.col.rgb[2] = alight->Color.b;
205 rep.dir[0] = alight->Direction.x;
206 rep.dir[1] = alight->Direction.y;
207 rep.dir[2] = alight->Direction.z;
210 case 2 : /* TOLS_POSITIONAL */
211 rep.type = TLightPositional;
212 rep.col.rgb[0] = alight->Color.r;
213 rep.col.rgb[1] = alight->Color.g;
214 rep.col.rgb[2] = alight->Color.b;
215 rep.pos[0] = alight->Position.x;
216 rep.pos[1] = alight->Position.y;
217 rep.pos[2] = alight->Position.z;
218 rep.atten[0] = alight->Attenuation[0];
219 rep.atten[1] = alight->Attenuation[1];
222 case 3 : /* TOLS_SPOT */
223 rep.type = TLightSpot;
224 rep.col.rgb[0] = alight->Color.r;
225 rep.col.rgb[1] = alight->Color.g;
226 rep.col.rgb[2] = alight->Color.b;
227 rep.pos[0] = alight->Position.x;
228 rep.pos[1] = alight->Position.y;
229 rep.pos[2] = alight->Position.z;
230 rep.dir[0] = alight->Direction.x;
231 rep.dir[1] = alight->Direction.y;
232 rep.dir[2] = alight->Direction.z;
233 rep.shine = alight->Concentration;
234 rep.atten[0] = alight->Attenuation[0];
235 rep.atten[1] = alight->Attenuation[1];
236 rep.angle = alight->Angle;
240 rep.HeadLight = alight->Headlight;
242 myLights.Append(rep);
246 /*----------------------------------------------------------------------*/
249 void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext)
251 // clear clipping planes information
252 myClippingPlanes.Clear();
253 // update information
255 for (; i < AContext.NbActivePlane; i++)
257 const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i];
258 if ( aCPlane.Active && aCPlane.PlaneId > 0 )
260 OPENGL_CLIP_REP aPlane;
261 aPlane.equation[0] = aCPlane.CoefA;
262 aPlane.equation[1] = aCPlane.CoefB;
263 aPlane.equation[2] = aCPlane.CoefC;
264 aPlane.equation[3] = aCPlane.CoefD;
265 myClippingPlanes.Append( aPlane );
270 /*----------------------------------------------------------------------*/
272 //call_togl_setvisualisation
273 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
275 myVisualization = AContext.Visualization;
277 switch (AContext.Model)
279 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
280 case 3 : /* VISUAL3D_TOM_VERTEX */
281 myIntShadingMethod = TEL_SM_GOURAUD;
284 myIntShadingMethod = TEL_SM_FLAT;
289 /*----------------------------------------------------------------------*/
291 //call_togl_cliplimit
292 void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
295 (theCView.Context.ZClipBackPlane - theCView.Mapping.BackPlaneDistance) /
296 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
297 myZClip.Front.Limit =
298 (theCView.Context.ZClipFrontPlane - theCView.Mapping.BackPlaneDistance) /
299 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
300 if (myZClip.Back.Limit < 0.0f)
301 myZClip.Back.Limit = 0.0f;
302 if (myZClip.Front.Limit > 1.0f)
303 myZClip.Front.Limit = 1.0f;
304 if (myZClip.Back.Limit > myZClip.Front.Limit)
306 myZClip.Back.Limit = 0.0f;
307 myZClip.Front.Limit = 1.0f;
310 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
311 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
314 /*----------------------------------------------------------------------*/
316 //call_togl_viewmapping
317 void OpenGl_View::SetMapping (const Graphic3d_CView& theCView)
319 const float ratio = theCView.DefWindow.dy / theCView.DefWindow.dx;
320 const float r_ratio = theCView.DefWindow.dx / theCView.DefWindow.dy;
322 TEL_VIEW_MAPPING Map;
324 Map.window.xmin = theCView.Mapping.WindowLimit.um;
325 Map.window.ymin = theCView.Mapping.WindowLimit.vm;
326 Map.window.xmax = theCView.Mapping.WindowLimit.uM;
327 Map.window.ymax = theCView.Mapping.WindowLimit.vM;
329 Map.viewport.xmin = 0.F;
330 Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio );
331 Map.viewport.ymin = 0.F;
332 Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio );
333 Map.viewport.zmin = 0.F;
334 Map.viewport.zmax = 1.F;
337 switch (theCView.Mapping.Projection)
340 Map.proj = TelPerspective;
343 Map.proj = TelParallel;
347 // projection reference point
348 Map.prp[0] = theCView.Mapping.ProjectionReferencePoint.x;
349 Map.prp[1] = theCView.Mapping.ProjectionReferencePoint.y;
350 Map.prp[2] = theCView.Mapping.ProjectionReferencePoint.z;
351 if (!openglDisplay.IsNull() && !openglDisplay->Walkthrough())
352 Map.prp[2] += theCView.Mapping.FrontPlaneDistance;
354 // view plane distance
355 Map.vpd = theCView.Mapping.ViewPlaneDistance;
357 // back plane distance
358 Map.bpd = theCView.Mapping.BackPlaneDistance;
360 // front plane distance
361 Map.fpd = theCView.Mapping.FrontPlaneDistance;
365 // use user-defined matrix
366 if (theCView.Mapping.IsCustomMatrix)
369 for( i = 0; i < 4; i++ )
370 for( j = 0; j < 4; j++ )
371 myMappingMatrix[i][j] = theCView.Mapping.ProjectionMatrix[i][j];
374 TelEvalViewMappingMatrix( &Map, &err_ind, myMappingMatrix );
380 /*----------------------------------------------------------------------*/
382 //call_togl_vieworientation
383 void OpenGl_View::SetOrientation (const Graphic3d_CView& theCView)
388 Tfloat ScaleFactors[3];
390 Vrp[0] = theCView.Orientation.ViewReferencePoint.x;
391 Vrp[1] = theCView.Orientation.ViewReferencePoint.y;
392 Vrp[2] = theCView.Orientation.ViewReferencePoint.z;
394 Vpn[0] = theCView.Orientation.ViewReferencePlane.x;
395 Vpn[1] = theCView.Orientation.ViewReferencePlane.y;
396 Vpn[2] = theCView.Orientation.ViewReferencePlane.z;
398 Vup[0] = theCView.Orientation.ViewReferenceUp.x;
399 Vup[1] = theCView.Orientation.ViewReferenceUp.y;
400 Vup[2] = theCView.Orientation.ViewReferenceUp.z;
402 ScaleFactors[0] = theCView.Orientation.ViewScaleX;
403 ScaleFactors[1] = theCView.Orientation.ViewScaleY;
404 ScaleFactors[2] = theCView.Orientation.ViewScaleZ;
408 // use user-defined matrix
409 if (theCView.Orientation.IsCustomMatrix)
412 for( i = 0; i < 4; i++ )
413 for( j = 0; j < 4; j++ )
414 myOrientationMatrix[i][j] = theCView.Orientation.ModelViewMatrix[i][j];
418 TelEvalViewOrientationMatrix (Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix);
423 myExtra.vrp[0] = Vrp[0];
424 myExtra.vrp[1] = Vrp[1];
425 myExtra.vrp[2] = Vrp[2];
427 myExtra.vpn[0] = Vpn[0];
428 myExtra.vpn[1] = Vpn[1];
429 myExtra.vpn[2] = Vpn[2];
431 myExtra.vup[0] = Vup[0];
432 myExtra.vup[1] = Vup[1];
433 myExtra.vup[2] = Vup[2];
435 myExtra.scaleFactors[0] = ScaleFactors[0],
436 myExtra.scaleFactors[1] = ScaleFactors[1],
437 myExtra.scaleFactors[2] = ScaleFactors[2];
441 /*----------------------------------------------------------------------*/
443 void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
444 const Standard_Boolean theFlag)
448 myFog.IsOn = Standard_False;
452 myFog.IsOn = Standard_True;
455 (theCView.Context.DepthFrontPlane - theCView.Mapping.BackPlaneDistance) /
456 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
459 (theCView.Context.DepthBackPlane - theCView.Mapping.BackPlaneDistance) /
460 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
462 if (myFog.Front < 0.F)
464 else if (myFog.Front > 1.F)
467 if (myFog.Back < 0.F)
469 else if (myFog.Back > 1.F)
472 if (myFog.Back > myFog.Front)
478 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
479 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
480 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
481 myFog.Color.rgb[3] = 1.0f;
485 /*----------------------------------------------------------------------*/
487 void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)& theCtx,
488 const Aspect_TypeOfTriedronPosition thePosition,
489 const Quantity_NameOfColor theColor,
490 const Standard_Real theScale,
491 const Standard_Boolean theAsWireframe)
493 OpenGl_Element::Destroy (theCtx, myTrihedron);
494 myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
497 /*----------------------------------------------------------------------*/
499 void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
501 OpenGl_Element::Destroy (theCtx, myTrihedron);
504 /*----------------------------------------------------------------------*/
506 void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
507 const Graphic3d_CGraduatedTrihedron& theData)
509 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
510 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
513 /*----------------------------------------------------------------------*/
515 void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
517 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
520 /*----------------------------------------------------------------------*/
522 //transform_persistence_end
523 void OpenGl_View::EndTransformPersistence()
528 glMatrixMode (GL_PROJECTION);
530 glMatrixMode (GL_MODELVIEW);
532 myIsTransPers = Standard_False;
536 /*----------------------------------------------------------------------*/
538 //transform_persistence_begin
539 const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE* theTransPers)
541 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
542 myTransPers = theTransPers;
543 if (theTransPers->mode == 0)
545 EndTransformPersistence();
546 return aTransPersPrev;
550 GLdouble aModelMatrix[4][4];
551 GLdouble aProjMatrix[4][4];
552 glGetIntegerv (GL_VIEWPORT, aViewport);
553 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
554 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble *)aProjMatrix);
555 const GLdouble aViewportW = (GLdouble )aViewport[2];
556 const GLdouble aViewportH = (GLdouble )aViewport[3];
560 // pop matrix stack - it will be overridden later
561 glMatrixMode (GL_PROJECTION);
563 glMatrixMode (GL_MODELVIEW);
568 myIsTransPers = Standard_True;
571 // push matrices into stack and reset them
572 glMatrixMode (GL_MODELVIEW);
576 glMatrixMode (GL_PROJECTION);
580 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
581 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
582 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
584 gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
585 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
586 &aWinX, &aWinY, &aWinZ);
590 if ((theTransPers->mode & TPF_ZOOM)
591 || (theTransPers->mode == TPF_TRIEDRON))
593 // compute fixed-zoom multiplier
594 // actually function works ugly with TelPerspective!
595 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix[1][1] : aProjMatrix[0][0]);
596 aProjMatrix[0][0] *= aDet2;
597 aProjMatrix[1][1] *= aDet2;
598 aProjMatrix[2][2] *= aDet2;
601 // prevent translation - annulate translate matrix
602 if ((theTransPers->mode & TPF_PAN)
603 || (theTransPers->mode == TPF_TRIEDRON))
605 aModelMatrix[3][0] = 0.0;
606 aModelMatrix[3][1] = 0.0;
607 aModelMatrix[3][2] = 0.0;
608 aProjMatrix [3][0] = 0.0;
609 aProjMatrix [3][1] = 0.0;
610 aProjMatrix [3][2] = 0.0;
613 // prevent scaling-on-axis
614 if (theTransPers->mode & TPF_ZOOM)
616 const double aScaleX = myExtra.scaleFactors[0];
617 const double aScaleY = myExtra.scaleFactors[1];
618 const double aScaleZ = myExtra.scaleFactors[2];
619 for (int i = 0; i < 3; ++i)
621 aModelMatrix[0][i] /= aScaleX;
622 aModelMatrix[1][i] /= aScaleY;
623 aModelMatrix[2][i] /= aScaleZ;
627 // prevent rotating - annulate rotate matrix
628 if (theTransPers->mode & TPF_ROTATE)
630 aModelMatrix[0][0] = 1.0;
631 aModelMatrix[1][1] = 1.0;
632 aModelMatrix[2][2] = 1.0;
634 aModelMatrix[1][0] = 0.0;
635 aModelMatrix[2][0] = 0.0;
636 aModelMatrix[0][1] = 0.0;
637 aModelMatrix[2][1] = 0.0;
638 aModelMatrix[0][2] = 0.0;
639 aModelMatrix[1][2] = 0.0;
642 // load computed matrices
643 glMatrixMode (GL_MODELVIEW);
644 glMultMatrixd ((GLdouble* )aModelMatrix);
646 glMatrixMode (GL_PROJECTION);
647 glMultMatrixd ((GLdouble* )aProjMatrix);
649 if (theTransPers->mode == TPF_TRIEDRON)
651 // move to the window corner
652 if (theTransPers->pointX != 0.0
653 && theTransPers->pointY != 0.0)
655 GLdouble aW1, aH1, aW2, aH2, aDummy;
656 glMatrixMode (GL_PROJECTION);
657 gluUnProject ( 0.5 * aViewportW, 0.5 * aViewportH, 0.0,
658 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
659 &aW1, &aH1, &aDummy);
660 gluUnProject (-0.5 * aViewportW, -0.5 * aViewportH, 0.0,
661 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
662 &aW2, &aH2, &aDummy);
663 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
664 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
665 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
666 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
667 glTranslated (aMoveX, aMoveY, 0.0);
670 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
672 // move to thePoint using saved win-coordinates ('marker-behaviour')
673 GLdouble aMoveX, aMoveY, aMoveZ;
674 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
675 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble* )aProjMatrix);
676 gluUnProject (aWinX, aWinY, aWinZ,
677 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
678 &aMoveX, &aMoveY, &aMoveZ);
680 glMatrixMode (GL_MODELVIEW);
681 glTranslated (aMoveX, aMoveY, aMoveZ);
684 return aTransPersPrev;