0024739: TKOpenGl - port ray-tracing from OpenCL to GLSL for better integration and...
[occt.git] / src / OpenGl / OpenGl_View.cxx
index 012af13..d3c006b 100644 (file)
@@ -1,39 +1,34 @@
 // Created on: 2011-09-20
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
+#include <NCollection_Mat4.hxx>
 
-#include <OpenGl_GlCore11.hxx>
-
-#include <OpenGl_View.hxx>
 #include <OpenGl_Context.hxx>
-#include <OpenGl_Workspace.hxx>
 #include <OpenGl_Display.hxx>
-
+#include <OpenGl_GlCore11.hxx>
+#include <OpenGl_GraduatedTrihedron.hxx>
+#include <OpenGl_GraphicDriver.hxx>
+#include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_Texture.hxx>
 #include <OpenGl_Trihedron.hxx>
-#include <OpenGl_GraduatedTrihedron.hxx>
-
 #include <OpenGl_transform_persistence.hxx>
+#include <OpenGl_View.hxx>
+#include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_TextureEnv.hxx>
-
-#include <GL/glu.h> // gluUnProject()
+#include <Graphic3d_Mat4d.hxx>
 
 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
@@ -44,67 +39,45 @@ static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERE
 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 };
 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 } };
 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
-static const OPENGL_EXTRA_REP myDefaultExtra =
-{
-  //vrp
-  { 0.F, 0.F, 0.F },
-  //vpn
-  { 0.F, 0.F, 1.F },
-  //vup
-  { 0.F, 1.F, 0.F },
-  //map
-  {
-    //window
-    { 0.F, 0.F, 1.F, 1.F },
-    //viewport
-    { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F },
-    //proj
-    TelParallel,
-    //prp
-    { 0.F, 0.F, 0.F },
-    //vpd
-    0.F,
-    //fpd
-    0.F,
-    //bpd
-    -1.F
-  },
-  //scaleFactors
-  { 1.F, 1.F, 1.F }
-};
 
 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
+static const GLdouble THE_IDENTITY_MATRIX[4][4] =
+{
+  {1.0, 0.0, 0.0, 0.0},
+  {0.0, 1.0, 0.0, 0.0},
+  {0.0, 0.0, 1.0, 0.0},
+  {0.0, 0.0, 0.0, 1.0}
+};
 
 /*----------------------------------------------------------------------*/
 
-OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
+OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
+                          OpenGl_StateCounter*       theCounter)
 : mySurfaceDetail(Visual3d_TOD_NONE),
   myBackfacing(0),
   myBgTexture(myDefaultBgTexture),
   myBgGradient(myDefaultBgGradient),
-  //myOrientationMatrix(myDefaultMatrix),
-  //myMappingMatrix(myDefaultMatrix),
   //shield_indicator = TOn,
   //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
   //border_indicator = TOff,
   //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
   //active_status = TOn,
   myZClip(myDefaultZClip),
-  myExtra(myDefaultExtra),
+  myCamera(AContext.Camera),
   myFog(myDefaultFog),
+  myTrihedron(NULL),
+  myGraduatedTrihedron(NULL),
   myVisualization(AContext.Visualization),
   myIntShadingMethod(TEL_SM_GOURAUD),
   myAntiAliasing(Standard_False),
-  myAnimationListIndex(0),
-  myAnimationListReady(Standard_False),
   myTransPers(&myDefaultTransPers),
   myIsTransPers(Standard_False),
-  myResetFLIST(Standard_False)
+  myProjectionState (0),
+  myModelViewState (0),
+  myStateCounter (theCounter),
+  myLastLightSourceState (0, 0)
 {
-  // Initialize matrices
-  memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
-  memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3));
 
   // Shading method
   switch (AContext.Model)
@@ -117,6 +90,10 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
       myIntShadingMethod = TEL_SM_FLAT;
       break;
   }
+
+  myCurrLightSourceState = myStateCounter->Increment();
+
+  myModificationState = 1; // initial state
 }
 
 /*----------------------------------------------------------------------*/
@@ -128,6 +105,9 @@ OpenGl_View::~OpenGl_View ()
 
 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
 {
+  OpenGl_Element::Destroy (theCtx, myTrihedron);
+  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
+
   if (!myTextureEnv.IsNull())
   {
     theCtx->DelayedRelease (myTextureEnv);
@@ -138,11 +118,6 @@ void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
     glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
     myBgTexture.TexId = 0;
   }
-  if (myAnimationListIndex)
-  {
-    glDeleteLists ((GLuint )myAnimationListIndex, 1);
-    myAnimationListIndex = 0;
-  }
 }
 
 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)&       theCtx,
