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