0024228: TKOpenGL - destroy GL context at view close
[occt.git] / src / OpenGl / OpenGl_View.cxx
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
20 #include <OpenGl_GlCore11.hxx>
21
22 #include <OpenGl_View.hxx>
23 #include <OpenGl_Context.hxx>
24 #include <OpenGl_Workspace.hxx>
25 #include <OpenGl_Display.hxx>
26
27 #include <OpenGl_Texture.hxx>
28 #include <OpenGl_Trihedron.hxx>
29 #include <OpenGl_GraduatedTrihedron.hxx>
30
31 #include <OpenGl_transform_persistence.hxx>
32
33 #include <Graphic3d_TextureEnv.hxx>
34
35 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
36 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
37
38 /*----------------------------------------------------------------------*/
39
40 static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
41 static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE };
42 static 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 } };
43 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
44 static 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
73 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
74 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
75 static 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 };
82
83 /*----------------------------------------------------------------------*/
84
85 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
86 : mySurfaceDetail(Visual3d_TOD_NONE),
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),
100   myTrihedron(NULL),
101   myGraduatedTrihedron(NULL),
102   myVisualization(AContext.Visualization),
103   myIntShadingMethod(TEL_SM_GOURAUD),
104   myAntiAliasing(Standard_False),
105   myTransPers(&myDefaultTransPers),
106   myIsTransPers(Standard_False)  
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
127 OpenGl_View::~OpenGl_View ()
128 {
129   ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
130 }
131
132 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
133 {
134   OpenGl_Element::Destroy (theCtx, myTrihedron);
135   OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
136    
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   }
147 }
148
149 void 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();
165   if( !anImage.IsNull())
166     myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
167 }
168
169 /*----------------------------------------------------------------------*/
170
171 void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
172 {
173   myBackfacing = theMode;
174 }
175
176 /*----------------------------------------------------------------------*/
177
178 //call_togl_setlight
179 void 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;
190     memset(&rep,0,sizeof(rep));
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
249 //call_togl_setvisualisation
250 void 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
269 void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
270 {
271   myZClip.Back.Limit =
272     (theCView.Context.ZClipBackPlane     - theCView.Mapping.BackPlaneDistance) /
273     (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
274   myZClip.Front.Limit =
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)
282   {
283     myZClip.Back.Limit  = 0.0f;
284     myZClip.Front.Limit = 1.0f;
285   }
286
287   myZClip.Back.IsOn  = (theCView.Context.BackZClipping  != 0);
288   myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
289 }
290
291 /*----------------------------------------------------------------------*/
292
293 //call_togl_viewmapping
294 void OpenGl_View::SetMapping (const Handle(OpenGl_Display)& theGlDisplay,
295                               const Graphic3d_CView&        theCView)
296 {
297   const float ratio   = theCView.DefWindow.dy / theCView.DefWindow.dx;
298   const float r_ratio = theCView.DefWindow.dx / theCView.DefWindow.dy;
299
300   TEL_VIEW_MAPPING Map;
301
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;
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
314   // projection type
315   switch (theCView.Mapping.Projection)
316   {
317     case 0 :
318       Map.proj = TelPerspective;
319       break;
320     case 1 :
321       Map.proj = TelParallel;
322       break;
323   }
324
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;
329   if (!theGlDisplay.IsNull() && !theGlDisplay->Walkthrough())
330     Map.prp[2] += theCView.Mapping.FrontPlaneDistance;
331
332   // view plane distance
333   Map.vpd = theCView.Mapping.ViewPlaneDistance;
334
335   // back plane distance
336   Map.bpd = theCView.Mapping.BackPlaneDistance;
337
338   // front plane distance
339   Map.fpd = theCView.Mapping.FrontPlaneDistance;
340
341   Tint err_ind = 0;
342
343   // use user-defined matrix
344   if (theCView.Mapping.IsCustomMatrix)
345   {
346     int i, j;
347     for( i = 0; i < 4; i++ )
348       for( j = 0; j < 4; j++ )
349         myMappingMatrix[i][j] = theCView.Mapping.ProjectionMatrix[i][j];
350   }
351   else
352     TelEvalViewMappingMatrix (theGlDisplay, &Map, &err_ind, myMappingMatrix);
353
354   if (!err_ind)
355     myExtra.map = Map;
356 }
357
358 /*----------------------------------------------------------------------*/
359
360 //call_togl_vieworientation
361 void OpenGl_View::SetOrientation (const Graphic3d_CView& theCView)
362 {
363   Tfloat Vrp[3];
364   Tfloat Vpn[3];
365   Tfloat Vup[3];
366   Tfloat ScaleFactors[3];
367
368   Vrp[0] = theCView.Orientation.ViewReferencePoint.x;
369   Vrp[1] = theCView.Orientation.ViewReferencePoint.y;
370   Vrp[2] = theCView.Orientation.ViewReferencePoint.z;
371
372   Vpn[0] = theCView.Orientation.ViewReferencePlane.x;
373   Vpn[1] = theCView.Orientation.ViewReferencePlane.y;
374   Vpn[2] = theCView.Orientation.ViewReferencePlane.z;
375
376   Vup[0] = theCView.Orientation.ViewReferenceUp.x;
377   Vup[1] = theCView.Orientation.ViewReferenceUp.y;
378   Vup[2] = theCView.Orientation.ViewReferenceUp.z;
379
380   ScaleFactors[0] = theCView.Orientation.ViewScaleX;
381   ScaleFactors[1] = theCView.Orientation.ViewScaleY;
382   ScaleFactors[2] = theCView.Orientation.ViewScaleZ;
383
384   Tint err_ind = 0;
385
386   // use user-defined matrix
387   if (theCView.Orientation.IsCustomMatrix)
388   {
389     int i, j;
390     for( i = 0; i < 4; i++ )
391       for( j = 0; j < 4; j++ )
392         myOrientationMatrix[i][j] = theCView.Orientation.ModelViewMatrix[i][j];
393   }
394   else
395   {
396     TelEvalViewOrientationMatrix (Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix);
397   }
398
399   if (!err_ind)
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
421 void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
422                           const Standard_Boolean theFlag)
423 {
424   if (!theFlag)
425   {
426     myFog.IsOn = Standard_False;
427   }
428   else
429   {
430     myFog.IsOn = Standard_True;
431
432     myFog.Front =
433       (theCView.Context.DepthFrontPlane    - theCView.Mapping.BackPlaneDistance) /
434       (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
435
436     myFog.Back =
437       (theCView.Context.DepthBackPlane     - theCView.Mapping.BackPlaneDistance) /
438       (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
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
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;
460   }
461 }
462
463 /*----------------------------------------------------------------------*/
464
465 void 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)
470 {
471   OpenGl_Element::Destroy (theCtx, myTrihedron);
472   myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
473 }
474
475 /*----------------------------------------------------------------------*/
476
477 void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
478 {
479   OpenGl_Element::Destroy (theCtx, myTrihedron);
480 }
481
482 /*----------------------------------------------------------------------*/
483
484 void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)&        theCtx,
485                                              const Graphic3d_CGraduatedTrihedron& theData)
486 {
487   OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
488   myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
489 }
490
491 /*----------------------------------------------------------------------*/
492
493 void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
494 {
495   OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
496 }
497
498 /*----------------------------------------------------------------------*/
499
500 //transform_persistence_end
501 void OpenGl_View::EndTransformPersistence()
502 {
503   if (myIsTransPers)
504   {
505     // restore matrix
506     glMatrixMode (GL_PROJECTION);
507     glPopMatrix();
508     glMatrixMode (GL_MODELVIEW);
509     glPopMatrix();
510     myIsTransPers = Standard_False;
511   }
512 }
513
514 /*----------------------------------------------------------------------*/
515
516 //transform_persistence_begin
517 const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE* theTransPers)
518 {
519   const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
520   myTransPers = theTransPers;
521   if (theTransPers->mode == 0)
522   {
523     EndTransformPersistence();
524     return aTransPersPrev;
525   }
526
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];
535
536   if (myIsTransPers)
537   {
538     // pop matrix stack - it will be overridden later
539     glMatrixMode (GL_PROJECTION);
540     glPopMatrix();
541     glMatrixMode (GL_MODELVIEW);
542     glPopMatrix();
543   }
544   else
545   {
546     myIsTransPers = Standard_True;
547   }
548
549   // push matrices into stack and reset them
550   glMatrixMode (GL_MODELVIEW);
551   glPushMatrix();
552   glLoadIdentity();
553
554   glMatrixMode (GL_PROJECTION);
555   glPushMatrix();
556   glLoadIdentity();
557
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)
561   {
562     gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
563                 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
564                 &aWinX, &aWinY, &aWinZ);
565   }
566
567   // prevent zooming
568   if ((theTransPers->mode & TPF_ZOOM)
569    || (theTransPers->mode == TPF_TRIEDRON))
570   {
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;
577   }
578
579   // prevent translation - annulate translate matrix
580   if ((theTransPers->mode & TPF_PAN)
581    || (theTransPers->mode == TPF_TRIEDRON))
582   {
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;
589   }
590
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     }
603   }
604
605   // prevent rotating - annulate rotate matrix
606   if (theTransPers->mode & TPF_ROTATE)
607   {
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;
618   }
619
620   // load computed matrices
621   glMatrixMode (GL_MODELVIEW);
622   glMultMatrixd ((GLdouble* )aModelMatrix);
623
624   glMatrixMode (GL_PROJECTION);
625   glMultMatrixd ((GLdouble* )aProjMatrix);
626
627   if (theTransPers->mode == TPF_TRIEDRON)
628   {
629     // move to the window corner
630     if (theTransPers->pointX != 0.0
631      && theTransPers->pointY != 0.0)
632     {
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);
646     }
647   }
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);
657
658     glMatrixMode (GL_MODELVIEW);
659     glTranslated (aMoveX, aMoveY, aMoveZ);
660   }
661
662   return aTransPersPrev;
663 }