@@ -161,109 +136,40 @@ void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)&       theCtx,
 
   myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
   Handle(Image_PixMap) anImage = theTexture->GetImage();
-  myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
-}
+  if (!anImage.IsNull())
+    myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
 
-/*----------------------------------------------------------------------*/
-
-void OpenGl_View::SetBackfacing (const Standard_Integer AMode)
-{
-  myBackfacing = AMode;
-  myResetFLIST = Standard_True;
+  myModificationState++;
 }
 
-/*----------------------------------------------------------------------*/
-
-//call_togl_setlight
-void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
+void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
 {
-  myLights.Clear();
-
-  const int nb_lights = AContext.NbActiveLight;
-
-  int i = 0;
-  const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]);
-  for ( ; i < nb_lights; i++, alight++ )
-  {
-    OpenGl_Light rep;
-
-       switch( alight->LightType )
-    {
-      case 0 : /* TOLS_AMBIENT */
-        rep.type = TLightAmbient;
-        rep.col.rgb[0] = alight->Color.r;
-        rep.col.rgb[1] = alight->Color.g;
-        rep.col.rgb[2] = alight->Color.b;
-        break;
-
-      case 1 : /* TOLS_DIRECTIONAL */
-        rep.type = TLightDirectional;
-        rep.col.rgb[0] = alight->Color.r;
-        rep.col.rgb[1] = alight->Color.g;
-        rep.col.rgb[2] = alight->Color.b;
-        rep.dir[0] = alight->Direction.x;
-        rep.dir[1] = alight->Direction.y;
-        rep.dir[2] = alight->Direction.z;
-        break;
-
-      case 2 : /* TOLS_POSITIONAL */
-        rep.type = TLightPositional;
-        rep.col.rgb[0] = alight->Color.r;
-        rep.col.rgb[1] = alight->Color.g;
-        rep.col.rgb[2] = alight->Color.b;
-        rep.pos[0] = alight->Position.x;
-        rep.pos[1] = alight->Position.y;
-        rep.pos[2] = alight->Position.z;
-        rep.atten[0] = alight->Attenuation[0];
-        rep.atten[1] = alight->Attenuation[1];
-        break;
-
-      case 3 : /* TOLS_SPOT */
-        rep.type = TLightSpot;
-        rep.col.rgb[0] = alight->Color.r;
-        rep.col.rgb[1] = alight->Color.g;
-        rep.col.rgb[2] = alight->Color.b;
-        rep.pos[0] = alight->Position.x;
-        rep.pos[1] = alight->Position.y;
-        rep.pos[2] = alight->Position.z;
-        rep.dir[0] = alight->Direction.x;
-        rep.dir[1] = alight->Direction.y;
-        rep.dir[2] = alight->Direction.z;
-        rep.shine = alight->Concentration;
-        rep.atten[0] = alight->Attenuation[0];
-        rep.atten[1] = alight->Attenuation[1];
-        rep.angle = alight->Angle;
-        break;
-    }
+  mySurfaceDetail = theMode;
 
-    rep.HeadLight = alight->Headlight;
-
-    myLights.Append(rep);
-  }
+  myModificationState++;
 }
 
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : SetBackfacing
+// purpose  :
+// =======================================================================
+void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
+{
+  myBackfacing = theMode;
+}
 
-//call_togl_setplane
-void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext)
+// =======================================================================
+// function : SetLights
+// purpose  :
+// =======================================================================
+void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
 {
-  // clear clipping planes information
-  myClippingPlanes.Clear();
-  // update information
-  int i = 0;
-  for (; i < AContext.NbActivePlane; i++)
+  myLights.Clear();
+  for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
   {
-    const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i];
-    if ( aCPlane.Active && aCPlane.PlaneId > 0 )
-    {
-      OPENGL_CLIP_REP aPlane;
-      aPlane.equation[0] = aCPlane.CoefA;
-      aPlane.equation[1] = aCPlane.CoefB;
-      aPlane.equation[2] = aCPlane.CoefC;
-      aPlane.equation[3] = aCPlane.CoefD;
-      myClippingPlanes.Append( aPlane );
-    }
+    myLights.Append (theViewCtx.ActiveLight[aLightIt]);
   }
