0025376: Inconsistence between function and derivatives evaluation in Extrema_GlobOpt...
[occt.git] / src / OpenGl / OpenGl_View.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
973c2be1 3// Copyright (c) 2011-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
30f0ad28 16#include <NCollection_Mat4.hxx>
5f8b738e 17
bf75be98 18#include <OpenGl_Context.hxx>
30f0ad28 19#include <OpenGl_GlCore11.hxx>
20#include <OpenGl_GraduatedTrihedron.hxx>
392ac980 21#include <OpenGl_GraphicDriver.hxx>
30f0ad28 22#include <OpenGl_ShaderManager.hxx>
bf75be98 23#include <OpenGl_Texture.hxx>
2166f0fa 24#include <OpenGl_Trihedron.hxx>
2166f0fa 25#include <OpenGl_transform_persistence.hxx>
30f0ad28 26#include <OpenGl_View.hxx>
27#include <OpenGl_Workspace.hxx>
2166f0fa 28
bf75be98 29#include <Graphic3d_TextureEnv.hxx>
197ac94e 30#include <Graphic3d_Mat4d.hxx>
bf75be98 31
2166f0fa
SK
32IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
33IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
34
35/*----------------------------------------------------------------------*/
36
37static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
38static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE };
39static 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 } };
40static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
2166f0fa
SK
41
42static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
43static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
c34dba32 44static const GLdouble THE_IDENTITY_MATRIX[4][4] =
45{
46 {1.0, 0.0, 0.0, 0.0},
47 {0.0, 1.0, 0.0, 0.0},
48 {0.0, 0.0, 1.0, 0.0},
49 {0.0, 0.0, 0.0, 1.0}
50};
2166f0fa
SK
51
52/*----------------------------------------------------------------------*/
53
392ac980 54OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
55 OpenGl_StateCounter* theCounter)
bf75be98 56: mySurfaceDetail(Visual3d_TOD_NONE),
2166f0fa
SK
57 myBackfacing(0),
58 myBgTexture(myDefaultBgTexture),
59 myBgGradient(myDefaultBgGradient),
2166f0fa
SK
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),
b5ac8292 66 myCamera(AContext.Camera),
2166f0fa 67 myFog(myDefaultFog),
2f6cb3ac 68 myTrihedron(NULL),
69 myGraduatedTrihedron(NULL),
2166f0fa 70 myVisualization(AContext.Visualization),
8625ef7e 71 myShadingModel ((Visual3d_TypeOfModel )AContext.Model),
2166f0fa 72 myAntiAliasing(Standard_False),
2166f0fa 73 myTransPers(&myDefaultTransPers),
30f0ad28 74 myIsTransPers(Standard_False),
b5ac8292 75 myProjectionState (0),
76 myModelViewState (0),
392ac980 77 myStateCounter (theCounter),
392ac980 78 myLastLightSourceState (0, 0)
2166f0fa 79{
392ac980 80 myCurrLightSourceState = myStateCounter->Increment();
e276548b 81 myModificationState = 1; // initial state
2166f0fa
SK
82}
83
84/*----------------------------------------------------------------------*/
85
86OpenGl_View::~OpenGl_View ()
87{
bf75be98 88 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
89}
90
91void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
92{
10b9c7df 93 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
94 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
30f0ad28 95
bf75be98 96 if (!myTextureEnv.IsNull())
97 {
98 theCtx->DelayedRelease (myTextureEnv);
99 myTextureEnv.Nullify();
100 }
101 if (myBgTexture.TexId != 0)
102 {
103 glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
104 myBgTexture.TexId = 0;
105 }
bf75be98 106}
2166f0fa 107
bf75be98 108void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
109 const Handle(Graphic3d_TextureEnv)& theTexture)
110{
111 if (!myTextureEnv.IsNull())
112 {
113 theCtx->DelayedRelease (myTextureEnv);
114 myTextureEnv.Nullify();
115 }
116
117 if (theTexture.IsNull())
118 {
119 return;
120 }
121
122 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
123 Handle(Image_PixMap) anImage = theTexture->GetImage();
e276548b 124 if (!anImage.IsNull())
da0e82aa 125 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
e276548b 126
e276548b 127 myModificationState++;
e276548b 128}
129
130void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
131{
132 mySurfaceDetail = theMode;
133
e276548b 134 myModificationState++;
2166f0fa
SK
135}
136
12381341 137// =======================================================================
138// function : SetBackfacing
139// purpose :
140// =======================================================================
de75ed09 141void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
2166f0fa 142{
de75ed09 143 myBackfacing = theMode;
2166f0fa
SK
144}
145
12381341 146// =======================================================================
147// function : SetLights
148// purpose :
149// =======================================================================
150void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
2166f0fa
SK
151{
152 myLights.Clear();
12381341 153 for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
2166f0fa 154 {
12381341 155 myLights.Append (theViewCtx.ActiveLight[aLightIt]);
2166f0fa 156 }
392ac980 157 myCurrLightSourceState = myStateCounter->Increment();
2166f0fa
SK
158}
159
160/*----------------------------------------------------------------------*/
161
2166f0fa
SK
162//call_togl_setvisualisation
163void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
164{
165 myVisualization = AContext.Visualization;
8625ef7e 166 myShadingModel = (Visual3d_TypeOfModel )AContext.Model;
2166f0fa
SK
167}
168
169/*----------------------------------------------------------------------*/
170
171//call_togl_cliplimit
bf75be98 172void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
2166f0fa 173{
b5ac8292 174 myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
175 myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
2166f0fa 176
bf75be98 177 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
178 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
2166f0fa
SK
179}
180
181/*----------------------------------------------------------------------*/
182
bf75be98 183void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
184 const Standard_Boolean theFlag)
2166f0fa 185{
bf75be98 186 if (!theFlag)
2166f0fa
SK
187 {
188 myFog.IsOn = Standard_False;
189 }
190 else
191 {
192 myFog.IsOn = Standard_True;
193
b5ac8292 194 myFog.Front = theCView.Context.DepthFrontPlane;
195 myFog.Back = theCView.Context.DepthBackPlane;
2166f0fa 196
bf75be98 197 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
198 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
199 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
200 myFog.Color.rgb[3] = 1.0f;
2166f0fa
SK
201 }
202}
203
204/*----------------------------------------------------------------------*/
205
a174a3c5 206void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)& theCtx,
207 const Aspect_TypeOfTriedronPosition thePosition,
208 const Quantity_NameOfColor theColor,
209 const Standard_Real theScale,
210 const Standard_Boolean theAsWireframe)
2166f0fa 211{
10b9c7df 212 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
a174a3c5 213 myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
2166f0fa
SK
214}
215
216/*----------------------------------------------------------------------*/
217
a174a3c5 218void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 219{
10b9c7df 220 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
2166f0fa
SK
221}
222
223/*----------------------------------------------------------------------*/
224
a174a3c5 225void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
226 const Graphic3d_CGraduatedTrihedron& theData)
2166f0fa 227{
10b9c7df 228 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
a174a3c5 229 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
2166f0fa
SK
230}
231
232/*----------------------------------------------------------------------*/
233
a174a3c5 234void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 235{
10b9c7df 236 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
2166f0fa
SK
237}
238
239/*----------------------------------------------------------------------*/
240
241//transform_persistence_end
30f0ad28 242void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
2166f0fa 243{
c34dba32 244 if (myIsTransPers)
2166f0fa 245 {
ca3c13d1 246 #if !defined(GL_ES_VERSION_2_0)
c34dba32 247 // restore matrix
2166f0fa 248 glMatrixMode (GL_PROJECTION);
c34dba32 249 glPopMatrix();
2166f0fa 250 glMatrixMode (GL_MODELVIEW);
c34dba32 251 glPopMatrix();
2166f0fa 252 myIsTransPers = Standard_False;
30f0ad28 253
254 // Note: the approach of accessing OpenGl matrices is used now since the matrix
255 // manipulation are made with help of OpenGl methods. This might be replaced by
256 // direct computation of matrices by OCC subroutines.
257 Tmatrix3 aResultWorldView;
258 glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
259
260 Tmatrix3 aResultProjection;
261 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
262
263 // Set OCCT state uniform variables
b5ac8292 264 theCtx->ShaderManager()->RevertWorldViewStateTo (&aResultWorldView);
265 theCtx->ShaderManager()->RevertProjectionStateTo (&aResultProjection);
ca3c13d1 266 #endif
2166f0fa 267 }
bf75be98 268}
2166f0fa
SK
269
270/*----------------------------------------------------------------------*/
271
272//transform_persistence_begin
30f0ad28 273const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
274 const TEL_TRANSFORM_PERSISTENCE* theTransPers)
2166f0fa 275{
c34dba32 276 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
277 myTransPers = theTransPers;
278 if (theTransPers->mode == 0)
2166f0fa 279 {
30f0ad28 280 EndTransformPersistence (theCtx);
c34dba32 281 return aTransPersPrev;
2166f0fa
SK
282 }
283
ca3c13d1 284#if !defined(GL_ES_VERSION_2_0)
c34dba32 285 GLint aViewport[4];
286 GLdouble aModelMatrix[4][4];
287 GLdouble aProjMatrix[4][4];
288 glGetIntegerv (GL_VIEWPORT, aViewport);
289 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
290 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble *)aProjMatrix);
ca3c13d1 291
c34dba32 292 const GLdouble aViewportW = (GLdouble )aViewport[2];
293 const GLdouble aViewportH = (GLdouble )aViewport[3];
2166f0fa 294
c34dba32 295 if (myIsTransPers)
2166f0fa 296 {
c34dba32 297 // pop matrix stack - it will be overridden later
2166f0fa 298 glMatrixMode (GL_PROJECTION);
c34dba32 299 glPopMatrix();
2166f0fa 300 glMatrixMode (GL_MODELVIEW);
c34dba32 301 glPopMatrix();
2166f0fa
SK
302 }
303 else
c34dba32 304 {
2166f0fa 305 myIsTransPers = Standard_True;
c34dba32 306 }
2166f0fa 307
c34dba32 308 // push matrices into stack and reset them
309 glMatrixMode (GL_MODELVIEW);
2166f0fa
SK
310 glPushMatrix();
311 glLoadIdentity();
312
c34dba32 313 glMatrixMode (GL_PROJECTION);
2166f0fa
SK
314 glPushMatrix();
315 glLoadIdentity();
316
c34dba32 317 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
318 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
319 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
2166f0fa 320 {
c34dba32 321 gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
322 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
323 &aWinX, &aWinY, &aWinZ);
2166f0fa
SK
324 }
325
c34dba32 326 // prevent zooming
327 if ((theTransPers->mode & TPF_ZOOM)
328 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 329 {
c34dba32 330 // compute fixed-zoom multiplier
331 // actually function works ugly with TelPerspective!
332 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix[1][1] : aProjMatrix[0][0]);
333 aProjMatrix[0][0] *= aDet2;
334 aProjMatrix[1][1] *= aDet2;
335 aProjMatrix[2][2] *= aDet2;
2166f0fa
SK
336 }
337
c34dba32 338 // prevent translation - annulate translate matrix
339 if ((theTransPers->mode & TPF_PAN)
340 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 341 {
c34dba32 342 aModelMatrix[3][0] = 0.0;
343 aModelMatrix[3][1] = 0.0;
344 aModelMatrix[3][2] = 0.0;
345 aProjMatrix [3][0] = 0.0;
346 aProjMatrix [3][1] = 0.0;
347 aProjMatrix [3][2] = 0.0;
2166f0fa 348 }
2166f0fa 349
c34dba32 350 // prevent scaling-on-axis
351 if (theTransPers->mode & TPF_ZOOM)
352 {
b5ac8292 353 const gp_Pnt anAxialScale = myCamera->AxialScale();
354 const double aScaleX = anAxialScale.X();
355 const double aScaleY = anAxialScale.Y();
356 const double aScaleZ = anAxialScale.Z();
c34dba32 357 for (int i = 0; i < 3; ++i)
358 {
359 aModelMatrix[0][i] /= aScaleX;
360 aModelMatrix[1][i] /= aScaleY;
361 aModelMatrix[2][i] /= aScaleZ;
362 }
2166f0fa
SK
363 }
364
c34dba32 365 // prevent rotating - annulate rotate matrix
366 if (theTransPers->mode & TPF_ROTATE)
2166f0fa 367 {
c34dba32 368 aModelMatrix[0][0] = 1.0;
369 aModelMatrix[1][1] = 1.0;
370 aModelMatrix[2][2] = 1.0;
371
372 aModelMatrix[1][0] = 0.0;
373 aModelMatrix[2][0] = 0.0;
374 aModelMatrix[0][1] = 0.0;
375 aModelMatrix[2][1] = 0.0;
376 aModelMatrix[0][2] = 0.0;
377 aModelMatrix[1][2] = 0.0;
2166f0fa
SK
378 }
379
c34dba32 380 // load computed matrices
2166f0fa 381 glMatrixMode (GL_MODELVIEW);
c34dba32 382 glMultMatrixd ((GLdouble* )aModelMatrix);
2166f0fa
SK
383
384 glMatrixMode (GL_PROJECTION);
c34dba32 385 glMultMatrixd ((GLdouble* )aProjMatrix);
2166f0fa 386
c34dba32 387 if (theTransPers->mode == TPF_TRIEDRON)
2166f0fa 388 {
c34dba32 389 // move to the window corner
390 if (theTransPers->pointX != 0.0
391 && theTransPers->pointY != 0.0)
2166f0fa 392 {
c34dba32 393 GLdouble aW1, aH1, aW2, aH2, aDummy;
394 glMatrixMode (GL_PROJECTION);
395 gluUnProject ( 0.5 * aViewportW, 0.5 * aViewportH, 0.0,
396 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
397 &aW1, &aH1, &aDummy);
398 gluUnProject (-0.5 * aViewportW, -0.5 * aViewportH, 0.0,
399 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
400 &aW2, &aH2, &aDummy);
ca3c13d1 401
c34dba32 402 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
403 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
404 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
405 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
ca3c13d1 406 theCtx->core11->glTranslated (aMoveX, aMoveY, 0.0);
2166f0fa
SK
407 }
408 }
c34dba32 409 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
410 {
411 // move to thePoint using saved win-coordinates ('marker-behaviour')
412 GLdouble aMoveX, aMoveY, aMoveZ;
413 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
414 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble* )aProjMatrix);
415 gluUnProject (aWinX, aWinY, aWinZ,
416 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
417 &aMoveX, &aMoveY, &aMoveZ);
2166f0fa 418
c34dba32 419 glMatrixMode (GL_MODELVIEW);
ca3c13d1 420 theCtx->core11->glTranslated (aMoveX, aMoveY, aMoveZ);
c34dba32 421 }
2166f0fa 422
30f0ad28 423 // Note: the approach of accessing OpenGl matrices is used now since the matrix
424 // manipulation are made with help of OpenGl methods. This might be replaced by
425 // direct computation of matrices by OCC subroutines.
426 Tmatrix3 aResultWorldView;
427 glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
428
429 Tmatrix3 aResultProjection;
430 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
431
432 // Set OCCT state uniform variables
b5ac8292 433 theCtx->ShaderManager()->UpdateWorldViewStateTo (&aResultWorldView);
434 theCtx->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
ca3c13d1 435#endif
c34dba32 436 return aTransPersPrev;
437}
b5ac8292 438
439/*----------------------------------------------------------------------*/
440
441void OpenGl_View::GetMatrices (TColStd_Array2OfReal& theMatOrient,
442 TColStd_Array2OfReal& theMatMapping) const
443{
197ac94e 444 const Graphic3d_Mat4d& aProj = myCamera->ProjectionMatrix();
445 const Graphic3d_Mat4d& aOrient = myCamera->OrientationMatrix();
b5ac8292 446
197ac94e 447 for (Standard_Integer aRow = 0; aRow < 4; ++aRow)
b5ac8292 448 {
197ac94e 449 for (Standard_Integer aCol = 0; aCol < 4; ++aCol)
b5ac8292 450 {
197ac94e 451 theMatOrient (aRow, aCol) = aOrient.GetValue (aRow, aCol);
452 theMatMapping (aRow, aCol) = aProj .GetValue (aRow, aCol);
b5ac8292 453 }
454 }
455}
456/*----------------------------------------------------------------------*/