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