0025992: Method Geom2dAPI_InterCurveCurve::Segment(...) requires detail revision
[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),
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
0b0320e7 89 OpenGl_Element::Destroy (NULL, myBgGradientArray);
90 OpenGl_Element::Destroy (NULL, myBgTextureArray);
91 OpenGl_Element::Destroy (NULL, myTextureParams);
bf75be98 92}
93
94void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
95{
536d98e2 96 myTrihedron .Release (theCtx.operator->());
97 myGraduatedTrihedron.Release (theCtx.operator->());
30f0ad28 98
bf75be98 99 if (!myTextureEnv.IsNull())
100 {
101 theCtx->DelayedRelease (myTextureEnv);
102 myTextureEnv.Nullify();
103 }
0b0320e7 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)
bf75be98 114 {
0b0320e7 115 myBgTextureArray->Release (theCtx.operator->());
bf75be98 116 }
bf75be98 117}
2166f0fa 118
bf75be98 119void 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();
e276548b 135 if (!anImage.IsNull())
da0e82aa 136 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
e276548b 137
e276548b 138 myModificationState++;
e276548b 139}
140
141void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
142{
143 mySurfaceDetail = theMode;
144
e276548b 145 myModificationState++;
2166f0fa
SK
146}
147
12381341 148// =======================================================================
149// function : SetBackfacing
150// purpose :
151// =======================================================================
de75ed09 152void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
2166f0fa 153{
de75ed09 154 myBackfacing = theMode;
2166f0fa
SK
155}
156
12381341 157// =======================================================================
158// function : SetLights
159// purpose :
160// =======================================================================
161void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
2166f0fa
SK
162{
163 myLights.Clear();
12381341 164 for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
2166f0fa 165 {
12381341 166 myLights.Append (theViewCtx.ActiveLight[aLightIt]);
2166f0fa 167 }
392ac980 168 myCurrLightSourceState = myStateCounter->Increment();
2166f0fa
SK
169}
170
171/*----------------------------------------------------------------------*/
172
2166f0fa
SK
173//call_togl_setvisualisation
174void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
175{
176 myVisualization = AContext.Visualization;
8625ef7e 177 myShadingModel = (Visual3d_TypeOfModel )AContext.Model;
2166f0fa
SK
178}
179
180/*----------------------------------------------------------------------*/
181
182//call_togl_cliplimit
bf75be98 183void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
2166f0fa 184{
b5ac8292 185 myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
186 myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
2166f0fa 187
bf75be98 188 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
189 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
2166f0fa
SK
190}
191
192/*----------------------------------------------------------------------*/
193
bf75be98 194void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
195 const Standard_Boolean theFlag)
2166f0fa 196{
bf75be98 197 if (!theFlag)
2166f0fa
SK
198 {
199 myFog.IsOn = Standard_False;
200 }
201 else
202 {
203 myFog.IsOn = Standard_True;
204
b5ac8292 205 myFog.Front = theCView.Context.DepthFrontPlane;
206 myFog.Back = theCView.Context.DepthBackPlane;
2166f0fa 207
bf75be98 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;
2166f0fa
SK
212 }
213}
214
215/*----------------------------------------------------------------------*/
216
536d98e2 217void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
a174a3c5 218 const Quantity_NameOfColor theColor,
219 const Standard_Real theScale,
220 const Standard_Boolean theAsWireframe)
2166f0fa 221{
536d98e2 222 myToShowTrihedron = true;
223 myTrihedron.SetWireframe (theAsWireframe);
224 myTrihedron.SetPosition (thePosition);
225 myTrihedron.SetScale (theScale);
226 myTrihedron.SetLabelsColor (theColor);
2166f0fa
SK
227}
228
229/*----------------------------------------------------------------------*/
230
a174a3c5 231void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 232{
536d98e2 233 myToShowTrihedron = false;
234 myTrihedron.Release (theCtx.operator->());
2166f0fa
SK
235}
236
237/*----------------------------------------------------------------------*/
238
536d98e2 239void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
a79f67f8 240 const Graphic3d_GraduatedTrihedron& theData)
2166f0fa 241{
536d98e2 242 myToShowGradTrihedron = true;
243 myGraduatedTrihedron.SetValues (theCtx, theData);
2166f0fa
SK
244}
245
246/*----------------------------------------------------------------------*/
247
a174a3c5 248void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 249{
536d98e2 250 myToShowGradTrihedron = false;
251 myGraduatedTrihedron.Release (theCtx.operator->());
2166f0fa
SK
252}
253
254/*----------------------------------------------------------------------*/
255
256//transform_persistence_end
30f0ad28 257void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
2166f0fa 258{
c34dba32 259 if (myIsTransPers)
2166f0fa 260 {
c827ea3a 261 theCtx->WorldViewState.Pop();
262 theCtx->ProjectionState.Pop();
30f0ad28 263
c827ea3a 264 theCtx->ApplyProjectionMatrix();
30f0ad28 265
c827ea3a 266 myIsTransPers = Standard_False;
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
c34dba32 284 GLint aViewport[4];
c827ea3a 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());
ca3c13d1 289
c34dba32 290 const GLdouble aViewportW = (GLdouble )aViewport[2];
291 const GLdouble aViewportH = (GLdouble )aViewport[3];
c34dba32 292 if (myIsTransPers)
2166f0fa 293 {
c34dba32 294 // pop matrix stack - it will be overridden later
c827ea3a 295 theCtx->WorldViewState.Pop();
296 theCtx->ProjectionState.Pop();
2166f0fa
SK
297 }
298 else
c34dba32 299 {
2166f0fa 300 myIsTransPers = Standard_True;
c34dba32 301 }
2166f0fa 302
c34dba32 303 // push matrices into stack and reset them
c827ea3a 304 theCtx->WorldViewState.Push();
305 theCtx->ProjectionState.Push();
2166f0fa 306
c34dba32 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)
2166f0fa 310 {
c827ea3a 311 OpenGl_Utils::Project<Standard_Real> (theTransPers->pointX,
312 theTransPers->pointY,
313 theTransPers->pointZ,
314 aModelMatrix,
315 aProjMatrix,
316 aViewport,
8621cdc2 317 aWinX,
c827ea3a 318 aWinY,
319 aWinZ);
2166f0fa
SK
320 }
321
c34dba32 322 // prevent zooming
323 if ((theTransPers->mode & TPF_ZOOM)
324 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 325 {
c34dba32 326 // compute fixed-zoom multiplier
327 // actually function works ugly with TelPerspective!
c827ea3a 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;
2166f0fa
SK
332 }
333
c34dba32 334 // prevent translation - annulate translate matrix
335 if ((theTransPers->mode & TPF_PAN)
336 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 337 {
c827ea3a 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);
2166f0fa 344 }
2166f0fa 345
c34dba32 346 // prevent scaling-on-axis
347 if (theTransPers->mode & TPF_ZOOM)
348 {
b5ac8292 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();
c34dba32 353 for (int i = 0; i < 3; ++i)
354 {
c827ea3a 355 aModelMatrix.ChangeValue (0, i) /= aScaleX;
356 aModelMatrix.ChangeValue (1, i) /= aScaleY;
357 aModelMatrix.ChangeValue (2, i) /= aScaleZ;
c34dba32 358 }
2166f0fa
SK
359 }
360
c34dba32 361 // prevent rotating - annulate rotate matrix
362 if (theTransPers->mode & TPF_ROTATE)
2166f0fa 363 {
c827ea3a 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);
2166f0fa
SK
374 }
375
c34dba32 376 // load computed matrices
c827ea3a 377 theCtx->ModelWorldState.SetIdentity();
378 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
379 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
2166f0fa 380
c34dba32 381 if (theTransPers->mode == TPF_TRIEDRON)
2166f0fa 382 {
c34dba32 383 // move to the window corner
384 if (theTransPers->pointX != 0.0
385 && theTransPers->pointY != 0.0)
2166f0fa 386 {
c34dba32 387 GLdouble aW1, aH1, aW2, aH2, aDummy;
c827ea3a 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);
ca3c13d1 410
c34dba32 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;
c827ea3a 415
416 OpenGl_Utils::Translate<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
417 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
2166f0fa
SK
418 }
419 }
c34dba32 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;
2166f0fa 424
c827ea3a 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 }
30f0ad28 438
c827ea3a 439 theCtx->ApplyProjectionMatrix();
c34dba32 440 return aTransPersPrev;
441}
b5ac8292 442
443/*----------------------------------------------------------------------*/
444
25ef750e 445void OpenGl_View::GetMatrices (OpenGl_Mat4& theOrientation,
446 OpenGl_Mat4& theViewMapping) const
b5ac8292 447{
25ef750e 448 theViewMapping = myCamera->ProjectionMatrixF();
449 theOrientation = myCamera->OrientationMatrixF();
b5ac8292 450}
451/*----------------------------------------------------------------------*/