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