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