0025974: Visualization - fix misprints in method naming of Graphic3d_GraduatedTrihedron
[occt.git] / src / OpenGl / OpenGl_View.cxx
1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <NCollection_Mat4.hxx>
17
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>
29
30 #include <Graphic3d_TextureEnv.hxx>
31 #include <Graphic3d_Mat4d.hxx>
32
33 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
34 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
35
36 /*----------------------------------------------------------------------*/
37
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 } };
40
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] =
44 {
45   {1.0, 0.0, 0.0, 0.0},
46   {0.0, 1.0, 0.0, 0.0},
47   {0.0, 0.0, 1.0, 0.0},
48   {0.0, 0.0, 0.0, 1.0}
49 };
50
51 /*----------------------------------------------------------------------*/
52
53 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
54                           OpenGl_StateCounter*       theCounter)
55 : mySurfaceDetail(Visual3d_TOD_ALL),
56   myBackfacing(0),
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),
64   myFog(myDefaultFog),
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),
73   myModelViewState (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))
80 {
81   myCurrLightSourceState = myStateCounter->Increment();
82 }
83
84 /*----------------------------------------------------------------------*/
85
86 OpenGl_View::~OpenGl_View()
87 {
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);
92 }
93
94 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
95 {
96   myTrihedron         .Release (theCtx.operator->());
97   myGraduatedTrihedron.Release (theCtx.operator->());
98
99   if (!myTextureEnv.IsNull())
100   {
101     theCtx->DelayedRelease (myTextureEnv);
102     myTextureEnv.Nullify();
103   }
104
105   if (myTextureParams != NULL)
106   {
107     myTextureParams->Release (theCtx.operator->());
108   }
109   if (myBgGradientArray != NULL)
110   {
111     myBgGradientArray->Release (theCtx.operator->());
112   }
113   if (myBgTextureArray != NULL)
114   {
115     myBgTextureArray->Release (theCtx.operator->());
116   }
117 }
118
119 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)&       theCtx,
120                                  const Handle(Graphic3d_TextureEnv)& theTexture)
121 {
122   if (!myTextureEnv.IsNull())
123   {
124     theCtx->DelayedRelease (myTextureEnv);
125     myTextureEnv.Nullify();
126   }
127
128   if (theTexture.IsNull())
129   {
130     return;
131   }
132
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());
137
138   myModificationState++;
139 }
140
141 void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
142 {
143   mySurfaceDetail = theMode;
144
145   myModificationState++;
146 }
147
148 // =======================================================================
149 // function : SetBackfacing
150 // purpose  :
151 // =======================================================================
152 void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
153 {
154   myBackfacing = theMode;
155 }
156
157 // =======================================================================
158 // function : SetLights
159 // purpose  :
160 // =======================================================================
161 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
162 {
163   myLights.Clear();
164   for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
165   {
166     myLights.Append (theViewCtx.ActiveLight[aLightIt]);
167   }
168   myCurrLightSourceState = myStateCounter->Increment();
169 }
170
171 /*----------------------------------------------------------------------*/
172
173 //call_togl_setvisualisation
174 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
175 {
176   myVisualization = AContext.Visualization;
177   myShadingModel  = (Visual3d_TypeOfModel )AContext.Model;
178 }
179
180 /*----------------------------------------------------------------------*/
181
182 //call_togl_cliplimit
183 void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
184 {
185   myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
186   myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
187
188   myZClip.Back.IsOn  = (theCView.Context.BackZClipping  != 0);
189   myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
190 }
191
192 /*----------------------------------------------------------------------*/
193
194 void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
195                           const Standard_Boolean theFlag)
196 {
197   if (!theFlag)
198   {
199     myFog.IsOn = Standard_False;
200   }
201   else
202   {
203     myFog.IsOn = Standard_True;
204
205     myFog.Front = theCView.Context.DepthFrontPlane;
206     myFog.Back = theCView.Context.DepthBackPlane;
207
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;
212   }
213 }
214
215 /*----------------------------------------------------------------------*/
216
217 void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
218                                    const Quantity_NameOfColor          theColor,
219                                    const Standard_Real                 theScale,
220                                    const Standard_Boolean              theAsWireframe)
221 {
222   myToShowTrihedron = true;
223   myTrihedron.SetWireframe   (theAsWireframe);
224   myTrihedron.SetPosition    (thePosition);
225   myTrihedron.SetScale       (theScale);
226   myTrihedron.SetLabelsColor (theColor);
227 }
228
229 /*----------------------------------------------------------------------*/
230
231 void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
232 {
233   myToShowTrihedron = false;
234   myTrihedron.Release (theCtx.operator->());
235 }
236
237 /*----------------------------------------------------------------------*/
238
239 void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)&       theCtx,
240                                              const Graphic3d_GraduatedTrihedron& theData)
241 {
242   myToShowGradTrihedron = true;
243   myGraduatedTrihedron.SetValues (theCtx, theData);
244 }
245
246 /*----------------------------------------------------------------------*/
247
248 void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
249 {
250   myToShowGradTrihedron = false;
251   myGraduatedTrihedron.Release (theCtx.operator->());
252 }
253
254 /*----------------------------------------------------------------------*/
255
256 //transform_persistence_end
257 void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
258 {
259   if (myIsTransPers)
260   {
261     theCtx->WorldViewState.Pop();
262     theCtx->ProjectionState.Pop();
263
264     theCtx->ApplyProjectionMatrix();
265
266     myIsTransPers = Standard_False;
267   }
268 }
269
270 /*----------------------------------------------------------------------*/
271
272 //transform_persistence_begin
273 const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
274                                                                          const TEL_TRANSFORM_PERSISTENCE* theTransPers)
275 {
276   const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
277   myTransPers = theTransPers;
278   if (theTransPers->mode == 0)
279   {
280     EndTransformPersistence (theCtx);
281     return aTransPersPrev;
282   }
283
284   GLint aViewport[4];
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());
289
290   const GLdouble aViewportW = (GLdouble )aViewport[2];
291   const GLdouble aViewportH = (GLdouble )aViewport[3];
292   if (myIsTransPers)
293   {
294     // pop matrix stack - it will be overridden later
295     theCtx->WorldViewState.Pop();
296     theCtx->ProjectionState.Pop();
297   }
298   else
299   {
300     myIsTransPers = Standard_True;
301   }
302
303   // push matrices into stack and reset them
304   theCtx->WorldViewState.Push();
305   theCtx->ProjectionState.Push();
306
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)
310   {
311     OpenGl_Utils::Project<Standard_Real> (theTransPers->pointX,
312                                           theTransPers->pointY,
313                                           theTransPers->pointZ,
314                                           aModelMatrix,
315                                           aProjMatrix,
316                                           aViewport,
317                                           aWinX,
318                                           aWinY,
319                                           aWinZ);
320   }
321
322   // prevent zooming
323   if ((theTransPers->mode & TPF_ZOOM)
324    || (theTransPers->mode == TPF_TRIEDRON))
325   {
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;
332   }
333
334   // prevent translation - annulate translate matrix
335   if ((theTransPers->mode & TPF_PAN)
336    || (theTransPers->mode == TPF_TRIEDRON))
337   {
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);
344   }
345
346   // prevent scaling-on-axis
347   if (theTransPers->mode & TPF_ZOOM)
348   {
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)
354     {
355       aModelMatrix.ChangeValue (0, i) /= aScaleX;
356       aModelMatrix.ChangeValue (1, i) /= aScaleY;
357       aModelMatrix.ChangeValue (2, i) /= aScaleZ;
358     }
359   }
360
361   // prevent rotating - annulate rotate matrix
362   if (theTransPers->mode & TPF_ROTATE)
363   {
364     aModelMatrix.SetValue (0, 0, 1.0);
365     aModelMatrix.SetValue (1, 1, 1.0);
366     aModelMatrix.SetValue (2, 2, 1.0);
367
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);
374   }
375
376   // load computed matrices
377   theCtx->ModelWorldState.SetIdentity();
378   theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
379   theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
380
381   if (theTransPers->mode == TPF_TRIEDRON)
382   {
383     // move to the window corner
384     if (theTransPers->pointX != 0.0
385      && theTransPers->pointY != 0.0)
386     {
387       GLdouble aW1, aH1, aW2, aH2, aDummy;
388
389       OpenGl_Mat4d anIdentity;
390
391       OpenGl_Utils::UnProject<Standard_Real> (0.5 * aViewportW,
392                                               0.5 * aViewportH,
393                                               0.0,
394                                               anIdentity,
395                                               aProjMatrix,
396                                               aViewport,
397                                               aW1,
398                                               aH1,
399                                               aDummy);
400
401       OpenGl_Utils::UnProject<Standard_Real> (-0.5 * aViewportW,
402                                               -0.5 * aViewportH,
403                                               0.0,
404                                               anIdentity,
405                                               aProjMatrix,
406                                               aViewport,
407                                               aW2,
408                                               aH2,
409                                               aDummy);
410
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;
415
416       OpenGl_Utils::Translate<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
417       theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
418     }
419   }
420   else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
421   {
422     // move to thePoint using saved win-coordinates ('marker-behaviour')
423     GLdouble aMoveX, aMoveY, aMoveZ;
424
425     OpenGl_Utils::UnProject<Standard_Real> (aWinX,
426                                             aWinY,
427                                             aWinZ,
428                                             aModelMatrix,
429                                             aProjMatrix,
430                                             aViewport,
431                                             aMoveX,
432                                             aMoveY,
433                                             aMoveZ);
434
435     OpenGl_Utils::Translate<Standard_Real> (aModelMatrix, aMoveX, aMoveY, aMoveZ);
436     theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
437   }
438
439   theCtx->ApplyProjectionMatrix();
440   return aTransPersPrev;
441 }
442
443 /*----------------------------------------------------------------------*/
444
445 void OpenGl_View::GetMatrices (OpenGl_Mat4& theOrientation,
446                                OpenGl_Mat4& theViewMapping) const
447 {
448   theViewMapping = myCamera->ProjectionMatrixF();
449   theOrientation = myCamera->OrientationMatrixF();
450 }
451 /*----------------------------------------------------------------------*/