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