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 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 } };
39 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
41 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
42 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
43 static const GLdouble THE_IDENTITY_MATRIX[4][4] =
51 /*----------------------------------------------------------------------*/
53 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
54 OpenGl_StateCounter* theCounter)
55 : mySurfaceDetail(Visual3d_TOD_ALL),
57 //shield_indicator = TOn,
58 //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
59 //border_indicator = TOff,
60 //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
61 //active_status = TOn,
62 myZClip(myDefaultZClip),
63 myCamera(AContext.Camera),
65 myToShowTrihedron (false),
66 myToShowGradTrihedron (false),
67 myVisualization(AContext.Visualization),
68 myShadingModel ((Visual3d_TypeOfModel )AContext.Model),
69 myAntiAliasing(Standard_False),
70 myTransPers(&myDefaultTransPers),
71 myIsTransPers(Standard_False),
72 myProjectionState (0),
74 myStateCounter (theCounter),
75 myLastLightSourceState (0, 0),
76 myModificationState (1), // initial state
77 myTextureParams (new OpenGl_AspectFace()),
78 myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
79 myBgTextureArray (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE))
81 myCurrLightSourceState = myStateCounter->Increment();
84 /*----------------------------------------------------------------------*/
86 OpenGl_View::~OpenGl_View()
88 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
89 OpenGl_Element::Destroy (NULL, myBgGradientArray);
90 OpenGl_Element::Destroy (NULL, myBgTextureArray);
91 OpenGl_Element::Destroy (NULL, myTextureParams);
94 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
96 myTrihedron .Release (theCtx.operator->());
97 myGraduatedTrihedron.Release (theCtx.operator->());
99 if (!myTextureEnv.IsNull())
101 theCtx->DelayedRelease (myTextureEnv);
102 myTextureEnv.Nullify();
105 if (myTextureParams != NULL)
107 myTextureParams->Release (theCtx.operator->());
109 if (myBgGradientArray != NULL)
111 myBgGradientArray->Release (theCtx.operator->());
113 if (myBgTextureArray != NULL)
115 myBgTextureArray->Release (theCtx.operator->());
119 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
120 const Handle(Graphic3d_TextureEnv)& theTexture)
122 if (!myTextureEnv.IsNull())
124 theCtx->DelayedRelease (myTextureEnv);
125 myTextureEnv.Nullify();
128 if (theTexture.IsNull())
133 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
134 Handle(Image_PixMap) anImage = theTexture->GetImage();
135 if (!anImage.IsNull())
136 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
138 myModificationState++;
141 void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
143 mySurfaceDetail = theMode;
145 myModificationState++;
148 // =======================================================================
149 // function : SetBackfacing
151 // =======================================================================
152 void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
154 myBackfacing = theMode;
157 // =======================================================================
158 // function : SetLights
160 // =======================================================================
161 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
164 for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
166 myLights.Append (theViewCtx.ActiveLight[aLightIt]);
168 myCurrLightSourceState = myStateCounter->Increment();
171 /*----------------------------------------------------------------------*/
173 //call_togl_setvisualisation
174 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
176 myVisualization = AContext.Visualization;
177 myShadingModel = (Visual3d_TypeOfModel )AContext.Model;
180 /*----------------------------------------------------------------------*/
182 //call_togl_cliplimit
183 void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
185 myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
186 myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
188 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
189 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
192 /*----------------------------------------------------------------------*/
194 void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
195 const Standard_Boolean theFlag)
199 myFog.IsOn = Standard_False;
203 myFog.IsOn = Standard_True;
205 myFog.Front = theCView.Context.DepthFrontPlane;
206 myFog.Back = theCView.Context.DepthBackPlane;
208 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
209 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
210 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
211 myFog.Color.rgb[3] = 1.0f;
215 /*----------------------------------------------------------------------*/
217 void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
218 const Quantity_NameOfColor theColor,
219 const Standard_Real theScale,
220 const Standard_Boolean theAsWireframe)
222 myToShowTrihedron = true;
223 myTrihedron.SetWireframe (theAsWireframe);
224 myTrihedron.SetPosition (thePosition);
225 myTrihedron.SetScale (theScale);
226 myTrihedron.SetLabelsColor (theColor);
229 /*----------------------------------------------------------------------*/
231 void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
233 myToShowTrihedron = false;
234 myTrihedron.Release (theCtx.operator->());
237 /*----------------------------------------------------------------------*/
239 void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
240 const Graphic3d_GraduatedTrihedron& theData)
242 myToShowGradTrihedron = true;
243 myGraduatedTrihedron.SetValues (theCtx, theData);
246 /*----------------------------------------------------------------------*/
248 void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
250 myToShowGradTrihedron = false;
251 myGraduatedTrihedron.Release (theCtx.operator->());
254 /*----------------------------------------------------------------------*/
256 //transform_persistence_end
257 void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
261 theCtx->WorldViewState.Pop();
262 theCtx->ProjectionState.Pop();
264 theCtx->ApplyProjectionMatrix();
266 myIsTransPers = Standard_False;
270 /*----------------------------------------------------------------------*/
272 //transform_persistence_begin
273 const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
274 const TEL_TRANSFORM_PERSISTENCE* theTransPers)
276 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
277 myTransPers = theTransPers;
278 if (theTransPers->mode == 0)
280 EndTransformPersistence (theCtx);
281 return aTransPersPrev;
285 OpenGl_Mat4d aModelMatrix, aProjMatrix;
286 theCtx->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport);
287 aModelMatrix.Convert (theCtx->ModelWorldState.Current() * theCtx->WorldViewState.Current());
288 aProjMatrix .Convert (theCtx->ProjectionState.Current());
290 const GLdouble aViewportW = (GLdouble )aViewport[2];
291 const GLdouble aViewportH = (GLdouble )aViewport[3];
294 // pop matrix stack - it will be overridden later
295 theCtx->WorldViewState.Pop();
296 theCtx->ProjectionState.Pop();
300 myIsTransPers = Standard_True;
303 // push matrices into stack and reset them
304 theCtx->WorldViewState.Push();
305 theCtx->ProjectionState.Push();
307 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
308 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
309 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
311 OpenGl_Utils::Project<Standard_Real> (theTransPers->pointX,
312 theTransPers->pointY,
313 theTransPers->pointZ,
323 if ((theTransPers->mode & TPF_ZOOM)
324 || (theTransPers->mode == TPF_TRIEDRON))
326 // compute fixed-zoom multiplier
327 // actually function works ugly with TelPerspective!
328 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix.GetValue (1, 1) : aProjMatrix.GetValue (0, 0));
329 aProjMatrix.ChangeValue (0, 0) *= aDet2;
330 aProjMatrix.ChangeValue (1, 1) *= aDet2;
331 aProjMatrix.ChangeValue (2, 2) *= aDet2;
334 // prevent translation - annulate translate matrix
335 if ((theTransPers->mode & TPF_PAN)
336 || (theTransPers->mode == TPF_TRIEDRON))
338 aModelMatrix.SetValue (0, 3, 0.0);
339 aModelMatrix.SetValue (1, 3, 0.0);
340 aModelMatrix.SetValue (2, 3, 0.0);
341 aProjMatrix .SetValue (0, 3, 0.0);
342 aProjMatrix .SetValue (1, 3, 0.0);
343 aProjMatrix .SetValue (2, 3, 0.0);
346 // prevent scaling-on-axis
347 if (theTransPers->mode & TPF_ZOOM)
349 const gp_Pnt anAxialScale = myCamera->AxialScale();
350 const double aScaleX = anAxialScale.X();
351 const double aScaleY = anAxialScale.Y();
352 const double aScaleZ = anAxialScale.Z();
353 for (int i = 0; i < 3; ++i)
355 aModelMatrix.ChangeValue (0, i) /= aScaleX;
356 aModelMatrix.ChangeValue (1, i) /= aScaleY;
357 aModelMatrix.ChangeValue (2, i) /= aScaleZ;
361 // prevent rotating - annulate rotate matrix
362 if (theTransPers->mode & TPF_ROTATE)
364 aModelMatrix.SetValue (0, 0, 1.0);
365 aModelMatrix.SetValue (1, 1, 1.0);
366 aModelMatrix.SetValue (2, 2, 1.0);
368 aModelMatrix.SetValue (1, 0, 0.0);
369 aModelMatrix.SetValue (2, 0, 0.0);
370 aModelMatrix.SetValue (0, 1, 0.0);
371 aModelMatrix.SetValue (2, 1, 0.0);
372 aModelMatrix.SetValue (0, 2, 0.0);
373 aModelMatrix.SetValue (1, 2, 0.0);
376 // load computed matrices
377 theCtx->ModelWorldState.SetIdentity();
378 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
379 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
381 if (theTransPers->mode == TPF_TRIEDRON)
383 // move to the window corner
384 if (theTransPers->pointX != 0.0
385 && theTransPers->pointY != 0.0)
387 GLdouble aW1, aH1, aW2, aH2, aDummy;
389 OpenGl_Mat4d anIdentity;
391 OpenGl_Utils::UnProject<Standard_Real> (0.5 * aViewportW,
401 OpenGl_Utils::UnProject<Standard_Real> (-0.5 * aViewportW,
411 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
412 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
413 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
414 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
416 OpenGl_Utils::Translate<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
417 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
420 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
422 // move to thePoint using saved win-coordinates ('marker-behaviour')
423 GLdouble aMoveX, aMoveY, aMoveZ;
425 OpenGl_Utils::UnProject<Standard_Real> (aWinX,
435 OpenGl_Utils::Translate<Standard_Real> (aModelMatrix, aMoveX, aMoveY, aMoveZ);
436 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
439 theCtx->ApplyProjectionMatrix();
440 return aTransPersPrev;
443 /*----------------------------------------------------------------------*/
445 void OpenGl_View::GetMatrices (OpenGl_Mat4& theOrientation,
446 OpenGl_Mat4& theViewMapping) const
448 theViewMapping = myCamera->ProjectionMatrixF();
449 theOrientation = myCamera->OrientationMatrixF();
451 /*----------------------------------------------------------------------*/