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