+  myCurrLightSourceState = myStateCounter->Increment();
 }
 
 /*----------------------------------------------------------------------*/
@@ -290,21 +196,8 @@ void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
 //call_togl_cliplimit
 void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
 {
-  myZClip.Back.Limit =
-    (theCView.Context.ZClipBackPlane     - theCView.Mapping.BackPlaneDistance) /
-    (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
-  myZClip.Front.Limit =
-    (theCView.Context.ZClipFrontPlane    - theCView.Mapping.BackPlaneDistance) /
-    (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
-  if (myZClip.Back.Limit < 0.0f)
-    myZClip.Back.Limit = 0.0f;
-  if (myZClip.Front.Limit > 1.0f)
-    myZClip.Front.Limit = 1.0f;
-  if (myZClip.Back.Limit > myZClip.Front.Limit)
-  {
-    myZClip.Back.Limit  = 0.0f;
-    myZClip.Front.Limit = 1.0f;
-  }
+  myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
+  myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
 
   myZClip.Back.IsOn  = (theCView.Context.BackZClipping  != 0);
   myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
@@ -312,133 +205,6 @@ void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
 
 /*----------------------------------------------------------------------*/
 
-//call_togl_viewmapping
-void OpenGl_View::SetMapping (const Graphic3d_CView& theCView)
-{
-  const float ratio   = theCView.DefWindow.dy / theCView.DefWindow.dx;
-  const float r_ratio = theCView.DefWindow.dx / theCView.DefWindow.dy;
-
-  TEL_VIEW_MAPPING Map;
-
-  Map.window.xmin = theCView.Mapping.WindowLimit.um;
-  Map.window.ymin = theCView.Mapping.WindowLimit.vm;
-  Map.window.xmax = theCView.Mapping.WindowLimit.uM;
-  Map.window.ymax = theCView.Mapping.WindowLimit.vM;
-
-  Map.viewport.xmin = 0.F;
-  Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio );
-  Map.viewport.ymin = 0.F;
-  Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio );
-  Map.viewport.zmin = 0.F;
-  Map.viewport.zmax = 1.F;
-
-  // projection type
-  switch (theCView.Mapping.Projection)
-  {
-    case 0 :
-      Map.proj = TelPerspective;
-      break;
-    case 1 :
-      Map.proj = TelParallel;
-      break;
-  }
-
-  // projection reference point
-  Map.prp[0] = theCView.Mapping.ProjectionReferencePoint.x;
-  Map.prp[1] = theCView.Mapping.ProjectionReferencePoint.y;
-  Map.prp[2] = theCView.Mapping.ProjectionReferencePoint.z;
-  if (!openglDisplay.IsNull() && !openglDisplay->Walkthrough())
-    Map.prp[2] += theCView.Mapping.FrontPlaneDistance;
-
-  // view plane distance
-  Map.vpd = theCView.Mapping.ViewPlaneDistance;
-
-  // back plane distance
-  Map.bpd = theCView.Mapping.BackPlaneDistance;
-
-  // front plane distance
-  Map.fpd = theCView.Mapping.FrontPlaneDistance;
-
-  Tint err_ind = 0;
-
-  // use user-defined matrix
-  if (theCView.Mapping.IsCustomMatrix)
-  {
-    int i, j;
-    for( i = 0; i < 4; i++ )
-      for( j = 0; j < 4; j++ )
-        myMappingMatrix[i][j] = theCView.Mapping.ProjectionMatrix[i][j];
-  }
-  else
-    TelEvalViewMappingMatrix( &Map, &err_ind, myMappingMatrix );
-
-  if (!err_ind)
-    myExtra.map = Map;
-}
-
-/*----------------------------------------------------------------------*/
-
-//call_togl_vieworientation
-void OpenGl_View::SetOrientation (const Graphic3d_CView& theCView)
-{
-  Tfloat Vrp[3];
-  Tfloat Vpn[3];
-  Tfloat Vup[3];
-  Tfloat ScaleFactors[3];
-
-  Vrp[0] = theCView.Orientation.ViewReferencePoint.x;
-  Vrp[1] = theCView.Orientation.ViewReferencePoint.y;
-  Vrp[2] = theCView.Orientation.ViewReferencePoint.z;
-
-  Vpn[0] = theCView.Orientation.ViewReferencePlane.x;
-  Vpn[1] = theCView.Orientation.ViewReferencePlane.y;
-  Vpn[2] = theCView.Orientation.ViewReferencePlane.z;
-
-  Vup[0] = theCView.Orientation.ViewReferenceUp.x;
-  Vup[1] = theCView.Orientation.ViewReferenceUp.y;
-  Vup[2] = theCView.Orientation.ViewReferenceUp.z;
-
-  ScaleFactors[0] = theCView.Orientation.ViewScaleX;
-  ScaleFactors[1] = theCView.Orientation.ViewScaleY;
-  ScaleFactors[2] = theCView.Orientation.ViewScaleZ;
-
-  Tint err_ind = 0;
-
-  // use user-defined matrix
-  if (theCView.Orientation.IsCustomMatrix)
-  {
-    int i, j;
-    for( i = 0; i < 4; i++ )
-      for( j = 0; j < 4; j++ )
-        myOrientationMatrix[i][j] = theCView.Orientation.ModelViewMatrix[i][j];
-  }
-  else
-  {
-    TelEvalViewOrientationMatrix (Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix);
-  }
-
-  if (!err_ind)
-  {
-    myExtra.vrp[0] = Vrp[0];
-    myExtra.vrp[1] = Vrp[1];
-    myExtra.vrp[2] = Vrp[2];
-
-    myExtra.vpn[0] = Vpn[0];
-    myExtra.vpn[1] = Vpn[1];
-    myExtra.vpn[2] = Vpn[2];
-
-    myExtra.vup[0] = Vup[0];
-    myExtra.vup[1] = Vup[1];
-    myExtra.vup[2] = Vup[2];
-
-    myExtra.scaleFactors[0] = ScaleFactors[0],
-    myExtra.scaleFactors[1] = ScaleFactors[1],
-    myExtra.scaleFactors[2] = ScaleFactors[2];
-  }
-}
-
-/*----------------------------------------------------------------------*/
-
 void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
                           const Standard_Boolean theFlag)
 {
@@ -450,29 +216,8 @@ void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
   {
     myFog.IsOn = Standard_True;
 
-    myFog.Front =
-      (theCView.Context.DepthFrontPlane    - theCView.Mapping.BackPlaneDistance) /
-      (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
-
-    myFog.Back =
-      (theCView.Context.DepthBackPlane     - theCView.Mapping.BackPlaneDistance) /
-      (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
-
-    if (myFog.Front < 0.F)
-      myFog.Front = 0.F;
-    else if (myFog.Front > 1.F)
-      myFog.Front = 1.F;
-
-    if (myFog.Back < 0.F)
-      myFog.Back = 0.F;
-    else if (myFog.Back > 1.F)
-      myFog.Back = 1.F;
-
-    if (myFog.Back > myFog.Front)
-    {
-      myFog.Front = 1.F;
-      myFog.Back = 0.F;
-    }
+    myFog.Front = theCView.Context.DepthFrontPlane;
+    myFog.Back = theCView.Context.DepthBackPlane;
 
     myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
     myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
@@ -483,217 +228,249 @@ void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
-                                  const Standard_Real AScale, const Standard_Boolean AsWireframe)
+void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)&       theCtx,
+                                   const Aspect_TypeOfTriedronPosition thePosition,
+                                   const Quantity_NameOfColor          theColor,
+                                   const Standard_Real                 theScale,
+                                   const Standard_Boolean              theAsWireframe)
 {
-  myTrihedron = new OpenGl_Trihedron (APosition, AColor, AScale, AsWireframe);
+  OpenGl_Element::Destroy (theCtx, myTrihedron);
+  myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::TriedronErase ()
+void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
 {
-  myTrihedron.Nullify();
+  OpenGl_Element::Destroy (theCtx, myTrihedron);
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_CGraduatedTrihedron &data)
+void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)&        theCtx,
+                                             const Graphic3d_CGraduatedTrihedron& theData)
 {
-  myGraduatedTrihedron = new OpenGl_GraduatedTrihedron(data);
+  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
+  myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::GraduatedTrihedronErase ()
+void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
 {
-  myGraduatedTrihedron.Nullify();
+  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
 }
 
 /*----------------------------------------------------------------------*/
 
 //transform_persistence_end
-void OpenGl_View::EndTransformPersistence ()
+void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
 {
-  if ( myIsTransPers )
+  if (myIsTransPers)
   {
-    /* restore matrix */
+    // restore matrix
     glMatrixMode (GL_PROJECTION);
-    glPopMatrix ();
+    glPopMatrix();
     glMatrixMode (GL_MODELVIEW);
-    glPopMatrix ();
+    glPopMatrix();
     myIsTransPers = Standard_False;
+
+    // Note: the approach of accessing OpenGl matrices is used now since the matrix
+    // manipulation are made with help of OpenGl methods. This might be replaced by
+    // direct computation of matrices by OCC subroutines.
+    Tmatrix3 aResultWorldView;
+    glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
+
+    Tmatrix3 aResultProjection;
+    glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
+
+    // Set OCCT state uniform variables
+    theCtx->ShaderManager()->RevertWorldViewStateTo (&aResultWorldView);
+    theCtx->ShaderManager()->RevertProjectionStateTo (&aResultProjection);
   }
 }
 
 /*----------------------------------------------------------------------*/
 
 //transform_persistence_begin
-const TEL_TRANSFORM_PERSISTENCE * OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE *ATransPers)
+const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
+                                                                         const TEL_TRANSFORM_PERSISTENCE* theTransPers)
 {
-  const TEL_TRANSFORM_PERSISTENCE *TransPers_old = myTransPers;
-
-  myTransPers = ATransPers;
-
-  if ( ATransPers->mode == 0 )
+  const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
+  myTransPers = theTransPers;
+  if (theTransPers->mode == 0)
   {
-    EndTransformPersistence();
-    return TransPers_old;
+    EndTransformPersistence (theCtx);
+    return aTransPersPrev;
   }
 
-  GLint viewport[4];
-  glGetIntegerv (GL_VIEWPORT, viewport);
-  GLdouble modelMatrix[4][4];
-  glGetDoublev( GL_MODELVIEW_MATRIX,  (GLdouble *) modelMatrix );
-  GLdouble projMatrix[4][4];
-  glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
+  GLint aViewport[4];
+  GLdouble aModelMatrix[4][4];
+  GLdouble aProjMatrix[4][4];
+  glGetIntegerv (GL_VIEWPORT,          aViewport);
+  glGetDoublev  (GL_MODELVIEW_MATRIX,  (GLdouble* )aModelMatrix);
+  glGetDoublev  (GL_PROJECTION_MATRIX, (GLdouble *)aProjMatrix);
+  const GLdouble aViewportW = (GLdouble )aViewport[2];
+  const GLdouble aViewportH = (GLdouble )aViewport[3];
 
-  double W = viewport[2];
-  double H = viewport[3];
-
-  if ( myIsTransPers )
+  if (myIsTransPers)
   {
-    /* restore matrix */
+    // pop matrix stack - it will be overridden later
     glMatrixMode (GL_PROJECTION);
-    glPopMatrix ();
+    glPopMatrix();
     glMatrixMode (GL_MODELVIEW);
-    glPopMatrix ();
+    glPopMatrix();
   }
   else
+  {
     myIsTransPers = Standard_True;
+  }
 
-  glMatrixMode( GL_MODELVIEW );
+  // push matrices into stack and reset them
+  glMatrixMode (GL_MODELVIEW);
   glPushMatrix();
   glLoadIdentity();
 
-  glMatrixMode( GL_PROJECTION );
+  glMatrixMode (GL_PROJECTION);
   glPushMatrix();
   glLoadIdentity();
 
-  /*pre loading matrix*/
-  if( ATransPers->mode & TPF_PAN )
-    /* Annulate translate matrix */
+  // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
+  GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
+  if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
   {
-    modelMatrix[3][0] = 0.;
-    modelMatrix[3][1] = 0.;
-    modelMatrix[3][2] = 0.;
-    projMatrix[3][0] = 0.;
-    projMatrix[3][1] = 0.;
-    projMatrix[3][2] = 0.;
+    gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
+                (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
+                &aWinX, &aWinY, &aWinZ);
   }
 
-  if( ATransPers->mode & TPF_ZOOM )
-    /* Annulate zoom matrix */
+  // prevent zooming
+  if ((theTransPers->mode & TPF_ZOOM)
+   || (theTransPers->mode == TPF_TRIEDRON))
   {
-    const double scaleX = myExtra.scaleFactors[0];
-    const double scaleY = myExtra.scaleFactors[1];
-    const double scaleZ = myExtra.scaleFactors[2];
+    // compute fixed-zoom multiplier
+    // actually function works ugly with TelPerspective!
+    const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix[1][1] : aProjMatrix[0][0]);
+    aProjMatrix[0][0] *= aDet2;
+    aProjMatrix[1][1] *= aDet2;
+    aProjMatrix[2][2] *= aDet2;
+  }
+
+  // prevent translation - annulate translate matrix
+  if ((theTransPers->mode & TPF_PAN)
+   || (theTransPers->mode == TPF_TRIEDRON))
+  {
+    aModelMatrix[3][0] = 0.0;
+    aModelMatrix[3][1] = 0.0;
+    aModelMatrix[3][2] = 0.0;
+    aProjMatrix [3][0] = 0.0;
+    aProjMatrix [3][1] = 0.0;
+    aProjMatrix [3][2] = 0.0;
+  }
 
