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 myTextureParams (new OpenGl_AspectFace()),
77 myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
78 myBgTextureArray (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
79 // ray-tracing fields initialization
80 myRaytraceInitStatus (OpenGl_RT_NONE),
81 myIsRaytraceDataValid (Standard_False),
82 myIsRaytraceWarnTextures (Standard_False),
83 myToUpdateEnvironmentMap (Standard_False),
84 myLayersModificationStatus (0)
86 myCurrLightSourceState = myStateCounter->Increment();
89 /*----------------------------------------------------------------------*/
91 OpenGl_View::~OpenGl_View()
93 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
94 OpenGl_Element::Destroy (NULL, myBgGradientArray);
95 OpenGl_Element::Destroy (NULL, myBgTextureArray);
96 OpenGl_Element::Destroy (NULL, myTextureParams);
99 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
101 myTrihedron .Release (theCtx.operator->());
102 myGraduatedTrihedron.Release (theCtx.operator->());
104 if (!myTextureEnv.IsNull())
106 theCtx->DelayedRelease (myTextureEnv);
107 myTextureEnv.Nullify();
110 if (myTextureParams != NULL)
112 myTextureParams->Release (theCtx.operator->());
114 if (myBgGradientArray != NULL)
116 myBgGradientArray->Release (theCtx.operator->());
118 if (myBgTextureArray != NULL)
120 myBgTextureArray->Release (theCtx.operator->());
123 releaseRaytraceResources (theCtx);
126 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
127 const Handle(Graphic3d_TextureEnv)& theTexture)
129 if (!myTextureEnv.IsNull())
131 theCtx->DelayedRelease (myTextureEnv);
132 myTextureEnv.Nullify();
135 if (theTexture.IsNull())
140 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
141 Handle(Image_PixMap) anImage = theTexture->GetImage();
142 if (!anImage.IsNull())
143 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
145 myToUpdateEnvironmentMap = Standard_True;
148 void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
150 mySurfaceDetail = theMode;
152 myToUpdateEnvironmentMap = Standard_True;
155 // =======================================================================
156 // function : SetBackfacing
158 // =======================================================================
159 void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
161 myBackfacing = theMode;
164 // =======================================================================
165 // function : SetLights
167 // =======================================================================
168 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
171 for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
173 myLights.Append (theViewCtx.ActiveLight[aLightIt]);
175 myCurrLightSourceState = myStateCounter->Increment();
178 /*----------------------------------------------------------------------*/
180 //call_togl_setvisualisation
181 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
183 myVisualization = AContext.Visualization;
184 myShadingModel = (Visual3d_TypeOfModel )AContext.Model;
187 /*----------------------------------------------------------------------*/
189 //call_togl_cliplimit
190 void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
192 myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
193 myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
195 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
196 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
199 /*----------------------------------------------------------------------*/
201 void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
202 const Standard_Boolean theFlag)
206 myFog.IsOn = Standard_False;
210 myFog.IsOn = Standard_True;
212 myFog.Front = theCView.Context.DepthFrontPlane;
213 myFog.Back = theCView.Context.DepthBackPlane;
215 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
216 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
217 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
218 myFog.Color.rgb[3] = 1.0f;
222 /*----------------------------------------------------------------------*/
224 void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
225 const Quantity_NameOfColor theColor,
226 const Standard_Real theScale,
227 const Standard_Boolean theAsWireframe)
229 myToShowTrihedron = true;
230 myTrihedron.SetWireframe (theAsWireframe);
231 myTrihedron.SetPosition (thePosition);
232 myTrihedron.SetScale (theScale);
233 myTrihedron.SetLabelsColor (theColor);
236 /*----------------------------------------------------------------------*/
238 void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
240 myToShowTrihedron = false;
241 myTrihedron.Release (theCtx.operator->());
244 /*----------------------------------------------------------------------*/
246 void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
247 const Graphic3d_GraduatedTrihedron& theData)
249 myToShowGradTrihedron = true;
250 myGraduatedTrihedron.SetValues (theCtx, theData);
253 /*----------------------------------------------------------------------*/
255 void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
257 myToShowGradTrihedron = false;
258 myGraduatedTrihedron.Release (theCtx.operator->());
261 /*----------------------------------------------------------------------*/
263 //transform_persistence_end
264 void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
268 theCtx->WorldViewState.Pop();
269 theCtx->ProjectionState.Pop();
271 theCtx->ApplyProjectionMatrix();
272 theCtx->ApplyWorldViewMatrix();
274 myIsTransPers = Standard_False;
278 /*----------------------------------------------------------------------*/
280 //transform_persistence_begin
281 const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
282 const TEL_TRANSFORM_PERSISTENCE* theTransPers,
283 Standard_Integer theWidth,
284 Standard_Integer theHeight)
286 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
287 myTransPers = theTransPers;
288 if (theTransPers->mode == 0)
290 EndTransformPersistence (theCtx);
291 return aTransPersPrev;
295 OpenGl_Mat4d aModelMatrix, aProjMatrix;
296 theCtx->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport);
297 aModelMatrix.Convert (theCtx->ModelWorldState.Current() * theCtx->WorldViewState.Current());
298 aProjMatrix .Convert (theCtx->ProjectionState.Current());
300 const GLdouble aViewportW = (GLdouble )aViewport[2];
301 const GLdouble aViewportH = (GLdouble )aViewport[3];
305 // pop matrix stack - it will be overridden later
306 theCtx->WorldViewState.Pop();
307 theCtx->ProjectionState.Pop();
311 myIsTransPers = Standard_True;
314 if (theTransPers->mode & TPF_2D)
316 GLfloat aLeft = -static_cast<GLfloat> (theWidth / 2);
317 GLfloat aRight = static_cast<GLfloat> (theWidth / 2);
318 GLfloat aBottom = -static_cast<GLfloat> (theHeight / 2);
319 GLfloat aTop = static_cast<GLfloat> (theHeight / 2);
320 GLfloat aGap = static_cast<GLfloat> (theTransPers->pointZ);
321 if (theTransPers->pointX > 0)
323 aLeft -= static_cast<GLfloat> (theWidth / 2) - aGap;
324 aRight -= static_cast<GLfloat> (theWidth / 2) - aGap;
326 else if (theTransPers->pointX < 0)
328 aLeft += static_cast<GLfloat> (theWidth / 2) - aGap;
329 aRight += static_cast<GLfloat> (theWidth / 2) - aGap;
331 if (theTransPers->pointY > 0)
333 aBottom -= static_cast<GLfloat> (theHeight / 2) - aGap;
334 aTop -= static_cast<GLfloat> (theHeight / 2) - aGap;
336 else if (theTransPers->pointY < 0)
338 aBottom += static_cast<GLfloat> (theHeight / 2) - aGap;
339 aTop += static_cast<GLfloat> (theHeight / 2) - aGap;
341 if (theTransPers->mode == TPF_2D_ISTOPDOWN)
343 const GLfloat aTemp = aTop;
348 OpenGl_Mat4 aProjectMat;
349 OpenGl_Utils::Ortho2D<Standard_ShortReal> (aProjectMat,
353 theCtx->WorldViewState.Push();
354 theCtx->ProjectionState.Push();
356 theCtx->WorldViewState.SetIdentity();
357 theCtx->ProjectionState.SetCurrent (aProjectMat);
359 theCtx->ApplyWorldViewMatrix();
360 theCtx->ApplyProjectionMatrix();
361 return aTransPersPrev;
364 // push matrices into stack and reset them
365 theCtx->WorldViewState.Push();
366 theCtx->ProjectionState.Push();
368 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
369 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
370 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
372 OpenGl_Utils::Project<Standard_Real> (theTransPers->pointX,
373 theTransPers->pointY,
374 theTransPers->pointZ,
384 if ((theTransPers->mode & TPF_ZOOM)
385 || (theTransPers->mode == TPF_TRIEDRON))
387 // compute fixed-zoom multiplier
388 // actually function works ugly with TelPerspective!
389 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix.GetValue (1, 1) : aProjMatrix.GetValue (0, 0));
390 aProjMatrix.ChangeValue (0, 0) *= aDet2;
391 aProjMatrix.ChangeValue (1, 1) *= aDet2;
392 aProjMatrix.ChangeValue (2, 2) *= aDet2;
395 // prevent translation - annulate translate matrix
396 if ((theTransPers->mode & TPF_PAN)
397 || (theTransPers->mode == TPF_TRIEDRON))
399 aModelMatrix.SetValue (0, 3, 0.0);
400 aModelMatrix.SetValue (1, 3, 0.0);
401 aModelMatrix.SetValue (2, 3, 0.0);
402 aProjMatrix .SetValue (0, 3, 0.0);
403 aProjMatrix .SetValue (1, 3, 0.0);
404 aProjMatrix .SetValue (2, 3, 0.0);
407 // prevent scaling-on-axis
408 if (theTransPers->mode & TPF_ZOOM)
410 const gp_Pnt anAxialScale = myCamera->AxialScale();
411 const double aScaleX = anAxialScale.X();
412 const double aScaleY = anAxialScale.Y();
413 const double aScaleZ = anAxialScale.Z();
414 for (int i = 0; i < 3; ++i)
416 aModelMatrix.ChangeValue (0, i) /= aScaleX;
417 aModelMatrix.ChangeValue (1, i) /= aScaleY;
418 aModelMatrix.ChangeValue (2, i) /= aScaleZ;
422 // prevent rotating - annulate rotate matrix
423 if (theTransPers->mode & TPF_ROTATE)
425 aModelMatrix.SetValue (0, 0, 1.0);
426 aModelMatrix.SetValue (1, 1, 1.0);
427 aModelMatrix.SetValue (2, 2, 1.0);
429 aModelMatrix.SetValue (1, 0, 0.0);
430 aModelMatrix.SetValue (2, 0, 0.0);
431 aModelMatrix.SetValue (0, 1, 0.0);
432 aModelMatrix.SetValue (2, 1, 0.0);
433 aModelMatrix.SetValue (0, 2, 0.0);
434 aModelMatrix.SetValue (1, 2, 0.0);
437 // load computed matrices
438 theCtx->ModelWorldState.SetIdentity();
439 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
440 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
442 if (theTransPers->mode == TPF_TRIEDRON)
444 // move to the window corner
445 if (theTransPers->pointX != 0.0
446 && theTransPers->pointY != 0.0)
448 GLdouble aW1, aH1, aW2, aH2, aDummy;
450 OpenGl_Mat4d anIdentity;
452 OpenGl_Utils::UnProject<Standard_Real> (0.5 * aViewportW,
462 OpenGl_Utils::UnProject<Standard_Real> (-0.5 * aViewportW,
472 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
473 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
474 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
475 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
477 OpenGl_Utils::Translate<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
478 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
481 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
483 // move to thePoint using saved win-coordinates ('marker-behaviour')
484 GLdouble aMoveX, aMoveY, aMoveZ;
486 OpenGl_Utils::UnProject<Standard_Real> (aWinX,
496 OpenGl_Utils::Translate<Standard_Real> (aModelMatrix, aMoveX, aMoveY, aMoveZ);
497 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
500 theCtx->ApplyProjectionMatrix();
501 return aTransPersPrev;