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