+  // prevent scaling-on-axis
+  if (theTransPers->mode & TPF_ZOOM)
+  {
+    const gp_Pnt anAxialScale = myCamera->AxialScale();
+    const double aScaleX = anAxialScale.X();
+    const double aScaleY = anAxialScale.Y();
+    const double aScaleZ = anAxialScale.Z();
     for (int i = 0; i < 3; ++i)
     {
-      modelMatrix[0][i] /= scaleX;
-      modelMatrix[1][i] /= scaleY;
-      modelMatrix[2][i] /= scaleZ;
+      aModelMatrix[0][i] /= aScaleX;
+      aModelMatrix[1][i] /= aScaleY;
+      aModelMatrix[2][i] /= aScaleZ;
     }
+  }
 
-    const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]);
-    projMatrix[0][0] *= det2;
-    projMatrix[1][1] *= det2;
+  // prevent rotating - annulate rotate matrix
+  if (theTransPers->mode & TPF_ROTATE)
+  {
+    aModelMatrix[0][0] = 1.0;
+    aModelMatrix[1][1] = 1.0;
+    aModelMatrix[2][2] = 1.0;
+
+    aModelMatrix[1][0] = 0.0;
+    aModelMatrix[2][0] = 0.0;
+    aModelMatrix[0][1] = 0.0;
+    aModelMatrix[2][1] = 0.0;
+    aModelMatrix[0][2] = 0.0;
+    aModelMatrix[1][2] = 0.0;
   }
 
