0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_View.cxx
1 // File:      OpenGl_View.cxx
2 // Created:   20 September 2011
3 // Author:    Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
5
6 #include <OpenGl_View.hxx>
7
8 #include <OpenGl_Workspace.hxx>
9 #include <OpenGl_Display.hxx>
10
11 #include <OpenGl_tgl_all.hxx>
12 #include <GL/gl.h>
13
14 #include <OpenGl_Display.hxx>
15 #include <OpenGl_Trihedron.hxx>
16 #include <OpenGl_GraduatedTrihedron.hxx>
17
18 #include <OpenGl_transform_persistence.hxx>
19
20 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
21 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
22
23 /*----------------------------------------------------------------------*/
24
25 static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
26 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 };
27 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 } };
28 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
29 static const OPENGL_EXTRA_REP myDefaultExtra =
30 {
31   //vrp
32   { 0.F, 0.F, 0.F },
33   //vpn
34   { 0.F, 0.F, 1.F },
35   //vup
36   { 0.F, 1.F, 0.F },
37   //map
38   {
39     //window
40     { 0.F, 0.F, 1.F, 1.F },
41     //viewport
42     { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F },
43     //proj
44     TelParallel,
45     //prp
46     { 0.F, 0.F, 0.F },
47     //vpd
48     0.F,
49     //fpd
50     0.F,
51     //bpd
52     -1.F
53   },
54   //scaleFactors
55   { 1.F, 1.F, 1.F }
56 };
57
58 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
59 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
60
61 /*----------------------------------------------------------------------*/
62
63 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
64 : myTextureEnv(0),
65   mySurfaceDetail(Visual3d_TOD_NONE),
66   myBackfacing(0),
67   myBgTexture(myDefaultBgTexture),
68   myBgGradient(myDefaultBgGradient),
69   //myOrientationMatrix(myDefaultMatrix),
70   //myMappingMatrix(myDefaultMatrix),
71   //shield_indicator = TOn,
72   //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
73   //border_indicator = TOff,
74   //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
75   //active_status = TOn,
76   myZClip(myDefaultZClip),
77   myExtra(myDefaultExtra),
78   myFog(myDefaultFog),
79   myVisualization(AContext.Visualization),
80   myIntShadingMethod(TEL_SM_GOURAUD),
81   myAntiAliasing(Standard_False),
82   myAnimationListIndex(0),
83   myAnimationListReady(Standard_False),
84   myTransPers(&myDefaultTransPers),
85   myIsTransPers(Standard_False),
86   myResetFLIST(Standard_False)
87 {
88   // Initialize matrices
89   memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
90   memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3));
91
92   // Shading method
93   switch (AContext.Model)
94   {
95     case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
96     case 3 : /* VISUAL3D_TOM_VERTEX */
97       myIntShadingMethod = TEL_SM_GOURAUD;
98       break;
99     default :
100       myIntShadingMethod = TEL_SM_FLAT;
101       break;
102   }
103 }
104
105 /*----------------------------------------------------------------------*/
106
107 OpenGl_View::~OpenGl_View ()
108 {
109   if (myAnimationListIndex)
110     glDeleteLists((GLuint)myAnimationListIndex,1);
111
112   if ( myBgTexture.TexId != 0 )
113     glDeleteTextures( 1, (GLuint*)&(myBgTexture.TexId) );
114 }
115
116 /*----------------------------------------------------------------------*/
117
118 void OpenGl_View::SetBackfacing (const Standard_Integer AMode)
119 {
120   myBackfacing = AMode;
121   myResetFLIST = Standard_True;
122 }
123
124 /*----------------------------------------------------------------------*/
125
126 //call_togl_setlight
127 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
128 {
129   myLights.Clear();
130
131   const int nb_lights = AContext.NbActiveLight;
132
133   int i = 0;
134   const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]);
135   for ( ; i < nb_lights; i++, alight++ )
136   {
137     OpenGl_Light rep;
138
139         switch( alight->LightType )
140     {
141       case 0 : /* TOLS_AMBIENT */
142         rep.type = TLightAmbient;
143         rep.col.rgb[0] = alight->Color.r;
144         rep.col.rgb[1] = alight->Color.g;
145         rep.col.rgb[2] = alight->Color.b;
146         break;
147
148       case 1 : /* TOLS_DIRECTIONAL */
149         rep.type = TLightDirectional;
150         rep.col.rgb[0] = alight->Color.r;
151         rep.col.rgb[1] = alight->Color.g;
152         rep.col.rgb[2] = alight->Color.b;
153         rep.dir[0] = alight->Direction.x;
154         rep.dir[1] = alight->Direction.y;
155         rep.dir[2] = alight->Direction.z;
156         break;
157
158       case 2 : /* TOLS_POSITIONAL */
159         rep.type = TLightPositional;
160         rep.col.rgb[0] = alight->Color.r;
161         rep.col.rgb[1] = alight->Color.g;
162         rep.col.rgb[2] = alight->Color.b;
163         rep.pos[0] = alight->Position.x;
164         rep.pos[1] = alight->Position.y;
165         rep.pos[2] = alight->Position.z;
166         rep.atten[0] = alight->Attenuation[0];
167         rep.atten[1] = alight->Attenuation[1];
168         break;
169
170       case 3 : /* TOLS_SPOT */
171         rep.type = TLightSpot;
172         rep.col.rgb[0] = alight->Color.r;
173         rep.col.rgb[1] = alight->Color.g;
174         rep.col.rgb[2] = alight->Color.b;
175         rep.pos[0] = alight->Position.x;
176         rep.pos[1] = alight->Position.y;
177         rep.pos[2] = alight->Position.z;
178         rep.dir[0] = alight->Direction.x;
179         rep.dir[1] = alight->Direction.y;
180         rep.dir[2] = alight->Direction.z;
181         rep.shine = alight->Concentration;
182         rep.atten[0] = alight->Attenuation[0];
183         rep.atten[1] = alight->Attenuation[1];
184         rep.angle = alight->Angle;
185         break;
186     }
187
188     rep.HeadLight = alight->Headlight;
189
190     myLights.Append(rep);
191   }
192 }
193
194 /*----------------------------------------------------------------------*/
195
196 //call_togl_setplane
197 void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext)
198 {
199   // clear clipping planes information
200   myClippingPlanes.Clear();
201   // update information 
202   int i = 0;
203   for (; i < AContext.NbActivePlane; i++)
204   {
205     const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i];
206     if ( aCPlane.Active && aCPlane.PlaneId > 0 )
207     {
208       OPENGL_CLIP_REP aPlane;
209       aPlane.equation[0] = aCPlane.CoefA;
210       aPlane.equation[1] = aCPlane.CoefB;
211       aPlane.equation[2] = aCPlane.CoefC;
212       aPlane.equation[3] = aCPlane.CoefD;
213       myClippingPlanes.Append( aPlane );
214     }
215   }
216 }
217
218 /*----------------------------------------------------------------------*/
219
220 //call_togl_setvisualisation
221 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
222 {
223   myVisualization = AContext.Visualization;
224   // Shading method
225   switch (AContext.Model)
226   {
227     case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
228     case 3 : /* VISUAL3D_TOM_VERTEX */
229       myIntShadingMethod = TEL_SM_GOURAUD;
230       break;
231     default :
232       myIntShadingMethod = TEL_SM_FLAT;
233       break;
234   }
235 }
236
237 /*----------------------------------------------------------------------*/
238
239 //call_togl_cliplimit
240 void OpenGl_View::SetClipLimit (const CALL_DEF_VIEW &ACView)
241 {
242   myZClip.Back.Limit =
243     ( ACView.Context.ZClipBackPlane - ACView.Mapping.BackPlaneDistance ) /
244     ( ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance );
245   myZClip.Front.Limit =
246     ( ACView.Context.ZClipFrontPlane - ACView.Mapping.BackPlaneDistance ) /
247     ( ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance );
248   if ( myZClip.Back.Limit < 0.F )
249     myZClip.Back.Limit = 0.F;
250   if ( myZClip.Front.Limit > 1.F )
251     myZClip.Front.Limit = 1.F;
252   if ( myZClip.Back.Limit > myZClip.Front.Limit )
253   {
254     myZClip.Back.Limit = 0.F;
255     myZClip.Front.Limit = 1.F;
256   }
257
258   myZClip.Back.IsOn = (ACView.Context.BackZClipping != 0);
259   myZClip.Front.IsOn = (ACView.Context.FrontZClipping != 0);
260 }
261
262 /*----------------------------------------------------------------------*/
263
264 //call_togl_viewmapping
265 void OpenGl_View::SetMapping (const CALL_DEF_VIEW &ACView)
266 {
267   const float ratio = ACView.DefWindow.dy / ACView.DefWindow.dx;
268   const float r_ratio = ACView.DefWindow.dx / ACView.DefWindow.dy;
269
270   TEL_VIEW_MAPPING Map;
271
272   Map.window.xmin = ACView.Mapping.WindowLimit.um;
273   Map.window.ymin = ACView.Mapping.WindowLimit.vm;
274   Map.window.xmax = ACView.Mapping.WindowLimit.uM;
275   Map.window.ymax = ACView.Mapping.WindowLimit.vM;
276
277   Map.viewport.xmin = 0.F;
278   Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio );
279   Map.viewport.ymin = 0.F;
280   Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio );
281   Map.viewport.zmin = 0.F;
282   Map.viewport.zmax = 1.F;
283
284   /* projection type */
285   switch( ACView.Mapping.Projection )
286   {
287     case 0 :
288       Map.proj = TelPerspective;
289       break;
290     case 1 :
291       Map.proj = TelParallel;
292       break;
293   }
294
295   /* projection reference point */
296   Map.prp[0] = ACView.Mapping.ProjectionReferencePoint.x;
297   Map.prp[1] = ACView.Mapping.ProjectionReferencePoint.y;
298   Map.prp[2] = ACView.Mapping.ProjectionReferencePoint.z;
299   if (!openglDisplay.IsNull() && !openglDisplay->Walkthrough())
300     Map.prp[2] += ACView.Mapping.FrontPlaneDistance;
301
302   /* view plane distance */
303   Map.vpd = ACView.Mapping.ViewPlaneDistance;
304
305   /* back plane distance */
306   Map.bpd = ACView.Mapping.BackPlaneDistance;
307
308   /* front plane distance */
309   Map.fpd = ACView.Mapping.FrontPlaneDistance;
310
311   Tint err_ind = 0;
312
313   /* use user-defined matrix */
314   if ( ACView.Mapping.IsCustomMatrix )
315   {
316     int i, j;
317     for( i = 0; i < 4; i++ )
318       for( j = 0; j < 4; j++ )
319         myMappingMatrix[i][j] = ACView.Mapping.ProjectionMatrix[i][j];
320   }
321   else 
322     TelEvalViewMappingMatrix( &Map, &err_ind, myMappingMatrix );
323
324   if ( !err_ind )
325     myExtra.map = Map;
326 }
327
328 /*----------------------------------------------------------------------*/
329
330 //call_togl_vieworientation
331 void OpenGl_View::SetOrientation (const CALL_DEF_VIEW &ACView)
332 {
333   Tfloat Vrp[3];
334   Tfloat Vpn[3];
335   Tfloat Vup[3];
336   Tfloat ScaleFactors[3];
337
338   Vrp[0] = ACView.Orientation.ViewReferencePoint.x;
339   Vrp[1] = ACView.Orientation.ViewReferencePoint.y;
340   Vrp[2] = ACView.Orientation.ViewReferencePoint.z;
341
342   Vpn[0] = ACView.Orientation.ViewReferencePlane.x;
343   Vpn[1] = ACView.Orientation.ViewReferencePlane.y;
344   Vpn[2] = ACView.Orientation.ViewReferencePlane.z;
345
346   Vup[0] = ACView.Orientation.ViewReferenceUp.x;
347   Vup[1] = ACView.Orientation.ViewReferenceUp.y;
348   Vup[2] = ACView.Orientation.ViewReferenceUp.z;
349
350   ScaleFactors[0] = ACView.Orientation.ViewScaleX;
351   ScaleFactors[1] = ACView.Orientation.ViewScaleY;
352   ScaleFactors[2] = ACView.Orientation.ViewScaleZ;
353
354   Tint err_ind = 0;
355
356   // use user-defined matrix
357   if ( ACView.Orientation.IsCustomMatrix )
358   {
359     int i, j;
360     for( i = 0; i < 4; i++ )
361       for( j = 0; j < 4; j++ )
362         myOrientationMatrix[i][j] = ACView.Orientation.ModelViewMatrix[i][j];
363   }
364   else
365     TelEvalViewOrientationMatrix( Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix );
366
367   if ( !err_ind )
368   {
369     myExtra.vrp[0] = Vrp[0];
370     myExtra.vrp[1] = Vrp[1];
371     myExtra.vrp[2] = Vrp[2];
372
373     myExtra.vpn[0] = Vpn[0];
374     myExtra.vpn[1] = Vpn[1];
375     myExtra.vpn[2] = Vpn[2];
376
377     myExtra.vup[0] = Vup[0];
378     myExtra.vup[1] = Vup[1];
379     myExtra.vup[2] = Vup[2];
380
381     myExtra.scaleFactors[0] = ScaleFactors[0],
382     myExtra.scaleFactors[1] = ScaleFactors[1],
383     myExtra.scaleFactors[2] = ScaleFactors[2];
384   }
385 }
386
387 /*----------------------------------------------------------------------*/
388
389 void OpenGl_View::SetFog (const CALL_DEF_VIEW &ACView, const Standard_Boolean AFlag)
390 {
391   if( !AFlag )
392   {
393     myFog.IsOn = Standard_False;
394   }
395   else
396   {
397     myFog.IsOn = Standard_True;
398
399     myFog.Front =
400       (ACView.Context.DepthFrontPlane - ACView.Mapping.BackPlaneDistance) /
401       (ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance);
402
403     myFog.Back =
404       (ACView.Context.DepthBackPlane - ACView.Mapping.BackPlaneDistance) /
405       (ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance);
406
407     if (myFog.Front < 0.F)
408       myFog.Front = 0.F;
409     else if (myFog.Front > 1.F)
410       myFog.Front = 1.F;
411
412     if (myFog.Back < 0.F)
413       myFog.Back = 0.F;
414     else if (myFog.Back > 1.F)
415       myFog.Back = 1.F;
416
417     if (myFog.Back > myFog.Front)
418     {
419       myFog.Front = 1.F;
420       myFog.Back = 0.F;
421     }
422
423     myFog.Color.rgb[0] = ACView.DefWindow.Background.r;
424     myFog.Color.rgb[1] = ACView.DefWindow.Background.g;
425     myFog.Color.rgb[2] = ACView.DefWindow.Background.b;
426     myFog.Color.rgb[3] = 1.F;
427   }
428 }
429
430 /*----------------------------------------------------------------------*/
431
432 void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
433                                   const Standard_Real AScale, const Standard_Boolean AsWireframe)
434 {
435   myTrihedron = new OpenGl_Trihedron (APosition, AColor, AScale, AsWireframe);
436 }
437
438 /*----------------------------------------------------------------------*/
439
440 void OpenGl_View::TriedronErase ()
441 {
442   myTrihedron.Nullify();
443 }
444
445 /*----------------------------------------------------------------------*/
446
447 void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_CGraduatedTrihedron &data)
448 {
449   myGraduatedTrihedron = new OpenGl_GraduatedTrihedron(data);
450 }
451
452 /*----------------------------------------------------------------------*/
453
454 void OpenGl_View::GraduatedTrihedronErase ()
455 {
456   myGraduatedTrihedron.Nullify();
457 }
458
459 /*----------------------------------------------------------------------*/
460
461 //transform_persistence_end
462 void OpenGl_View::EndTransformPersistence ()
463 {
464   if ( myIsTransPers )
465   {
466     /* restore matrix */
467     glMatrixMode (GL_PROJECTION);
468     glPopMatrix ();
469     glMatrixMode (GL_MODELVIEW);
470     glPopMatrix ();
471     myIsTransPers = Standard_False;
472   }
473
474
475 /*----------------------------------------------------------------------*/
476
477 //transform_persistence_begin
478 const TEL_TRANSFORM_PERSISTENCE * OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE *ATransPers)
479 {
480   const TEL_TRANSFORM_PERSISTENCE *TransPers_old = myTransPers;
481
482   if ( ATransPers->mode == 0 )
483   {
484     EndTransformPersistence();
485     return TransPers_old;
486   }
487
488   myTransPers = ATransPers;
489
490   GLint viewport[4];
491   glGetIntegerv (GL_VIEWPORT, viewport);
492   GLdouble modelMatrix[4][4];
493   glGetDoublev( GL_MODELVIEW_MATRIX,  (GLdouble *) modelMatrix );
494   GLdouble projMatrix[4][4];
495   glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
496
497   double W = viewport[2];
498   double H = viewport[3];
499
500   if ( myIsTransPers )
501   {
502     /* restore matrix */
503     glMatrixMode (GL_PROJECTION);
504     glPopMatrix ();
505     glMatrixMode (GL_MODELVIEW);
506     glPopMatrix ();
507   }
508   else
509     myIsTransPers = Standard_True;
510
511   glMatrixMode( GL_MODELVIEW );
512   glPushMatrix();
513   glLoadIdentity();
514
515   glMatrixMode( GL_PROJECTION );
516   glPushMatrix();
517   glLoadIdentity();
518
519   /*pre loading matrix*/
520   if( ATransPers->mode & TPF_PAN )
521     /* Annulate translate matrix */
522   {
523     modelMatrix[3][0] = 0.;
524     modelMatrix[3][1] = 0.;
525     modelMatrix[3][2] = 0.;
526     projMatrix[3][0] = 0.;
527     projMatrix[3][1] = 0.;
528     projMatrix[3][2] = 0.;
529   }
530
531   if( ATransPers->mode & TPF_ZOOM )
532     /* Annulate zoom matrix */
533   {
534     const double scaleX = myExtra.scaleFactors[0];
535     const double scaleY = myExtra.scaleFactors[1];
536     const double scaleZ = myExtra.scaleFactors[2];
537
538     for (int i = 0; i < 3; ++i)
539     {
540       modelMatrix[0][i] /= scaleX;
541       modelMatrix[1][i] /= scaleY;
542       modelMatrix[2][i] /= scaleZ;
543     }
544
545     const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]);
546     projMatrix[0][0] *= det2;
547     projMatrix[1][1] *= det2;
548   }
549
550   if( ATransPers->mode & TPF_ROTATE )
551     /* Annulate rotate matrix */
552   {
553     modelMatrix[0][0] = 1.;
554     modelMatrix[1][1] = 1.;
555     modelMatrix[2][2] = 1.;
556
557     modelMatrix[1][0] = 0.;
558     modelMatrix[2][0] = 0.;
559     modelMatrix[0][1] = 0.;
560     modelMatrix[2][1] = 0.;
561     modelMatrix[0][2] = 0.;
562     modelMatrix[1][2] = 0.;
563   }
564   else if( ATransPers->mode & TPF_RELATIVE_ROTATE )
565     /* Initialize relative rotate matrix*/
566   {
567     modelMatrix[3][0] = 0.;
568     modelMatrix[3][1] = 0.;
569     modelMatrix[3][2] = 0.;
570
571     glMatrixMode( GL_MODELVIEW );
572     glLoadIdentity();
573     glTranslated( ATransPers->pointX, ATransPers->pointY, ATransPers->pointZ );        
574   }
575
576   if( ATransPers->mode == TPF_TRIEDRON )
577   {
578     /* Annulate translation matrix */
579     modelMatrix[3][0] = 0.;
580     modelMatrix[3][1] = 0.;
581     modelMatrix[3][2] = 0.;
582
583     projMatrix[3][0] = 0.;
584     projMatrix[3][1] = 0.;
585     projMatrix[3][2] = 0.;
586
587     const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]);
588     projMatrix[0][0] *= det2;
589     projMatrix[1][1] *= det2;
590   }
591
592   /* load matrix */
593   glMatrixMode (GL_MODELVIEW);
594   glMultMatrixd ((GLdouble *) modelMatrix);
595
596   glMatrixMode (GL_PROJECTION);
597   glMultMatrixd ((GLdouble *) projMatrix);
598
599   /*post loading matrix*/
600   if( ATransPers->mode == TPF_TRIEDRON )
601   {
602     glMatrixMode( GL_PROJECTION );
603
604         double winx, winy, winz;
605     const GLdouble idenMatrix[4][4] = { {1.,0.,0.,0.}, {0.,1.,0.,0.}, {0.,0.,1.,0.}, {0.,0.,0.,1.} };
606
607     gluUnProject( W/2., H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz);
608     double W1, H1;
609     W1 = winx;
610     H1 = winy;
611     gluUnProject( -W/2., -H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz);
612     double W2, H2;
613     W2 = winx;
614     H2 = winy;
615
616     if( ATransPers->pointX == 0. && ATransPers->pointY == 0. )
617     {
618       /*center*/
619     }
620     else if( ATransPers->pointX > 0. && ATransPers->pointY > 0. )
621     {
622       /*right upper*/
623       glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. );
624     }
625     else if( ATransPers->pointX > 0. && ATransPers->pointY < 0. )
626     {
627       /*right lower*/
628       glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H2 - H1 + ATransPers->pointZ), 0. );
629     }
630     else if( ATransPers->pointX < 0. && ATransPers->pointY > 0. )
631     {
632       /*left upper*/
633       glTranslated( 0.5*(W2 - W1 + ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. );
634     }
635     else if( ATransPers->pointX < 0 && ATransPers->pointY < 0 )
636     {
637       /*left lower*/
638       glTranslated( -(W1 - W2)/2. + ATransPers->pointZ/2., -(H1-H2)/2. + ATransPers->pointZ/2., 0. );
639     }
640   }
641
642   return TransPers_old;
643 }
644
645 /*----------------------------------------------------------------------*/