1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <NCollection_Mat4.hxx>
18 #include <OpenGl_Context.hxx>
19 #include <OpenGl_GlCore11.hxx>
20 #include <OpenGl_GraduatedTrihedron.hxx>
21 #include <OpenGl_GraphicDriver.hxx>
22 #include <OpenGl_ShaderManager.hxx>
23 #include <OpenGl_Texture.hxx>
24 #include <OpenGl_Trihedron.hxx>
25 #include <OpenGl_transform_persistence.hxx>
26 #include <OpenGl_View.hxx>
27 #include <OpenGl_Workspace.hxx>
29 #include <Graphic3d_TextureEnv.hxx>
30 #include <Graphic3d_Mat4d.hxx>
32 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
33 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
35 /*----------------------------------------------------------------------*/
37 static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
38 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 };
39 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 } };
40 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
42 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
43 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
44 static const GLdouble THE_IDENTITY_MATRIX[4][4] =
52 /*----------------------------------------------------------------------*/
54 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
55 OpenGl_StateCounter* theCounter)
56 : mySurfaceDetail(Visual3d_TOD_NONE),
58 myBgTexture(myDefaultBgTexture),
59 myBgGradient(myDefaultBgGradient),
60 //shield_indicator = TOn,
61 //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
62 //border_indicator = TOff,
63 //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
64 //active_status = TOn,
65 myZClip(myDefaultZClip),
66 myCamera(AContext.Camera),
69 myGraduatedTrihedron(NULL),
70 myVisualization(AContext.Visualization),
71 myIntShadingMethod(TEL_SM_GOURAUD),
72 myAntiAliasing(Standard_False),
73 myTransPers(&myDefaultTransPers),
74 myIsTransPers(Standard_False),
75 myProjectionState (0),
77 myStateCounter (theCounter),
78 myLastLightSourceState (0, 0)
82 switch (AContext.Model)
84 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
85 case 3 : /* VISUAL3D_TOM_VERTEX */
86 myIntShadingMethod = TEL_SM_GOURAUD;
89 myIntShadingMethod = TEL_SM_FLAT;
93 myCurrLightSourceState = myStateCounter->Increment();
95 myModificationState = 1; // initial state
98 /*----------------------------------------------------------------------*/
100 OpenGl_View::~OpenGl_View ()
102 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
105 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
107 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
108 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
110 if (!myTextureEnv.IsNull())
112 theCtx->DelayedRelease (myTextureEnv);
113 myTextureEnv.Nullify();
115 if (myBgTexture.TexId != 0)
117 glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
118 myBgTexture.TexId = 0;
122 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
123 const Handle(Graphic3d_TextureEnv)& theTexture)
125 if (!myTextureEnv.IsNull())
127 theCtx->DelayedRelease (myTextureEnv);
128 myTextureEnv.Nullify();
131 if (theTexture.IsNull())
136 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
137 Handle(Image_PixMap) anImage = theTexture->GetImage();
138 if (!anImage.IsNull())
139 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
141 myModificationState++;
144 void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
146 mySurfaceDetail = theMode;
148 myModificationState++;
151 // =======================================================================
152 // function : SetBackfacing
154 // =======================================================================
155 void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
157 myBackfacing = theMode;
160 // =======================================================================
161 // function : SetLights
163 // =======================================================================
164 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
167 for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
169 myLights.Append (theViewCtx.ActiveLight[aLightIt]);
171 myCurrLightSourceState = myStateCounter->Increment();
174 /*----------------------------------------------------------------------*/
176 //call_togl_setvisualisation
177 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
179 myVisualization = AContext.Visualization;
181 switch (AContext.Model)
183 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
184 case 3 : /* VISUAL3D_TOM_VERTEX */
185 myIntShadingMethod = TEL_SM_GOURAUD;
188 myIntShadingMethod = TEL_SM_FLAT;
193 /*----------------------------------------------------------------------*/
195 //call_togl_cliplimit
196 void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
198 myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
199 myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
201 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
202 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
205 /*----------------------------------------------------------------------*/
207 void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
208 const Standard_Boolean theFlag)
212 myFog.IsOn = Standard_False;
216 myFog.IsOn = Standard_True;
218 myFog.Front = theCView.Context.DepthFrontPlane;
219 myFog.Back = theCView.Context.DepthBackPlane;
221 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
222 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
223 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
224 myFog.Color.rgb[3] = 1.0f;
228 /*----------------------------------------------------------------------*/
230 void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)& theCtx,
231 const Aspect_TypeOfTriedronPosition thePosition,
232 const Quantity_NameOfColor theColor,
233 const Standard_Real theScale,
234 const Standard_Boolean theAsWireframe)
236 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
237 myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
240 /*----------------------------------------------------------------------*/
242 void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
244 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
247 /*----------------------------------------------------------------------*/
249 void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
250 const Graphic3d_CGraduatedTrihedron& theData)
252 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
253 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
256 /*----------------------------------------------------------------------*/
258 void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
260 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
263 /*----------------------------------------------------------------------*/
265 //transform_persistence_end
266 void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
270 #if !defined(GL_ES_VERSION_2_0)
272 glMatrixMode (GL_PROJECTION);
274 glMatrixMode (GL_MODELVIEW);
276 myIsTransPers = Standard_False;
278 // Note: the approach of accessing OpenGl matrices is used now since the matrix
279 // manipulation are made with help of OpenGl methods. This might be replaced by
280 // direct computation of matrices by OCC subroutines.
281 Tmatrix3 aResultWorldView;
282 glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
284 Tmatrix3 aResultProjection;
285 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
287 // Set OCCT state uniform variables
288 theCtx->ShaderManager()->RevertWorldViewStateTo (&aResultWorldView);
289 theCtx->ShaderManager()->RevertProjectionStateTo (&aResultProjection);
294 /*----------------------------------------------------------------------*/
296 //transform_persistence_begin
297 const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
298 const TEL_TRANSFORM_PERSISTENCE* theTransPers)
300 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
301 myTransPers = theTransPers;
302 if (theTransPers->mode == 0)
304 EndTransformPersistence (theCtx);
305 return aTransPersPrev;
308 #if !defined(GL_ES_VERSION_2_0)
310 GLdouble aModelMatrix[4][4];
311 GLdouble aProjMatrix[4][4];
312 glGetIntegerv (GL_VIEWPORT, aViewport);
313 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
314 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble *)aProjMatrix);
316 const GLdouble aViewportW = (GLdouble )aViewport[2];
317 const GLdouble aViewportH = (GLdouble )aViewport[3];
321 // pop matrix stack - it will be overridden later
322 glMatrixMode (GL_PROJECTION);
324 glMatrixMode (GL_MODELVIEW);
329 myIsTransPers = Standard_True;
332 // push matrices into stack and reset them
333 glMatrixMode (GL_MODELVIEW);
337 glMatrixMode (GL_PROJECTION);
341 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
342 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
343 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
345 gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
346 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
347 &aWinX, &aWinY, &aWinZ);
351 if ((theTransPers->mode & TPF_ZOOM)
352 || (theTransPers->mode == TPF_TRIEDRON))
354 // compute fixed-zoom multiplier
355 // actually function works ugly with TelPerspective!
356 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix[1][1] : aProjMatrix[0][0]);
357 aProjMatrix[0][0] *= aDet2;
358 aProjMatrix[1][1] *= aDet2;
359 aProjMatrix[2][2] *= aDet2;
362 // prevent translation - annulate translate matrix
363 if ((theTransPers->mode & TPF_PAN)
364 || (theTransPers->mode == TPF_TRIEDRON))
366 aModelMatrix[3][0] = 0.0;
367 aModelMatrix[3][1] = 0.0;
368 aModelMatrix[3][2] = 0.0;
369 aProjMatrix [3][0] = 0.0;
370 aProjMatrix [3][1] = 0.0;
371 aProjMatrix [3][2] = 0.0;
374 // prevent scaling-on-axis
375 if (theTransPers->mode & TPF_ZOOM)
377 const gp_Pnt anAxialScale = myCamera->AxialScale();
378 const double aScaleX = anAxialScale.X();
379 const double aScaleY = anAxialScale.Y();
380 const double aScaleZ = anAxialScale.Z();
381 for (int i = 0; i < 3; ++i)
383 aModelMatrix[0][i] /= aScaleX;
384 aModelMatrix[1][i] /= aScaleY;
385 aModelMatrix[2][i] /= aScaleZ;
389 // prevent rotating - annulate rotate matrix
390 if (theTransPers->mode & TPF_ROTATE)
392 aModelMatrix[0][0] = 1.0;
393 aModelMatrix[1][1] = 1.0;
394 aModelMatrix[2][2] = 1.0;
396 aModelMatrix[1][0] = 0.0;
397 aModelMatrix[2][0] = 0.0;
398 aModelMatrix[0][1] = 0.0;
399 aModelMatrix[2][1] = 0.0;
400 aModelMatrix[0][2] = 0.0;
401 aModelMatrix[1][2] = 0.0;
404 // load computed matrices
405 glMatrixMode (GL_MODELVIEW);
406 glMultMatrixd ((GLdouble* )aModelMatrix);
408 glMatrixMode (GL_PROJECTION);
409 glMultMatrixd ((GLdouble* )aProjMatrix);
411 if (theTransPers->mode == TPF_TRIEDRON)
413 // move to the window corner
414 if (theTransPers->pointX != 0.0
415 && theTransPers->pointY != 0.0)
417 GLdouble aW1, aH1, aW2, aH2, aDummy;
418 glMatrixMode (GL_PROJECTION);
419 gluUnProject ( 0.5 * aViewportW, 0.5 * aViewportH, 0.0,
420 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
421 &aW1, &aH1, &aDummy);
422 gluUnProject (-0.5 * aViewportW, -0.5 * aViewportH, 0.0,
423 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
424 &aW2, &aH2, &aDummy);
426 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
427 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
428 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
429 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
430 theCtx->core11->glTranslated (aMoveX, aMoveY, 0.0);
433 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
435 // move to thePoint using saved win-coordinates ('marker-behaviour')
436 GLdouble aMoveX, aMoveY, aMoveZ;
437 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
438 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble* )aProjMatrix);
439 gluUnProject (aWinX, aWinY, aWinZ,
440 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
441 &aMoveX, &aMoveY, &aMoveZ);
443 glMatrixMode (GL_MODELVIEW);
444 theCtx->core11->glTranslated (aMoveX, aMoveY, aMoveZ);
447 // Note: the approach of accessing OpenGl matrices is used now since the matrix
448 // manipulation are made with help of OpenGl methods. This might be replaced by
449 // direct computation of matrices by OCC subroutines.
450 Tmatrix3 aResultWorldView;
451 glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
453 Tmatrix3 aResultProjection;
454 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
456 // Set OCCT state uniform variables
457 theCtx->ShaderManager()->UpdateWorldViewStateTo (&aResultWorldView);
458 theCtx->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
460 return aTransPersPrev;
463 /*----------------------------------------------------------------------*/
465 void OpenGl_View::GetMatrices (TColStd_Array2OfReal& theMatOrient,
466 TColStd_Array2OfReal& theMatMapping) const
468 const Graphic3d_Mat4d& aProj = myCamera->ProjectionMatrix();
469 const Graphic3d_Mat4d& aOrient = myCamera->OrientationMatrix();
471 for (Standard_Integer aRow = 0; aRow < 4; ++aRow)
473 for (Standard_Integer aCol = 0; aCol < 4; ++aCol)
475 theMatOrient (aRow, aCol) = aOrient.GetValue (aRow, aCol);
476 theMatMapping (aRow, aCol) = aProj .GetValue (aRow, aCol);
480 /*----------------------------------------------------------------------*/