-  if( ATransPers->mode & TPF_ROTATE )
-    /* Annulate rotate matrix */
+  // load computed matrices
+  glMatrixMode (GL_MODELVIEW);
+  glMultMatrixd ((GLdouble* )aModelMatrix);
+
+  glMatrixMode (GL_PROJECTION);
+  glMultMatrixd ((GLdouble* )aProjMatrix);
+
+  if (theTransPers->mode == TPF_TRIEDRON)
   {
-    modelMatrix[0][0] = 1.;
-    modelMatrix[1][1] = 1.;
-    modelMatrix[2][2] = 1.;
-
-    modelMatrix[1][0] = 0.;
-    modelMatrix[2][0] = 0.;
-    modelMatrix[0][1] = 0.;
-    modelMatrix[2][1] = 0.;
-    modelMatrix[0][2] = 0.;
-    modelMatrix[1][2] = 0.;
+    // move to the window corner
+    if (theTransPers->pointX != 0.0
+     && theTransPers->pointY != 0.0)
+    {
+      GLdouble aW1, aH1, aW2, aH2, aDummy;
+      glMatrixMode (GL_PROJECTION);
+      gluUnProject ( 0.5 * aViewportW,  0.5 * aViewportH, 0.0,
+                    (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
+                    &aW1, &aH1, &aDummy);
+      gluUnProject (-0.5 * aViewportW, -0.5 * aViewportH, 0.0,
+                    (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
+                    &aW2, &aH2, &aDummy);
+      GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
+      GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
+      aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
+      aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
+      glTranslated (aMoveX, aMoveY, 0.0);
+    }
   }
-  else if( ATransPers->mode & TPF_RELATIVE_ROTATE )
-    /* Initialize relative rotate matrix*/
+  else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
   {
-    modelMatrix[3][0] = 0.;
-    modelMatrix[3][1] = 0.;
-    modelMatrix[3][2] = 0.;
+    // move to thePoint using saved win-coordinates ('marker-behaviour')
+    GLdouble aMoveX, aMoveY, aMoveZ;
+    glGetDoublev (GL_MODELVIEW_MATRIX,  (GLdouble* )aModelMatrix);
+    glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble* )aProjMatrix);
+    gluUnProject (aWinX, aWinY, aWinZ,
+                  (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
+                  &aMoveX, &aMoveY, &aMoveZ);
 
-    glMatrixMode( GL_MODELVIEW );
-    glLoadIdentity();
-    glTranslated( ATransPers->pointX, ATransPers->pointY, ATransPers->pointZ );
+    glMatrixMode (GL_MODELVIEW);
+    glTranslated (aMoveX, aMoveY, aMoveZ);
   }
 
-  if( ATransPers->mode == TPF_TRIEDRON )
-  {
-    /* Annulate translation matrix */
-    modelMatrix[3][0] = 0.;
-    modelMatrix[3][1] = 0.;
-    modelMatrix[3][2] = 0.;
-
-    projMatrix[3][0] = 0.;
-    projMatrix[3][1] = 0.;
-    projMatrix[3][2] = 0.;
-
-    const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]);
-    projMatrix[0][0] *= det2;
-    projMatrix[1][1] *= det2;
-  }
+  // Note: the approach of accessing OpenGl matrices is used now since the matrix
+  // manipulation are made with help of OpenGl methods. This might be replaced by
+  // direct computation of matrices by OCC subroutines.
+  Tmatrix3 aResultWorldView;
+  glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
 
