0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / OpenGl / OpenGl_View.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
e276548b 20#ifdef HAVE_CONFIG_H
21 #include <config.h>
22#endif
23
30f0ad28 24#include <NCollection_Mat4.hxx>
5f8b738e 25
bf75be98 26#include <OpenGl_Context.hxx>
2166f0fa 27#include <OpenGl_Display.hxx>
30f0ad28 28#include <OpenGl_GlCore11.hxx>
29#include <OpenGl_GraduatedTrihedron.hxx>
392ac980 30#include <OpenGl_GraphicDriver.hxx>
30f0ad28 31#include <OpenGl_ShaderManager.hxx>
bf75be98 32#include <OpenGl_Texture.hxx>
2166f0fa 33#include <OpenGl_Trihedron.hxx>
2166f0fa 34#include <OpenGl_transform_persistence.hxx>
30f0ad28 35#include <OpenGl_View.hxx>
36#include <OpenGl_Workspace.hxx>
2166f0fa 37
bf75be98 38#include <Graphic3d_TextureEnv.hxx>
39
2166f0fa
SK
40IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
41IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
42
43/*----------------------------------------------------------------------*/
44
45static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
46static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE };
47static 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 } };
48static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
49static const OPENGL_EXTRA_REP myDefaultExtra =
50{
51 //vrp
52 { 0.F, 0.F, 0.F },
53 //vpn
54 { 0.F, 0.F, 1.F },
55 //vup
56 { 0.F, 1.F, 0.F },
57 //map
58 {
59 //window
60 { 0.F, 0.F, 1.F, 1.F },
61 //viewport
62 { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F },
63 //proj
64 TelParallel,
65 //prp
66 { 0.F, 0.F, 0.F },
67 //vpd
68 0.F,
69 //fpd
70 0.F,
71 //bpd
72 -1.F
73 },
74 //scaleFactors
75 { 1.F, 1.F, 1.F }
76};
77
78static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
79static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
c34dba32 80static const GLdouble THE_IDENTITY_MATRIX[4][4] =
81{
82 {1.0, 0.0, 0.0, 0.0},
83 {0.0, 1.0, 0.0, 0.0},
84 {0.0, 0.0, 1.0, 0.0},
85 {0.0, 0.0, 0.0, 1.0}
86};
2166f0fa
SK
87
88/*----------------------------------------------------------------------*/
89
392ac980 90OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
91 OpenGl_StateCounter* theCounter)
bf75be98 92: mySurfaceDetail(Visual3d_TOD_NONE),
2166f0fa
SK
93 myBackfacing(0),
94 myBgTexture(myDefaultBgTexture),
95 myBgGradient(myDefaultBgGradient),
96 //myOrientationMatrix(myDefaultMatrix),
97 //myMappingMatrix(myDefaultMatrix),
98 //shield_indicator = TOn,
99 //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
100 //border_indicator = TOff,
101 //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
102 //active_status = TOn,
103 myZClip(myDefaultZClip),
104 myExtra(myDefaultExtra),
105 myFog(myDefaultFog),
2f6cb3ac 106 myTrihedron(NULL),
107 myGraduatedTrihedron(NULL),
2166f0fa
SK
108 myVisualization(AContext.Visualization),
109 myIntShadingMethod(TEL_SM_GOURAUD),
110 myAntiAliasing(Standard_False),
2166f0fa 111 myTransPers(&myDefaultTransPers),
30f0ad28 112 myIsTransPers(Standard_False),
392ac980 113 myStateCounter (theCounter),
114 myLastOrientationState (0, 0),
115 myLastViewMappingState (0, 0),
116 myLastLightSourceState (0, 0)
2166f0fa
SK
117{
118 // Initialize matrices
119 memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
120 memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3));
121
122 // Shading method
123 switch (AContext.Model)
124 {
125 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
126 case 3 : /* VISUAL3D_TOM_VERTEX */
127 myIntShadingMethod = TEL_SM_GOURAUD;
128 break;
129 default :
130 myIntShadingMethod = TEL_SM_FLAT;
131 break;
132 }
e276548b 133
392ac980 134 myCurrOrientationState = myStateCounter->Increment(); // <-- delete after merge with camera
135 myCurrViewMappingState = myStateCounter->Increment(); // <-- delete after merge with camera
136 myCurrLightSourceState = myStateCounter->Increment();
137
e276548b 138#ifdef HAVE_OPENCL
139 myModificationState = 1; // initial state
140#endif
2166f0fa
SK
141}
142
143/*----------------------------------------------------------------------*/
144
145OpenGl_View::~OpenGl_View ()
146{
bf75be98 147 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
148}
149
150void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
151{
a174a3c5 152 OpenGl_Element::Destroy (theCtx, myTrihedron);
153 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
30f0ad28 154
bf75be98 155 if (!myTextureEnv.IsNull())
156 {
157 theCtx->DelayedRelease (myTextureEnv);
158 myTextureEnv.Nullify();
159 }
160 if (myBgTexture.TexId != 0)
161 {
162 glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
163 myBgTexture.TexId = 0;
164 }
bf75be98 165}
2166f0fa 166
bf75be98 167void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
168 const Handle(Graphic3d_TextureEnv)& theTexture)
169{
170 if (!myTextureEnv.IsNull())
171 {
172 theCtx->DelayedRelease (myTextureEnv);
173 myTextureEnv.Nullify();
174 }
175
176 if (theTexture.IsNull())
177 {
178 return;
179 }
180
181 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
182 Handle(Image_PixMap) anImage = theTexture->GetImage();
e276548b 183 if (!anImage.IsNull())
da0e82aa 184 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
e276548b 185
186#ifdef HAVE_OPENCL
187 myModificationState++;
188#endif
189}
190
191void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
192{
193 mySurfaceDetail = theMode;
194
195#ifdef HAVE_OPENCL
196 myModificationState++;
197#endif
2166f0fa
SK
198}
199
12381341 200// =======================================================================
201// function : SetBackfacing
202// purpose :
203// =======================================================================
de75ed09 204void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
2166f0fa 205{
de75ed09 206 myBackfacing = theMode;
2166f0fa
SK
207}
208
12381341 209// =======================================================================
210// function : SetLights
211// purpose :
212// =======================================================================
213void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
2166f0fa
SK
214{
215 myLights.Clear();
12381341 216 for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
2166f0fa 217 {
12381341 218 myLights.Append (theViewCtx.ActiveLight[aLightIt]);
2166f0fa 219 }
392ac980 220 myCurrLightSourceState = myStateCounter->Increment();
2166f0fa
SK
221}
222
223/*----------------------------------------------------------------------*/
224
2166f0fa
SK
225//call_togl_setvisualisation
226void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
227{
228 myVisualization = AContext.Visualization;
229 // Shading method
230 switch (AContext.Model)
231 {
232 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
233 case 3 : /* VISUAL3D_TOM_VERTEX */
234 myIntShadingMethod = TEL_SM_GOURAUD;
235 break;
236 default :
237 myIntShadingMethod = TEL_SM_FLAT;
238 break;
239 }
240}
241
242/*----------------------------------------------------------------------*/
243
244//call_togl_cliplimit
bf75be98 245void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
2166f0fa
SK
246{
247 myZClip.Back.Limit =
bf75be98 248 (theCView.Context.ZClipBackPlane - theCView.Mapping.BackPlaneDistance) /
249 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa 250 myZClip.Front.Limit =
bf75be98 251 (theCView.Context.ZClipFrontPlane - theCView.Mapping.BackPlaneDistance) /
252 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
253 if (myZClip.Back.Limit < 0.0f)
254 myZClip.Back.Limit = 0.0f;
255 if (myZClip.Front.Limit > 1.0f)
256 myZClip.Front.Limit = 1.0f;
257 if (myZClip.Back.Limit > myZClip.Front.Limit)
2166f0fa 258 {
bf75be98 259 myZClip.Back.Limit = 0.0f;
260 myZClip.Front.Limit = 1.0f;
2166f0fa
SK
261 }
262
bf75be98 263 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
264 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
2166f0fa
SK
265}
266
267/*----------------------------------------------------------------------*/
268
269//call_togl_viewmapping
fd4a6963 270void OpenGl_View::SetMapping (const Handle(OpenGl_Display)& theGlDisplay,
271 const Graphic3d_CView& theCView)
2166f0fa 272{
bf75be98 273 const float ratio = theCView.DefWindow.dy / theCView.DefWindow.dx;
274 const float r_ratio = theCView.DefWindow.dx / theCView.DefWindow.dy;
2166f0fa
SK
275
276 TEL_VIEW_MAPPING Map;
277
bf75be98 278 Map.window.xmin = theCView.Mapping.WindowLimit.um;
279 Map.window.ymin = theCView.Mapping.WindowLimit.vm;
280 Map.window.xmax = theCView.Mapping.WindowLimit.uM;
281 Map.window.ymax = theCView.Mapping.WindowLimit.vM;
2166f0fa
SK
282
283 Map.viewport.xmin = 0.F;
284 Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio );
285 Map.viewport.ymin = 0.F;
286 Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio );
287 Map.viewport.zmin = 0.F;
288 Map.viewport.zmax = 1.F;
289
bf75be98 290 // projection type
291 switch (theCView.Mapping.Projection)
2166f0fa
SK
292 {
293 case 0 :
294 Map.proj = TelPerspective;
295 break;
296 case 1 :
297 Map.proj = TelParallel;
298 break;
299 }
300
bf75be98 301 // projection reference point
302 Map.prp[0] = theCView.Mapping.ProjectionReferencePoint.x;
303 Map.prp[1] = theCView.Mapping.ProjectionReferencePoint.y;
304 Map.prp[2] = theCView.Mapping.ProjectionReferencePoint.z;
fd4a6963 305 if (!theGlDisplay.IsNull() && !theGlDisplay->Walkthrough())
bf75be98 306 Map.prp[2] += theCView.Mapping.FrontPlaneDistance;
2166f0fa 307
bf75be98 308 // view plane distance
309 Map.vpd = theCView.Mapping.ViewPlaneDistance;
2166f0fa 310
bf75be98 311 // back plane distance
312 Map.bpd = theCView.Mapping.BackPlaneDistance;
2166f0fa 313
bf75be98 314 // front plane distance
315 Map.fpd = theCView.Mapping.FrontPlaneDistance;
2166f0fa
SK
316
317 Tint err_ind = 0;
318
bf75be98 319 // use user-defined matrix
320 if (theCView.Mapping.IsCustomMatrix)
2166f0fa
SK
321 {
322 int i, j;
323 for( i = 0; i < 4; i++ )
324 for( j = 0; j < 4; j++ )
bf75be98 325 myMappingMatrix[i][j] = theCView.Mapping.ProjectionMatrix[i][j];
2166f0fa 326 }
bf75be98 327 else
fd4a6963 328 TelEvalViewMappingMatrix (theGlDisplay, &Map, &err_ind, myMappingMatrix);
2166f0fa 329
bf75be98 330 if (!err_ind)
2166f0fa 331 myExtra.map = Map;
30f0ad28 332
392ac980 333 myCurrViewMappingState = myStateCounter->Increment();
2166f0fa
SK
334}
335
336/*----------------------------------------------------------------------*/
337
338//call_togl_vieworientation
bf75be98 339void OpenGl_View::SetOrientation (const Graphic3d_CView& theCView)
2166f0fa
SK
340{
341 Tfloat Vrp[3];
342 Tfloat Vpn[3];
343 Tfloat Vup[3];
344 Tfloat ScaleFactors[3];
345
bf75be98 346 Vrp[0] = theCView.Orientation.ViewReferencePoint.x;
347 Vrp[1] = theCView.Orientation.ViewReferencePoint.y;
348 Vrp[2] = theCView.Orientation.ViewReferencePoint.z;
2166f0fa 349
bf75be98 350 Vpn[0] = theCView.Orientation.ViewReferencePlane.x;
351 Vpn[1] = theCView.Orientation.ViewReferencePlane.y;
352 Vpn[2] = theCView.Orientation.ViewReferencePlane.z;
2166f0fa 353
bf75be98 354 Vup[0] = theCView.Orientation.ViewReferenceUp.x;
355 Vup[1] = theCView.Orientation.ViewReferenceUp.y;
356 Vup[2] = theCView.Orientation.ViewReferenceUp.z;
2166f0fa 357
bf75be98 358 ScaleFactors[0] = theCView.Orientation.ViewScaleX;
359 ScaleFactors[1] = theCView.Orientation.ViewScaleY;
360 ScaleFactors[2] = theCView.Orientation.ViewScaleZ;
2166f0fa
SK
361
362 Tint err_ind = 0;
363
364 // use user-defined matrix
bf75be98 365 if (theCView.Orientation.IsCustomMatrix)
2166f0fa
SK
366 {
367 int i, j;
368 for( i = 0; i < 4; i++ )
369 for( j = 0; j < 4; j++ )
bf75be98 370 myOrientationMatrix[i][j] = theCView.Orientation.ModelViewMatrix[i][j];
2166f0fa
SK
371 }
372 else
bf75be98 373 {
374 TelEvalViewOrientationMatrix (Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix);
375 }
2166f0fa 376
bf75be98 377 if (!err_ind)
2166f0fa
SK
378 {
379 myExtra.vrp[0] = Vrp[0];
380 myExtra.vrp[1] = Vrp[1];
381 myExtra.vrp[2] = Vrp[2];
382
383 myExtra.vpn[0] = Vpn[0];
384 myExtra.vpn[1] = Vpn[1];
385 myExtra.vpn[2] = Vpn[2];
386
387 myExtra.vup[0] = Vup[0];
388 myExtra.vup[1] = Vup[1];
389 myExtra.vup[2] = Vup[2];
390
391 myExtra.scaleFactors[0] = ScaleFactors[0],
392 myExtra.scaleFactors[1] = ScaleFactors[1],
393 myExtra.scaleFactors[2] = ScaleFactors[2];
394 }
30f0ad28 395
392ac980 396 myCurrOrientationState = myStateCounter->Increment();
2166f0fa
SK
397}
398
399/*----------------------------------------------------------------------*/
400
bf75be98 401void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
402 const Standard_Boolean theFlag)
2166f0fa 403{
bf75be98 404 if (!theFlag)
2166f0fa
SK
405 {
406 myFog.IsOn = Standard_False;
407 }
408 else
409 {
410 myFog.IsOn = Standard_True;
411
412 myFog.Front =
bf75be98 413 (theCView.Context.DepthFrontPlane - theCView.Mapping.BackPlaneDistance) /
414 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa
SK
415
416 myFog.Back =
bf75be98 417 (theCView.Context.DepthBackPlane - theCView.Mapping.BackPlaneDistance) /
418 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa
SK
419
420 if (myFog.Front < 0.F)
421 myFog.Front = 0.F;
422 else if (myFog.Front > 1.F)
423 myFog.Front = 1.F;
424
425 if (myFog.Back < 0.F)
426 myFog.Back = 0.F;
427 else if (myFog.Back > 1.F)
428 myFog.Back = 1.F;
429
430 if (myFog.Back > myFog.Front)
431 {
432 myFog.Front = 1.F;
433 myFog.Back = 0.F;
434 }
435
bf75be98 436 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
437 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
438 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
439 myFog.Color.rgb[3] = 1.0f;
2166f0fa
SK
440 }
441}
442
443/*----------------------------------------------------------------------*/
444
a174a3c5 445void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)& theCtx,
446 const Aspect_TypeOfTriedronPosition thePosition,
447 const Quantity_NameOfColor theColor,
448 const Standard_Real theScale,
449 const Standard_Boolean theAsWireframe)
2166f0fa 450{
a174a3c5 451 OpenGl_Element::Destroy (theCtx, myTrihedron);
452 myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
2166f0fa
SK
453}
454
455/*----------------------------------------------------------------------*/
456
a174a3c5 457void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 458{
a174a3c5 459 OpenGl_Element::Destroy (theCtx, myTrihedron);
2166f0fa
SK
460}
461
462/*----------------------------------------------------------------------*/
463
a174a3c5 464void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
465 const Graphic3d_CGraduatedTrihedron& theData)
2166f0fa 466{
a174a3c5 467 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
468 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
2166f0fa
SK
469}
470
471/*----------------------------------------------------------------------*/
472
a174a3c5 473void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 474{
a174a3c5 475 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
2166f0fa
SK
476}
477
478/*----------------------------------------------------------------------*/
479
480//transform_persistence_end
30f0ad28 481void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
2166f0fa 482{
c34dba32 483 if (myIsTransPers)
2166f0fa 484 {
c34dba32 485 // restore matrix
2166f0fa 486 glMatrixMode (GL_PROJECTION);
c34dba32 487 glPopMatrix();
2166f0fa 488 glMatrixMode (GL_MODELVIEW);
c34dba32 489 glPopMatrix();
2166f0fa 490 myIsTransPers = Standard_False;
30f0ad28 491
492 // Note: the approach of accessing OpenGl matrices is used now since the matrix
493 // manipulation are made with help of OpenGl methods. This might be replaced by
494 // direct computation of matrices by OCC subroutines.
495 Tmatrix3 aResultWorldView;
496 glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
497
498 Tmatrix3 aResultProjection;
499 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
500
501 // Set OCCT state uniform variables
502 theCtx->ShaderManager()->RevertWorldViewStateTo (aResultWorldView);
503 theCtx->ShaderManager()->RevertProjectionStateTo (aResultProjection);
2166f0fa 504 }
bf75be98 505}
2166f0fa
SK
506
507/*----------------------------------------------------------------------*/
508
509//transform_persistence_begin
30f0ad28 510const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
511 const TEL_TRANSFORM_PERSISTENCE* theTransPers)
2166f0fa 512{
c34dba32 513 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
514 myTransPers = theTransPers;
515 if (theTransPers->mode == 0)
2166f0fa 516 {
30f0ad28 517 EndTransformPersistence (theCtx);
c34dba32 518 return aTransPersPrev;
2166f0fa
SK
519 }
520
c34dba32 521 GLint aViewport[4];
522 GLdouble aModelMatrix[4][4];
523 GLdouble aProjMatrix[4][4];
524 glGetIntegerv (GL_VIEWPORT, aViewport);
525 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
526 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble *)aProjMatrix);
527 const GLdouble aViewportW = (GLdouble )aViewport[2];
528 const GLdouble aViewportH = (GLdouble )aViewport[3];
2166f0fa 529
c34dba32 530 if (myIsTransPers)
2166f0fa 531 {
c34dba32 532 // pop matrix stack - it will be overridden later
2166f0fa 533 glMatrixMode (GL_PROJECTION);
c34dba32 534 glPopMatrix();
2166f0fa 535 glMatrixMode (GL_MODELVIEW);
c34dba32 536 glPopMatrix();
2166f0fa
SK
537 }
538 else
c34dba32 539 {
2166f0fa 540 myIsTransPers = Standard_True;
c34dba32 541 }
2166f0fa 542
c34dba32 543 // push matrices into stack and reset them
544 glMatrixMode (GL_MODELVIEW);
2166f0fa
SK
545 glPushMatrix();
546 glLoadIdentity();
547
c34dba32 548 glMatrixMode (GL_PROJECTION);
2166f0fa
SK
549 glPushMatrix();
550 glLoadIdentity();
551
c34dba32 552 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
553 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
554 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
2166f0fa 555 {
c34dba32 556 gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
557 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
558 &aWinX, &aWinY, &aWinZ);
2166f0fa
SK
559 }
560
c34dba32 561 // prevent zooming
562 if ((theTransPers->mode & TPF_ZOOM)
563 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 564 {
c34dba32 565 // compute fixed-zoom multiplier
566 // actually function works ugly with TelPerspective!
567 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix[1][1] : aProjMatrix[0][0]);
568 aProjMatrix[0][0] *= aDet2;
569 aProjMatrix[1][1] *= aDet2;
570 aProjMatrix[2][2] *= aDet2;
2166f0fa
SK
571 }
572
c34dba32 573 // prevent translation - annulate translate matrix
574 if ((theTransPers->mode & TPF_PAN)
575 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 576 {
c34dba32 577 aModelMatrix[3][0] = 0.0;
578 aModelMatrix[3][1] = 0.0;
579 aModelMatrix[3][2] = 0.0;
580 aProjMatrix [3][0] = 0.0;
581 aProjMatrix [3][1] = 0.0;
582 aProjMatrix [3][2] = 0.0;
2166f0fa 583 }
2166f0fa 584
c34dba32 585 // prevent scaling-on-axis
586 if (theTransPers->mode & TPF_ZOOM)
587 {
588 const double aScaleX = myExtra.scaleFactors[0];
589 const double aScaleY = myExtra.scaleFactors[1];
590 const double aScaleZ = myExtra.scaleFactors[2];
591 for (int i = 0; i < 3; ++i)
592 {
593 aModelMatrix[0][i] /= aScaleX;
594 aModelMatrix[1][i] /= aScaleY;
595 aModelMatrix[2][i] /= aScaleZ;
596 }
2166f0fa
SK
597 }
598
c34dba32 599 // prevent rotating - annulate rotate matrix
600 if (theTransPers->mode & TPF_ROTATE)
2166f0fa 601 {
c34dba32 602 aModelMatrix[0][0] = 1.0;
603 aModelMatrix[1][1] = 1.0;
604 aModelMatrix[2][2] = 1.0;
605
606 aModelMatrix[1][0] = 0.0;
607 aModelMatrix[2][0] = 0.0;
608 aModelMatrix[0][1] = 0.0;
609 aModelMatrix[2][1] = 0.0;
610 aModelMatrix[0][2] = 0.0;
611 aModelMatrix[1][2] = 0.0;
2166f0fa
SK
612 }
613
c34dba32 614 // load computed matrices
2166f0fa 615 glMatrixMode (GL_MODELVIEW);
c34dba32 616 glMultMatrixd ((GLdouble* )aModelMatrix);
2166f0fa
SK
617
618 glMatrixMode (GL_PROJECTION);
c34dba32 619 glMultMatrixd ((GLdouble* )aProjMatrix);
2166f0fa 620
c34dba32 621 if (theTransPers->mode == TPF_TRIEDRON)
2166f0fa 622 {
c34dba32 623 // move to the window corner
624 if (theTransPers->pointX != 0.0
625 && theTransPers->pointY != 0.0)
2166f0fa 626 {
c34dba32 627 GLdouble aW1, aH1, aW2, aH2, aDummy;
628 glMatrixMode (GL_PROJECTION);
629 gluUnProject ( 0.5 * aViewportW, 0.5 * aViewportH, 0.0,
630 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
631 &aW1, &aH1, &aDummy);
632 gluUnProject (-0.5 * aViewportW, -0.5 * aViewportH, 0.0,
633 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
634 &aW2, &aH2, &aDummy);
635 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
636 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
637 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
638 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
639 glTranslated (aMoveX, aMoveY, 0.0);
2166f0fa
SK
640 }
641 }
c34dba32 642 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
643 {
644 // move to thePoint using saved win-coordinates ('marker-behaviour')
645 GLdouble aMoveX, aMoveY, aMoveZ;
646 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
647 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble* )aProjMatrix);
648 gluUnProject (aWinX, aWinY, aWinZ,
649 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
650 &aMoveX, &aMoveY, &aMoveZ);
2166f0fa 651
c34dba32 652 glMatrixMode (GL_MODELVIEW);
653 glTranslated (aMoveX, aMoveY, aMoveZ);
654 }
2166f0fa 655
30f0ad28 656 // Note: the approach of accessing OpenGl matrices is used now since the matrix
657 // manipulation are made with help of OpenGl methods. This might be replaced by
658 // direct computation of matrices by OCC subroutines.
659 Tmatrix3 aResultWorldView;
660 glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
661
662 Tmatrix3 aResultProjection;
663 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
664
665 // Set OCCT state uniform variables
666 theCtx->ShaderManager()->UpdateWorldViewStateTo (aResultWorldView);
667 theCtx->ShaderManager()->UpdateProjectionStateTo (aResultProjection);
668
c34dba32 669 return aTransPersPrev;
670}