0026016: BRepPrimAPI_MakeRevol crash
[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>
c827ea3a 27#include <OpenGl_Utils.hxx>
30f0ad28 28#include <OpenGl_Workspace.hxx>
2166f0fa 29
bf75be98 30#include <Graphic3d_TextureEnv.hxx>
197ac94e 31#include <Graphic3d_Mat4d.hxx>
bf75be98 32
2166f0fa
SK
33IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
34IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
35
36/*----------------------------------------------------------------------*/
37
2166f0fa
SK
38static 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 } };
39static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
2166f0fa
SK
40
41static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
42static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
c34dba32 43static 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};
2166f0fa
SK
50
51/*----------------------------------------------------------------------*/
52
392ac980 53OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
54 OpenGl_StateCounter* theCounter)
a6964ce6 55: mySurfaceDetail(Visual3d_TOD_ALL),
2166f0fa 56 myBackfacing(0),
2166f0fa
SK
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),
b5ac8292 63 myCamera(AContext.Camera),
2166f0fa 64 myFog(myDefaultFog),
2f6cb3ac 65 myTrihedron(NULL),
66 myGraduatedTrihedron(NULL),
2166f0fa 67 myVisualization(AContext.Visualization),
8625ef7e 68 myShadingModel ((Visual3d_TypeOfModel )AContext.Model),
2166f0fa 69 myAntiAliasing(Standard_False),
2166f0fa 70 myTransPers(&myDefaultTransPers),
30f0ad28 71 myIsTransPers(Standard_False),
b5ac8292 72 myProjectionState (0),
73 myModelViewState (0),
392ac980 74 myStateCounter (theCounter),
0b0320e7 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))
2166f0fa 80{
392ac980 81 myCurrLightSourceState = myStateCounter->Increment();
2166f0fa
SK
82}
83
84/*----------------------------------------------------------------------*/
85
0b0320e7 86OpenGl_View::~OpenGl_View()
2166f0fa 87{
bf75be98 88 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
c827ea3a 89 OpenGl_Element::Destroy (NULL, myTrihedron);
90 OpenGl_Element::Destroy (NULL, myGraduatedTrihedron);
0b0320e7 91 OpenGl_Element::Destroy (NULL, myBgGradientArray);
92 OpenGl_Element::Destroy (NULL, myBgTextureArray);
93 OpenGl_Element::Destroy (NULL, myTextureParams);
bf75be98 94}
95
96void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
97{
c827ea3a 98 if (myTrihedron != NULL)
99 {
100 myTrihedron->Release (theCtx.operator->());
101 }
102 if (myGraduatedTrihedron != NULL)
103 {
104 myGraduatedTrihedron->Release (theCtx.operator->());
105 }
30f0ad28 106
bf75be98 107 if (!myTextureEnv.IsNull())
108 {
109 theCtx->DelayedRelease (myTextureEnv);
110 myTextureEnv.Nullify();
111 }
0b0320e7 112
113 if (myTextureParams != NULL)
114 {
115 myTextureParams->Release (theCtx.operator->());
116 }
117 if (myBgGradientArray != NULL)
118 {
119 myBgGradientArray->Release (theCtx.operator->());
120 }
121 if (myBgTextureArray != NULL)
bf75be98 122 {
0b0320e7 123 myBgTextureArray->Release (theCtx.operator->());
bf75be98 124 }
bf75be98 125}
2166f0fa 126
bf75be98 127void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
128 const Handle(Graphic3d_TextureEnv)& theTexture)
129{
130 if (!myTextureEnv.IsNull())
131 {
132 theCtx->DelayedRelease (myTextureEnv);
133 myTextureEnv.Nullify();
134 }
135
136 if (theTexture.IsNull())
137 {
138 return;
139 }
140
141 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
142 Handle(Image_PixMap) anImage = theTexture->GetImage();
e276548b 143 if (!anImage.IsNull())
da0e82aa 144 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
e276548b 145
e276548b 146 myModificationState++;
e276548b 147}
148
149void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
150{
151 mySurfaceDetail = theMode;
152
e276548b 153 myModificationState++;
2166f0fa
SK
154}
155
12381341 156// =======================================================================
157// function : SetBackfacing
158// purpose :
159// =======================================================================
de75ed09 160void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
2166f0fa 161{
de75ed09 162 myBackfacing = theMode;
2166f0fa
SK
163}
164
12381341 165// =======================================================================
166// function : SetLights
167// purpose :
168// =======================================================================
169void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
2166f0fa
SK
170{
171 myLights.Clear();
12381341 172 for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
2166f0fa 173 {
12381341 174 myLights.Append (theViewCtx.ActiveLight[aLightIt]);
2166f0fa 175 }
392ac980 176 myCurrLightSourceState = myStateCounter->Increment();
2166f0fa
SK
177}
178
179/*----------------------------------------------------------------------*/
180
2166f0fa
SK
181//call_togl_setvisualisation
182void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
183{
184 myVisualization = AContext.Visualization;
8625ef7e 185 myShadingModel = (Visual3d_TypeOfModel )AContext.Model;
2166f0fa
SK
186}
187
188/*----------------------------------------------------------------------*/
189
190//call_togl_cliplimit
bf75be98 191void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
2166f0fa 192{
b5ac8292 193 myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
194 myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
2166f0fa 195
bf75be98 196 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
197 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
2166f0fa
SK
198}
199
200/*----------------------------------------------------------------------*/
201
bf75be98 202void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
203 const Standard_Boolean theFlag)
2166f0fa 204{
bf75be98 205 if (!theFlag)
2166f0fa
SK
206 {
207 myFog.IsOn = Standard_False;
208 }
209 else
210 {
211 myFog.IsOn = Standard_True;
212
b5ac8292 213 myFog.Front = theCView.Context.DepthFrontPlane;
214 myFog.Back = theCView.Context.DepthBackPlane;
2166f0fa 215
bf75be98 216 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
217 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
218 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
219 myFog.Color.rgb[3] = 1.0f;
2166f0fa
SK
220 }
221}
222
223/*----------------------------------------------------------------------*/
224
a174a3c5 225void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)& theCtx,
226 const Aspect_TypeOfTriedronPosition thePosition,
227 const Quantity_NameOfColor theColor,
228 const Standard_Real theScale,
229 const Standard_Boolean theAsWireframe)
2166f0fa 230{
10b9c7df 231 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
a174a3c5 232 myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
2166f0fa
SK
233}
234
235/*----------------------------------------------------------------------*/
236
a174a3c5 237void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 238{
10b9c7df 239 OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
2166f0fa
SK
240}
241
242/*----------------------------------------------------------------------*/
243
a174a3c5 244void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
a79f67f8 245 const Graphic3d_GraduatedTrihedron& theData)
2166f0fa 246{
10b9c7df 247 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
a174a3c5 248 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
2166f0fa
SK
249}
250
251/*----------------------------------------------------------------------*/
252
a174a3c5 253void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 254{
10b9c7df 255 OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
2166f0fa
SK
256}
257
258/*----------------------------------------------------------------------*/
259
260//transform_persistence_end
30f0ad28 261void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
2166f0fa 262{
c34dba32 263 if (myIsTransPers)
2166f0fa 264 {
c827ea3a 265 theCtx->WorldViewState.Pop();
266 theCtx->ProjectionState.Pop();
30f0ad28 267
c827ea3a 268 theCtx->ApplyProjectionMatrix();
30f0ad28 269
c827ea3a 270 myIsTransPers = Standard_False;
2166f0fa 271 }
bf75be98 272}
2166f0fa
SK
273
274/*----------------------------------------------------------------------*/
275
276//transform_persistence_begin
30f0ad28 277const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
278 const TEL_TRANSFORM_PERSISTENCE* theTransPers)
2166f0fa 279{
c34dba32 280 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
281 myTransPers = theTransPers;
282 if (theTransPers->mode == 0)
2166f0fa 283 {
30f0ad28 284 EndTransformPersistence (theCtx);
c34dba32 285 return aTransPersPrev;
2166f0fa
SK
286 }
287
c34dba32 288 GLint aViewport[4];
c827ea3a 289 OpenGl_Mat4d aModelMatrix, aProjMatrix;
290 theCtx->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport);
291 aModelMatrix.Convert (theCtx->ModelWorldState.Current() * theCtx->WorldViewState.Current());
292 aProjMatrix .Convert (theCtx->ProjectionState.Current());
ca3c13d1 293
c34dba32 294 const GLdouble aViewportW = (GLdouble )aViewport[2];
295 const GLdouble aViewportH = (GLdouble )aViewport[3];
c34dba32 296 if (myIsTransPers)
2166f0fa 297 {
c34dba32 298 // pop matrix stack - it will be overridden later
c827ea3a 299 theCtx->WorldViewState.Pop();
300 theCtx->ProjectionState.Pop();
2166f0fa
SK
301 }
302 else
c34dba32 303 {
2166f0fa 304 myIsTransPers = Standard_True;
c34dba32 305 }
2166f0fa 306
c34dba32 307 // push matrices into stack and reset them
c827ea3a 308 theCtx->WorldViewState.Push();
309 theCtx->ProjectionState.Push();
2166f0fa 310
c34dba32 311 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
312 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
313 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
2166f0fa 314 {
c827ea3a 315 OpenGl_Utils::Project<Standard_Real> (theTransPers->pointX,
316 theTransPers->pointY,
317 theTransPers->pointZ,
318 aModelMatrix,
319 aProjMatrix,
320 aViewport,
8621cdc2 321 aWinX,
c827ea3a 322 aWinY,
323 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!
c827ea3a 332 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix.GetValue (1, 1) : aProjMatrix.GetValue (0, 0));
333 aProjMatrix.ChangeValue (0, 0) *= aDet2;
334 aProjMatrix.ChangeValue (1, 1) *= aDet2;
335 aProjMatrix.ChangeValue (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 {
c827ea3a 342 aModelMatrix.SetValue (0, 3, 0.0);
343 aModelMatrix.SetValue (1, 3, 0.0);
344 aModelMatrix.SetValue (2, 3, 0.0);
345 aProjMatrix .SetValue (0, 3, 0.0);
346 aProjMatrix .SetValue (1, 3, 0.0);
347 aProjMatrix .SetValue (2, 3, 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 {
c827ea3a 359 aModelMatrix.ChangeValue (0, i) /= aScaleX;
360 aModelMatrix.ChangeValue (1, i) /= aScaleY;
361 aModelMatrix.ChangeValue (2, i) /= aScaleZ;
c34dba32 362 }
2166f0fa
SK
363 }
364
c34dba32 365 // prevent rotating - annulate rotate matrix
366 if (theTransPers->mode & TPF_ROTATE)
2166f0fa 367 {
c827ea3a 368 aModelMatrix.SetValue (0, 0, 1.0);
369 aModelMatrix.SetValue (1, 1, 1.0);
370 aModelMatrix.SetValue (2, 2, 1.0);
371
372 aModelMatrix.SetValue (1, 0, 0.0);
373 aModelMatrix.SetValue (2, 0, 0.0);
374 aModelMatrix.SetValue (0, 1, 0.0);
375 aModelMatrix.SetValue (2, 1, 0.0);
376 aModelMatrix.SetValue (0, 2, 0.0);
377 aModelMatrix.SetValue (1, 2, 0.0);
2166f0fa
SK
378 }
379
c34dba32 380 // load computed matrices
c827ea3a 381 theCtx->ModelWorldState.SetIdentity();
382 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
383 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
2166f0fa 384
c34dba32 385 if (theTransPers->mode == TPF_TRIEDRON)
2166f0fa 386 {
c34dba32 387 // move to the window corner
388 if (theTransPers->pointX != 0.0
389 && theTransPers->pointY != 0.0)
2166f0fa 390 {
c34dba32 391 GLdouble aW1, aH1, aW2, aH2, aDummy;
c827ea3a 392
393 OpenGl_Mat4d anIdentity;
394
395 OpenGl_Utils::UnProject<Standard_Real> (0.5 * aViewportW,
396 0.5 * aViewportH,
397 0.0,
398 anIdentity,
399 aProjMatrix,
400 aViewport,
401 aW1,
402 aH1,
403 aDummy);
404
405 OpenGl_Utils::UnProject<Standard_Real> (-0.5 * aViewportW,
406 -0.5 * aViewportH,
407 0.0,
408 anIdentity,
409 aProjMatrix,
410 aViewport,
411 aW2,
412 aH2,
413 aDummy);
ca3c13d1 414
c34dba32 415 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
416 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
417 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
418 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
c827ea3a 419
420 OpenGl_Utils::Translate<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
421 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
2166f0fa
SK
422 }
423 }
c34dba32 424 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
425 {
426 // move to thePoint using saved win-coordinates ('marker-behaviour')
427 GLdouble aMoveX, aMoveY, aMoveZ;
2166f0fa 428
c827ea3a 429 OpenGl_Utils::UnProject<Standard_Real> (aWinX,
430 aWinY,
431 aWinZ,
432 aModelMatrix,
433 aProjMatrix,
434 aViewport,
435 aMoveX,
436 aMoveY,
437 aMoveZ);
438
439 OpenGl_Utils::Translate<Standard_Real> (aModelMatrix, aMoveX, aMoveY, aMoveZ);
440 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
441 }
30f0ad28 442
c827ea3a 443 theCtx->ApplyProjectionMatrix();
c34dba32 444 return aTransPersPrev;
445}
b5ac8292 446
447/*----------------------------------------------------------------------*/
448
25ef750e 449void OpenGl_View::GetMatrices (OpenGl_Mat4& theOrientation,
450 OpenGl_Mat4& theViewMapping) const
b5ac8292 451{
25ef750e 452 theViewMapping = myCamera->ProjectionMatrixF();
453 theOrientation = myCamera->OrientationMatrixF();
b5ac8292 454}
455/*----------------------------------------------------------------------*/