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_Utils.hxx>
28 #include <OpenGl_Workspace.hxx>
30 #include <Graphic3d_TextureEnv.hxx>
31 #include <Graphic3d_Mat4d.hxx>
33 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
34 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
36 /*----------------------------------------------------------------------*/
38 static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
39 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 };
40 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 } };
41 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
43 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
44 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
45 static const GLdouble THE_IDENTITY_MATRIX[4][4] =
53 /*----------------------------------------------------------------------*/
55 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
56 OpenGl_StateCounter* theCounter)
57 : mySurfaceDetail(Visual3d_TOD_ALL),
59 myBgTexture(myDefaultBgTexture),
60 myBgGradient(myDefaultBgGradient),
61 //shield_indicator = TOn,
62 //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
63 //border_indicator = TOff,
64 //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
65 //active_status = TOn,
66 myZClip(myDefaultZClip),
67 myCamera(AContext.Camera),
70 myGraduatedTrihedron(NULL),
71 myVisualization(AContext.Visualization),
72 myShadingModel ((Visual3d_TypeOfModel )AContext.Model),
73 myAntiAliasing(Standard_False),
74 myTransPers(&myDefaultTransPers),
75 myIsTransPers(Standard_False),
76 myProjectionState (0),
78 myStateCounter (theCounter),
79 myLastLightSourceState (0, 0)
81 myCurrLightSourceState = myStateCounter->Increment();
82 myModificationState = 1; // initial state
85 /*----------------------------------------------------------------------*/
87 OpenGl_View::~OpenGl_View ()
89 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
90 OpenGl_Element::Destroy (NULL, myTrihedron);
91 OpenGl_Element::Destroy (NULL, myGraduatedTrihedron);
94 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
96 if (myTrihedron != NULL)
98 myTrihedron->Release (theCtx.operator->());
100 if (myGraduatedTrihedron != NULL)
102 myGraduatedTrihedron->Release (theCtx.operator->());
105 if (!myTextureEnv.IsNull())
107 theCtx->DelayedRelease (myTextureEnv);
108 myTextureEnv.Nullify();
110 if (myBgTexture.TexId != 0)
112 glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
113 myBgTexture.TexId = 0;
117 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
118 const Handle(Graphic3d_TextureEnv)& theTexture)
120 if (!myTextureEnv.IsNull())
122 theCtx->DelayedRelease (myTextureEnv);
123 myTextureEnv.Nullify();
126 if (theTexture.IsNull())
131 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
132 Handle(Image_PixMap) anImage = theTexture->GetImage();
133 if (!anImage.IsNull())
134 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
136 myModificationState++;
139 void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
141 mySurfaceDetail = theMode;
143 myModificationState++;
146 // =======================================================================
147 // function : SetBackfacing
149 // =======================================================================
150 void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
152 myBackfacing = theMode;
155 // =======================================================================
156 // function : SetLights
158 // =======================================================================
159 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
162 for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
164 myLights.Append (theViewCtx.ActiveLight[aLightIt]);
166 myCurrLightSourceState = myStateCounter->Increment();
169 /*----------------------------------------------------------------------*/
171 //call_togl_setvisualisation
172 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
174 myVisualization = AContext.Visualization;
175 myShadingModel = (Visual3d_TypeOfModel )AContext.Model;
178 /*----------------------------------------------------------------------*/
180 //call_togl_cliplimit
181 void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
183 myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
184 myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
186 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
187 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
190 /*----------------------------------------------------------------------*/
192 void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
193 const Standard_Boolean theFlag)
197 myFog.IsOn = Standard_False;
201 myFog.IsOn = Standard_True;
203 myFog.Front = theCView.Context.DepthFrontPlane;
204 myFog.Back = theCView.Context.DepthBackPlane;
206 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
207 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
208 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
209 myFog.Color.rgb[3] = 1.0f;
213 /*----------------------------------------------------------------------*/
215 void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)& theCtx,
216 const Aspect_TypeOfTriedronPosition thePosition,
217 const Quantity_NameOfColor theColor,
218 const Standard_Real theScale,
219 const Standard_Boolean theAsWireframe)
221 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
222 myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
225 /*----------------------------------------------------------------------*/
227 void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
229 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
232 /*----------------------------------------------------------------------*/
234 void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
235 const Graphic3d_CGraduatedTrihedron& theData)
237 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
238 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
241 /*----------------------------------------------------------------------*/
243 void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
245 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
248 /*----------------------------------------------------------------------*/
250 //transform_persistence_end
251 void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
255 theCtx->WorldViewState.Pop();
256 theCtx->ProjectionState.Pop();
258 theCtx->ApplyProjectionMatrix();
260 myIsTransPers = Standard_False;
264 /*----------------------------------------------------------------------*/
266 //transform_persistence_begin
267 const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
268 const TEL_TRANSFORM_PERSISTENCE* theTransPers)
270 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
271 myTransPers = theTransPers;
272 if (theTransPers->mode == 0)
274 EndTransformPersistence (theCtx);
275 return aTransPersPrev;
279 OpenGl_Mat4d aModelMatrix, aProjMatrix;
280 theCtx->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport);
281 aModelMatrix.Convert (theCtx->ModelWorldState.Current() * theCtx->WorldViewState.Current());
282 aProjMatrix .Convert (theCtx->ProjectionState.Current());
284 const GLdouble aViewportW = (GLdouble )aViewport[2];
285 const GLdouble aViewportH = (GLdouble )aViewport[3];
288 // pop matrix stack - it will be overridden later
289 theCtx->WorldViewState.Pop();
290 theCtx->ProjectionState.Pop();
294 myIsTransPers = Standard_True;
297 // push matrices into stack and reset them
298 theCtx->WorldViewState.Push();
299 theCtx->ProjectionState.Push();
301 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
302 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
303 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
305 OpenGl_Utils::Project<Standard_Real> (theTransPers->pointX,
306 theTransPers->pointY,
307 theTransPers->pointZ,
317 if ((theTransPers->mode & TPF_ZOOM)
318 || (theTransPers->mode == TPF_TRIEDRON))
320 // compute fixed-zoom multiplier
321 // actually function works ugly with TelPerspective!
322 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix.GetValue (1, 1) : aProjMatrix.GetValue (0, 0));
323 aProjMatrix.ChangeValue (0, 0) *= aDet2;
324 aProjMatrix.ChangeValue (1, 1) *= aDet2;
325 aProjMatrix.ChangeValue (2, 2) *= aDet2;
328 // prevent translation - annulate translate matrix
329 if ((theTransPers->mode & TPF_PAN)
330 || (theTransPers->mode == TPF_TRIEDRON))
332 aModelMatrix.SetValue (0, 3, 0.0);
333 aModelMatrix.SetValue (1, 3, 0.0);
334 aModelMatrix.SetValue (2, 3, 0.0);
335 aProjMatrix .SetValue (0, 3, 0.0);
336 aProjMatrix .SetValue (1, 3, 0.0);
337 aProjMatrix .SetValue (2, 3, 0.0);
340 // prevent scaling-on-axis
341 if (theTransPers->mode & TPF_ZOOM)
343 const gp_Pnt anAxialScale = myCamera->AxialScale();
344 const double aScaleX = anAxialScale.X();
345 const double aScaleY = anAxialScale.Y();
346 const double aScaleZ = anAxialScale.Z();
347 for (int i = 0; i < 3; ++i)
349 aModelMatrix.ChangeValue (0, i) /= aScaleX;
350 aModelMatrix.ChangeValue (1, i) /= aScaleY;
351 aModelMatrix.ChangeValue (2, i) /= aScaleZ;
355 // prevent rotating - annulate rotate matrix
356 if (theTransPers->mode & TPF_ROTATE)
358 aModelMatrix.SetValue (0, 0, 1.0);
359 aModelMatrix.SetValue (1, 1, 1.0);
360 aModelMatrix.SetValue (2, 2, 1.0);
362 aModelMatrix.SetValue (1, 0, 0.0);
363 aModelMatrix.SetValue (2, 0, 0.0);
364 aModelMatrix.SetValue (0, 1, 0.0);
365 aModelMatrix.SetValue (2, 1, 0.0);
366 aModelMatrix.SetValue (0, 2, 0.0);
367 aModelMatrix.SetValue (1, 2, 0.0);
370 // load computed matrices
371 theCtx->ModelWorldState.SetIdentity();
372 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
373 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
375 if (theTransPers->mode == TPF_TRIEDRON)
377 // move to the window corner
378 if (theTransPers->pointX != 0.0
379 && theTransPers->pointY != 0.0)
381 GLdouble aW1, aH1, aW2, aH2, aDummy;
383 OpenGl_Mat4d anIdentity;
385 OpenGl_Utils::UnProject<Standard_Real> (0.5 * aViewportW,
395 OpenGl_Utils::UnProject<Standard_Real> (-0.5 * aViewportW,
405 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
406 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
407 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
408 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
410 OpenGl_Utils::Translate<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
411 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
414 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
416 // move to thePoint using saved win-coordinates ('marker-behaviour')
417 GLdouble aMoveX, aMoveY, aMoveZ;
419 OpenGl_Utils::UnProject<Standard_Real> (aWinX,
429 OpenGl_Utils::Translate<Standard_Real> (aModelMatrix, aMoveX, aMoveY, aMoveZ);
430 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
433 theCtx->ApplyProjectionMatrix();
434 return aTransPersPrev;
437 /*----------------------------------------------------------------------*/
439 void OpenGl_View::GetMatrices (OpenGl_Mat4& theOrientation,
440 OpenGl_Mat4& theViewMapping) const
442 theViewMapping = myCamera->ProjectionMatrixF();
443 theOrientation = myCamera->OrientationMatrixF();
445 /*----------------------------------------------------------------------*/