-  /* load matrix */
-  glMatrixMode (GL_MODELVIEW);
-  glMultMatrixd ((GLdouble *) modelMatrix);
+  Tmatrix3 aResultProjection;
+  glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
 
-  glMatrixMode (GL_PROJECTION);
-  glMultMatrixd ((GLdouble *) projMatrix);
+  // Set OCCT state uniform variables
+  theCtx->ShaderManager()->UpdateWorldViewStateTo (&aResultWorldView);
+  theCtx->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
 
-  /*post loading matrix*/
-  if( ATransPers->mode == TPF_TRIEDRON )
-  {
-    glMatrixMode( GL_PROJECTION );
+  return aTransPersPrev;
+}
 
-       double winx, winy, winz;
-    const GLdouble idenMatrix[4][4] = { {1.,0.,0.,0.}, {0.,1.,0.,0.}, {0.,0.,1.,0.}, {0.,0.,0.,1.} };
+/*----------------------------------------------------------------------*/
 
-    gluUnProject( W/2., H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz);
-    double W1, H1;
-    W1 = winx;
-    H1 = winy;
-    gluUnProject( -W/2., -H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz);
-    double W2, H2;
-    W2 = winx;
-    H2 = winy;
+void OpenGl_View::GetMatrices (TColStd_Array2OfReal&  theMatOrient,
+                               TColStd_Array2OfReal&  theMatMapping) const
+{
+  const Graphic3d_Mat4d& aProj   = myCamera->ProjectionMatrix();
+  const Graphic3d_Mat4d& aOrient = myCamera->OrientationMatrix();
 
-    if( ATransPers->pointX == 0. && ATransPers->pointY == 0. )
-    {
-      /*center*/
-    }
-    else if( ATransPers->pointX > 0. && ATransPers->pointY > 0. )
-    {
-      /*right upper*/
-      glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. );
-    }
-    else if( ATransPers->pointX > 0. && ATransPers->pointY < 0. )
-    {
-      /*right lower*/
-      glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H2 - H1 + ATransPers->pointZ), 0. );
-    }
-    else if( ATransPers->pointX < 0. && ATransPers->pointY > 0. )
-    {
-      /*left upper*/
-      glTranslated( 0.5*(W2 - W1 + ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. );
-    }
-    else if( ATransPers->pointX < 0 && ATransPers->pointY < 0 )
+  for (Standard_Integer aRow = 0; aRow < 4; ++aRow)
+  {
+    for (Standard_Integer aCol = 0; aCol < 4; ++aCol)
     {
-      /*left lower*/
-      glTranslated( -(W1 - W2)/2. + ATransPers->pointZ/2., -(H1-H2)/2. + ATransPers->pointZ/2., 0. );
+      theMatOrient  (aRow, aCol) = aOrient.GetValue (aRow, aCol);
+      theMatMapping (aRow, aCol) = aProj  .GetValue (aRow, aCol);
     }
   }
-
-  return TransPers_old;
 }
-
 /*----------------------------------------------------------------------*/