0026025: Visualization, TKOpenGl - stereoscopic output does not work
[occt.git] / src / OpenGl / OpenGl_View_2.cxx
index 5110e24..3abea51 100644 (file)
@@ -19,6 +19,8 @@
 #include <OpenGl_GlCore11.hxx>
 #include <OpenGl_tgl_funcs.hxx>
 
+#include <Graphic3d_TextureParams.hxx>
+#include <Graphic3d_Texture2Dmanual.hxx>
 #include <Image_AlienPixMap.hxx>
 #include <Visual3d_Layer.hxx>
 
 
 #include <OpenGl_AspectLine.hxx>
 #include <OpenGl_Context.hxx>
-#include <OpenGl_Display.hxx>
 #include <OpenGl_Matrix.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_View.hxx>
 #include <OpenGl_Trihedron.hxx>
 #include <OpenGl_GraduatedTrihedron.hxx>
+#include <OpenGl_PrimitiveArray.hxx>
 #include <OpenGl_PrinterContext.hxx>
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Structure.hxx>
+#include <OpenGl_ArbFBO.hxx>
 
 #define EPSI 0.0001
 
@@ -51,27 +54,20 @@ namespace
 
 extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
 
-/*----------------------------------------------------------------------*/
-
-struct OPENGL_CLIP_PLANE
-{
-  GLboolean isEnabled;
-  GLdouble Equation[4];
-  DEFINE_STANDARD_ALLOC
-};
-
 /*----------------------------------------------------------------------*/
 /*
 * Fonctions privees
 */
 
+#if !defined(GL_ES_VERSION_2_0)
 /*-----------------------------------------------------------------*/
 /*
 *  Set des lumieres
 */
-static void bind_light (const OpenGl_Light& theLight,
-                        GLenum&             theLightGlId,
-                        Graphic3d_Vec4&     theAmbientColor)
+static void bindLight (const OpenGl_Light&             theLight,
+                       GLenum&                         theLightGlId,
+                       Graphic3d_Vec4&                 theAmbientColor,
+                       const Handle(OpenGl_Workspace)& theWorkspace)
 {
   // Only 8 lights in OpenGL...
   if (theLightGlId > GL_LIGHT7)
@@ -86,14 +82,16 @@ static void bind_light (const OpenGl_Light& theLight,
     return;
   }
 
+  const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+
   // the light is a headlight?
-  GLint aMatrixModeOld = 0;
   if (theLight.IsHeadlight)
   {
-    glGetIntegerv (GL_MATRIX_MODE, &aMatrixModeOld);
-    glMatrixMode  (GL_MODELVIEW);
-    glPushMatrix();
-    glLoadIdentity();
+
+    aContext->WorldViewState.Push();
+    aContext->WorldViewState.SetIdentity();
+
+    aContext->ApplyWorldViewMatrix();
   }
 
   // setup light type
@@ -148,206 +146,97 @@ static void bind_light (const OpenGl_Light& theLight,
   // restore matrix in case of headlight
   if (theLight.IsHeadlight)
   {
-    glPopMatrix();
-    glMatrixMode (aMatrixModeOld);
+    aContext->WorldViewState.Pop();
   }
 
   glEnable (theLightGlId++);
 }
+#endif
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
+void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
 {
-  if ( (theWorkspace.NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
-       ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
+  const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+
+  if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
+    || (!myBgTextureArray->IsDefined()                       // no texture
+     && !myBgGradientArray->IsDefined()))                    // no gradient
   {
-    const Standard_Integer aViewWidth = theWorkspace.Width();
-    const Standard_Integer aViewHeight = theWorkspace.Height();
-
-    glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
-
-    glMatrixMode( GL_PROJECTION );
-    glPushMatrix();
-    glLoadIdentity();
-    glMatrixMode( GL_MODELVIEW );
-    glPushMatrix();
-    glLoadIdentity();
-
-    if ( glIsEnabled( GL_DEPTH_TEST ) )
-      glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
-
-    // drawing bg gradient if:
-    // - gradient fill type is not Aspect_GFM_NONE and
-    // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
-    if ( ( myBgGradient.type != Aspect_GFM_NONE ) &&
-      ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
-      myBgTexture.Style == Aspect_FM_NONE ) )
-    {
-      Tfloat* corner1 = 0;/* -1,-1*/
-      Tfloat* corner2 = 0;/*  1,-1*/
-      Tfloat* corner3 = 0;/*  1, 1*/
-      Tfloat* corner4 = 0;/* -1, 1*/
-      Tfloat dcorner1[3];
-      Tfloat dcorner2[3];
-
-      switch( myBgGradient.type )
-      {
-      case Aspect_GFM_HOR:
-        corner1 = myBgGradient.color1.rgb;
-        corner2 = myBgGradient.color2.rgb;
-        corner3 = myBgGradient.color2.rgb;
-        corner4 = myBgGradient.color1.rgb;
-        break;
-      case Aspect_GFM_VER:
-        corner1 = myBgGradient.color2.rgb;
-        corner2 = myBgGradient.color2.rgb;
-        corner3 = myBgGradient.color1.rgb;
-        corner4 = myBgGradient.color1.rgb;
-        break;
-      case Aspect_GFM_DIAG1:
-        corner2 = myBgGradient.color2.rgb;
-        corner4 = myBgGradient.color1.rgb;
-        dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
-        dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
-        dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
-        corner1 = dcorner1;
-        corner3 = dcorner2;
-        break;
-      case Aspect_GFM_DIAG2:
-        corner1 = myBgGradient.color2.rgb;
-        corner3 = myBgGradient.color1.rgb;
-        dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
-        dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
-        dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
-        corner2 = dcorner1;
-        corner4 = dcorner2;
-        break;
-      case Aspect_GFM_CORNER1:
-        corner1 = myBgGradient.color2.rgb;
-        corner2 = myBgGradient.color2.rgb;
-        corner3 = myBgGradient.color2.rgb;
-        corner4 = myBgGradient.color1.rgb;
-        break;
-      case Aspect_GFM_CORNER2:
-        corner1 = myBgGradient.color2.rgb;
-        corner2 = myBgGradient.color2.rgb;
-        corner3 = myBgGradient.color1.rgb;
-        corner4 = myBgGradient.color2.rgb;
-        break;
-      case Aspect_GFM_CORNER3:
-        corner1 = myBgGradient.color2.rgb;
-        corner2 = myBgGradient.color1.rgb;
-        corner3 = myBgGradient.color2.rgb;
-        corner4 = myBgGradient.color2.rgb;
-        break;
-      case Aspect_GFM_CORNER4:
-        corner1 = myBgGradient.color1.rgb;
-        corner2 = myBgGradient.color2.rgb;
-        corner3 = myBgGradient.color2.rgb;
-        corner4 = myBgGradient.color2.rgb;
-        break;
-      default:
-        //printf("gradient background type not right\n");
-        break;
-      }
+    return;
+  }
 
-      // Save GL parameters
-      glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
+  aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
+
+  aCtx->WorldViewState.Push();
+  aCtx->ProjectionState.Push();
+  aCtx->WorldViewState.SetIdentity();
+  aCtx->ProjectionState.SetIdentity();
+  aCtx->ApplyProjectionMatrix();
+  aCtx->ApplyWorldViewMatrix();
+
+  // Drawing background gradient if:
+  // - gradient fill type is not Aspect_GFM_NONE and
+  // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
+  if (myBgGradientArray->IsDefined()
+    && (!myTextureParams->DoTextureMap()
+      || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
+      || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
+  {
+  #if !defined(GL_ES_VERSION_2_0)
+    GLint aShadingModelOld = GL_SMOOTH;
+    if (aCtx->core11 != NULL)
+    {
+      aCtx->core11fwd->glDisable (GL_LIGHTING);
+      aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
+      aCtx->core11->glShadeModel (GL_SMOOTH);
+    }
+  #endif
 
-      GLint curSM;
-      glGetIntegerv( GL_SHADE_MODEL, &curSM );
-      if ( curSM != GL_SMOOTH )
-        glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
+    if (myBgGradientArray->IsDataChanged())
+    {
+      myBgGradientArray->Init (theWorkspace);
+    }
 
-      glBegin(GL_TRIANGLE_FAN);
-      if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
-      {
-        glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
-        glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
-        glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
-        glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
-      }
-      else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
-      {
-        glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
-        glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
-        glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
-        glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
-      }
-      glEnd();
+    myBgGradientArray->Render (theWorkspace);
 
-      // Restore GL parameters
-      if ( curSM != GL_SMOOTH )
-        glShadeModel( curSM );
-    }
-    // drawing bg image if:
-    // - it is defined and
-    // - fill type is not Aspect_FM_NONE
-    if ( myBgTexture.TexId != 0 && myBgTexture.Style != Aspect_FM_NONE )
+  #if !defined(GL_ES_VERSION_2_0)
+    if (aCtx->core11 != NULL)
     {
-      GLfloat texX_range = 1.F; // texture <s> coordinate
-      GLfloat texY_range = 1.F; // texture <t> coordinate
+      aCtx->core11->glShadeModel (aShadingModelOld);
+    }
+  #endif
+  }
 
-      // Set up for stretching or tiling
-      GLfloat x_offset, y_offset;
-      if ( myBgTexture.Style == Aspect_FM_CENTERED )
-      {
-        x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
-        y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
-      }
-      else
-      {
-        x_offset = 1.F;
-        y_offset = 1.F;
-        if ( myBgTexture.Style == Aspect_FM_TILED )
-        {
-          texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
-          texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
-        }
-      }
+  // Drawing background image if it is defined
+  // (texture is defined and fill type is not Aspect_FM_NONE)
+  if (myBgTextureArray->IsDefined()
+   && myTextureParams->DoTextureMap())
+  {
+    aCtx->core11fwd->glDisable (GL_BLEND);
 
-      // OCCT issue 0023000: Improve the way the gradient and textured
-      // background is managed in 3d viewer (note 0020339)
-      // Setting this coefficient to -1.F allows to tile textures relatively
-      // to the top-left corner of the view (value 1.F corresponds to the
-      // initial behaviour - tiling from the bottom-left corner)
-      GLfloat aCoef = -1.F;
-
-      glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
-      glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
-
-      glDisable( GL_BLEND ); //push GL_ENABLE_BIT
-
-      glColor3fv (theWorkspace.BackgroundColor().rgb);
-      glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
-
-      // Note that texture is mapped using GL_REPEAT wrapping mode so integer part
-      // is simply ignored, and negative multiplier is here for convenience only
-      // and does not result e.g. in texture mirroring
-      glBegin( GL_QUADS );
-      glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -aCoef * y_offset );
-      glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -aCoef * y_offset );
-      glTexCoord2f(texX_range, aCoef * texY_range); glVertex2f( x_offset, aCoef * y_offset );
-      glTexCoord2f(0.F, aCoef * texY_range); glVertex2f( -x_offset, aCoef * y_offset );
-      glEnd();
+    const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
+
+    if (myBgTextureArray->IsDataChanged()
+     || myBgTextureArray->IsViewSizeChanged (theWorkspace))
+    {
+      myBgTextureArray->Init (theWorkspace);
     }
 
-    glPopMatrix();
-    glMatrixMode( GL_PROJECTION );
-    glPopMatrix();
-    glMatrixMode( GL_MODELVIEW );
+    myBgTextureArray->Render (theWorkspace);
 
-    glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
+    // restore aspects
+    theWorkspace->SetAspectFace (anOldAspectFace);
+  }
 
-    if (theWorkspace.UseZBuffer())
-      glEnable (GL_DEPTH_TEST);
+  aCtx->WorldViewState.Pop();
+  aCtx->ProjectionState.Pop();
+  aCtx->ApplyProjectionMatrix();
+  aCtx->ApplyWorldViewMatrix();
 
-    /* GL_DITHER on/off pour le trace */
-    if (theWorkspace.Dither())
-      glEnable (GL_DITHER);
-    else
-      glDisable (GL_DITHER);
+  if (theWorkspace->UseZBuffer())
+  {
+    aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
   }
 }
 
@@ -355,10 +244,13 @@ void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
 
 //call_func_redraw_all_structs_proc
 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
-                          const Handle(OpenGl_Workspace) &theWorkspace,
-                          const Graphic3d_CView& theCView,
-                          const Aspect_CLayer2d& theCUnderLayer,
-                          const Aspect_CLayer2d& theCOverLayer)
+                          const Handle(OpenGl_Workspace)&      theWorkspace,
+                          OpenGl_FrameBuffer*                  theOutputFBO,
+                          Graphic3d_Camera::Projection         theProjection,
+                          const Graphic3d_CView&               theCView,
+                          const Aspect_CLayer2d&               theCUnderLayer,
+                          const Aspect_CLayer2d&               theCOverLayer,
+                          const Standard_Boolean               theToDrawImmediate)
 {
   // ==================================
   //      Step 1: Prepare for redraw
@@ -366,72 +258,65 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
 
   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
 
-  // Store and disable current clipping planes
-  Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
-
-  OPENGL_CLIP_PLANE *aOldPlanes = new OPENGL_CLIP_PLANE[aMaxPlanes];
-  OPENGL_CLIP_PLANE *aPtrPlane = aOldPlanes;
-
-  GLenum aClipPlaneId = GL_CLIP_PLANE0;
-  const GLenum aClipLastId = GL_CLIP_PLANE0 + aMaxPlanes;
-  for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
+#if !defined(GL_ES_VERSION_2_0)
+  // Disable current clipping planes
+  if (aContext->core11 != NULL)
   {
-    glGetClipPlane (aClipPlaneId, aPtrPlane->Equation);
-    if (aPtrPlane->isEnabled)
-    {
-      glDisable (aClipPlaneId);
-      aPtrPlane->isEnabled = GL_TRUE;
-    }
-    else
+    const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
+    for (Standard_Integer aClipPlaneId = GL_CLIP_PLANE0; aClipPlaneId < GL_CLIP_PLANE0 + aMaxPlanes; ++aClipPlaneId)
     {
-      aPtrPlane->isEnabled = GL_FALSE;
+      aContext->core11fwd->glDisable (aClipPlaneId);
     }
   }
+#endif
 
-  // Set OCCT state uniform variables
-  const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
-  if (!aManager->IsEmpty())
+  // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
+  Standard_Boolean isProjectionMatUpdateNeeded  = Standard_False;
+  Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
+  if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
   {
-    if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
-    {
-      aManager->UpdateLightSourceStateTo (&myLights);
-      myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
-    }
-
-    if (myProjectionState != myCamera->ProjectionState())
-    {
-      myProjectionState = myCamera->ProjectionState();
-      aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
-    }
+    isProjectionMatUpdateNeeded = Standard_True;
+    myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
+  }
+  if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
+  {
+    isOrientationMatUpdateNeeded = Standard_True;
+    myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
+  }
 
-    if (myModelViewState != myCamera->ModelViewState())
-    {
-      myModelViewState = myCamera->ModelViewState();
-      aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
-    }
+  if (isProjectionMatUpdateNeeded
+   || isOrientationMatUpdateNeeded)
+  {
+    myBVHSelector.SetViewVolume (myCamera);
+  }
 
-    if (aManager->ModelWorldState().Index() == 0)
-    {
-      Tmatrix3 aModelWorldState = { { 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 } };
+  const Handle(OpenGl_ShaderManager)& aManager   = aContext->ShaderManager();
+  const Standard_Boolean              isSameView = aManager->IsSameView (this); // force camera state update when needed
+  if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
+  {
+    aManager->UpdateLightSourceStateTo (&myLights);
+    myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
+  }
 
-      aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorldState);
-    }
+  if (myProjectionState != myCamera->ProjectionState()
+  || !isSameView)
+  {
+    myProjectionState = myCamera->ProjectionState();
+    aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
+    aContext->ApplyProjectionMatrix();
   }
 
-  if (!aManager.IsNull())
+  if (myModelViewState != myCamera->ModelViewState()
+  || !isSameView)
   {
-    if (!aManager->IsSameView (this))
-    {
-      // Force update camera states
-      myProjectionState = myCamera->ProjectionState();
-      aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
+    myModelViewState = myCamera->ModelViewState();
+    aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF());
+    aContext->ApplyWorldViewMatrix();
+  }
 
-      myModelViewState = myCamera->ModelViewState();
-      aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
-    }
+  if (aManager->ModelWorldState().Index() == 0)
+  {
+    aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
   }
 
   // ====================================
@@ -439,16 +324,26 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   // ====================================
 
   // Render background
-  DrawBackground (*theWorkspace);
+  if (!theToDrawImmediate)
+  {
+    DrawBackground (theWorkspace);
+  }
 
+#if !defined(GL_ES_VERSION_2_0)
   // Switch off lighting by default
-  glDisable(GL_LIGHTING);
+  if (aContext->core11 != NULL)
+  {
+    glDisable(GL_LIGHTING);
+  }
+#endif
 
   // =================================
   //      Step 3: Draw underlayer
   // =================================
-
-  RedrawLayer2d (thePrintContext, theCView, theCUnderLayer);
+  if (!theToDrawImmediate)
+  {
+    RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer);
+  }
 
   // =================================
   //      Step 4: Redraw main plane
@@ -468,18 +363,24 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
       glDisable( GL_CULL_FACE );
   }
 
+#if !defined(GL_ES_VERSION_2_0)
   // if the view is scaled normal vectors are scaled to unit
   // length for correct displaying of shaded objects
   const gp_Pnt anAxialScale = myCamera->AxialScale();
-  if(anAxialScale.X() != 1.F ||
-     anAxialScale.Y() != 1.F ||
-     anAxialScale.Z() != 1.F)
-    glEnable(GL_NORMALIZE);
-  else if(glIsEnabled(GL_NORMALIZE))
-    glDisable(GL_NORMALIZE);
+  if (anAxialScale.X() != 1.F ||
+      anAxialScale.Y() != 1.F ||
+      anAxialScale.Z() != 1.F)
+  {
+    aContext->SetGlNormalizeEnabled (Standard_True);
+  }
+  else
+  {
+    aContext->SetGlNormalizeEnabled (Standard_False);
+  }
 
   // Apply Fog
-  if ( myFog.IsOn )
+  if (myFog.IsOn
+   && aContext->core11 != NULL)
   {
     Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
     if (myCamera->ZFar() < aFogFrontConverted)
@@ -499,7 +400,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     {
       myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
       myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
-    }    
+    }
 
     glFogi(GL_FOG_MODE, GL_LINEAR);
     glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
@@ -507,11 +408,20 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
     glEnable(GL_FOG);
   }
-  else
-    glDisable(GL_FOG);
+  else if (aContext->core11 != NULL)
+  {
+    glDisable (GL_FOG);
+  }
 
   // Apply InteriorShadingMethod
-  glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
+  if (aContext->core11 != NULL)
+  {
+    aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
+                                 || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
+  }
+#endif
+
+  aManager->SetShadingModel (myShadingModel);
 
   // Apply AntiAliasing
   if (myAntiAliasing)
@@ -525,43 +435,17 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   }
 
   // Redraw 3d scene
-  if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
+  if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
   {
-    // single-pass monographic rendering
-    const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
-
-    const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
-
-    // redraw scene with normal orientation and projection
-    RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
+    aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
+    aContext->ApplyProjectionMatrix();
   }
-  else
+  else if (theProjection == Graphic3d_Camera::Projection_MonoRightEye)
   {
-    // two stereographic passes
-    const OpenGl_Matrix* aLProj  = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
-    const OpenGl_Matrix* aRProj  = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
-    const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
-
-    // safely switch to left Eye buffer
-    aContext->SetDrawBufferLeft();
-
-    // redraw left Eye
-    RedrawScene (thePrintContext, theWorkspace, aLProj, aOrient);
-
-    // reset depth buffer of first rendering pass
-    if (theWorkspace->UseDepthTest())
-    {
-      glClear (GL_DEPTH_BUFFER_BIT);
-    }
-    // safely switch to right Eye buffer
-    aContext->SetDrawBufferRight();
-    
-    // redraw right Eye
-    RedrawScene (thePrintContext, theWorkspace, aRProj, aOrient);
-
-    // switch back to monographic rendering
-    aContext->SetDrawBufferMono();
+    aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
+    aContext->ApplyProjectionMatrix();
   }
+  RedrawScene (thePrintContext, theWorkspace, theOutputFBO, theCView, theToDrawImmediate);
 
   // ===============================
   //      Step 5: Trihedron
@@ -583,63 +467,42 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     // We need to disable (unbind) all shaders programs to ensure
     // that all objects without specified aspect will be drawn
     // correctly (such as background)
-    OpenGl_ShaderProgram::Unbind (aContext);
+    aContext->BindProgram (NULL);
   }
 
-  // display global trihedron
-  if (myTrihedron != NULL)
-  {
-    myTrihedron->Render (theWorkspace);
-  }
-  if (myGraduatedTrihedron != NULL)
+  // Render trihedron
+  if (!theToDrawImmediate)
   {
-    myGraduatedTrihedron->Render (theWorkspace);
-  }
+    RedrawTrihedron (theWorkspace);
 
-  // Restore face culling
-  if ( myBackfacing )
-  {
-    if ( isCullFace )
+    // Restore face culling
+    if ( myBackfacing )
     {
-      glEnable   ( GL_CULL_FACE );
-      glCullFace ( GL_BACK      );
+      if ( isCullFace )
+      {
+        glEnable   ( GL_CULL_FACE );
+        glCullFace ( GL_BACK      );
+      }
+      else
+        glDisable ( GL_CULL_FACE );
     }
-    else
-      glDisable ( GL_CULL_FACE );
   }
 
   // ===============================
   //      Step 6: Redraw overlay
   // ===============================
+  if (!theToDrawImmediate)
+  {
+    const int aMode = 0;
+    theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
 
-  const int aMode = 0;
-  theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
-
-  RedrawLayer2d (thePrintContext, theCView, theCOverLayer);
-
-  theWorkspace->DisplayCallback (theCView, aMode);
-
-  // ===============================
-  //      Step 7: Finalize
-  // ===============================
-
-  // Restore clipping planes
-  aClipPlaneId = GL_CLIP_PLANE0;
-  aPtrPlane = aOldPlanes;
+    RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
 
-  for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
-  {
-    glClipPlane (aClipPlaneId, aPtrPlane->Equation);
-    if (aPtrPlane->isEnabled)
-      glEnable (aClipPlaneId);
-    else
-      glDisable (aClipPlaneId);
+    theWorkspace->DisplayCallback (theCView, aMode);
   }
 
-  delete[] aOldPlanes;
-
   // ==============================================================
-  //      Step 8: Keep shader manager informed about last View
+  //      Step 7: Keep shader manager informed about last View
   // ==============================================================
 
   if (!aManager.IsNull())
@@ -648,70 +511,187 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   }
 }
 
+// =======================================================================
+// function : InvalidateBVHData
+// purpose  :
+// =======================================================================
+void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
+{
+  myZLayers.InvalidateBVHData (theLayerId);
+}
+
 /*----------------------------------------------------------------------*/
 
 //ExecuteViewDisplay
-void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
+void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& theWorkspace,
+                                 OpenGl_FrameBuffer*             theReadDrawFbo,
+                                 const Graphic3d_CView&          theCView,
+                                 const Standard_Boolean          theToDrawImmediate)
 {
   if ( myZLayers.NbStructures() <= 0 )
     return;
 
-  glPushAttrib ( GL_DEPTH_BUFFER_BIT );
+  const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
 
-  //TsmPushAttri(); /* save previous graphics context */
-
-  if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
+  if ( (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
   {
-    const int antiAliasingMode = AWorkspace->GetDisplay()->AntiAliasingMode();
+  #if !defined(GL_ES_VERSION_2_0)
+    const int anAntiAliasingMode = theWorkspace->AntiAliasingMode();
+  #endif
 
     if ( !myAntiAliasing )
     {
-      glDisable(GL_POINT_SMOOTH);
+    #if !defined(GL_ES_VERSION_2_0)
+      if (aCtx->core11 != NULL)
+      {
+        glDisable (GL_POINT_SMOOTH);
+      }
       glDisable(GL_LINE_SMOOTH);
-      if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
+      if( anAntiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
+    #endif
       glBlendFunc (GL_ONE, GL_ZERO);
       glDisable (GL_BLEND);
     }
     else
     {
-      glEnable(GL_POINT_SMOOTH);
+    #if !defined(GL_ES_VERSION_2_0)
+      if (aCtx->core11 != NULL)
+      {
+        glEnable(GL_POINT_SMOOTH);
+      }
       glEnable(GL_LINE_SMOOTH);
-      if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
+      if( anAntiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
+    #endif
       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       glEnable (GL_BLEND);
     }
   }
 
-  myZLayers.Render (AWorkspace);
+  Standard_Boolean toRenderGL = theToDrawImmediate ||
+    theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myRaytraceInitStatus == OpenGl_RT_FAIL;
+
+  if (!toRenderGL)
+  {
+    toRenderGL = !initRaytraceResources (theCView, aCtx) ||
+      !updateRaytraceGeometry (OpenGl_GUM_CHECK, theWorkspace->ActiveViewId(), aCtx);
+
+    toRenderGL |= !myIsRaytraceDataValid; // if no ray-trace data use OpenGL
+
+    if (!toRenderGL)
+    {
+      const Standard_Integer aSizeX = theReadDrawFbo != NULL ?
+        theReadDrawFbo->GetVPSizeX() : theWorkspace->Width();
+      const Standard_Integer aSizeY = theReadDrawFbo != NULL ?
+        theReadDrawFbo->GetVPSizeY() : theWorkspace->Height();
+
+      if (myOpenGlFBO.IsNull())
+        myOpenGlFBO = new OpenGl_FrameBuffer;
+
+      if (myOpenGlFBO->GetVPSizeX() != aSizeX
+       || myOpenGlFBO->GetVPSizeY() != aSizeY)
+      {
+        myOpenGlFBO->Init (aCtx, aSizeX, aSizeY);
+      }
+
+      if (myRaytraceFilter.IsNull())
+        myRaytraceFilter = new OpenGl_RaytraceFilter;
+
+      myRaytraceFilter->SetPrevRenderFilter (theWorkspace->GetRenderFilter());
+
+      if (theReadDrawFbo != NULL)
+        theReadDrawFbo->UnbindBuffer (aCtx);
+
+      // Prepare preliminary OpenGL output
+      if (aCtx->arbFBOBlit != NULL)
+      {
+        // Render bottom OSD layer
+        myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Bottom);
+
+        theWorkspace->SetRenderFilter (myRaytraceFilter);
+        {
+          if (theReadDrawFbo != NULL)
+          {
+            theReadDrawFbo->BindReadBuffer (aCtx);
+          }
+          else
+          {
+            aCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
+          }
+
+          myOpenGlFBO->BindDrawBuffer (aCtx);
+
+          aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aSizeX, aSizeY,
+                                               0, 0, aSizeX, aSizeY,
+                                               GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+                                               GL_NEAREST);
+
+          // Render non-polygonal elements in default layer
+          myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Default);
+        }
+        theWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
+      }
 
-  //TsmPopAttri(); /* restore previous graphics context; before update lights */
-  glPopAttrib();
+      if (theReadDrawFbo != NULL)
+      {
+        theReadDrawFbo->BindBuffer (aCtx);
+      }
+      else
+      {
+        aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0);
+      }
+
+      // Ray-tracing polygonal primitive arrays
+      raytrace (theCView, aSizeX, aSizeY, theReadDrawFbo, aCtx);
+
+      // Render upper (top and topmost) OpenGL layers
+      myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Upper);
+    }
+  }
+
+  // Redraw 3D scene using OpenGL in standard
+  // mode or in case of ray-tracing failure
+  if (toRenderGL)
+  {
+    myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_All);
+
+    // Set flag that scene was redrawn by standard pipeline
+    theCView.WasRedrawnGL = Standard_True;
+  }
 }
 
 /*----------------------------------------------------------------------*/
 
 //call_togl_redraw_layer2d
 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
-                                 const Graphic3d_CView&               ACView,
+                                 const Handle(OpenGl_Workspace)&      theWorkspace,
+                                 const Graphic3d_CView&               /*ACView*/,
                                  const Aspect_CLayer2d&               ACLayer)
 {
+#if !defined(GL_ES_VERSION_2_0)
   if (&ACLayer == NULL
    || ACLayer.ptrLayer == NULL
    || ACLayer.ptrLayer->listIndex == 0) return;
 
+  const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+  if (aContext->core11 == NULL)
+  {
+    return;
+  }
+
   GLsizei dispWidth  = (GLsizei )ACLayer.viewport[0];
   GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
 
-  glMatrixMode( GL_MODELVIEW );
-  glPushMatrix ();
-  glLoadIdentity ();
+  aContext->WorldViewState.Push();
+  aContext->ProjectionState.Push();
+
+  aContext->WorldViewState.SetIdentity();
+  aContext->ProjectionState.SetIdentity();
 
-  glMatrixMode (GL_PROJECTION);
-  glPushMatrix ();
-  glLoadIdentity ();
+  aContext->ApplyWorldViewMatrix();
+  aContext->ApplyProjectionMatrix();
 
   if (!ACLayer.sizeDependent)
-    glViewport (0, 0, dispWidth, dispHeight);
+    aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
 
   float left = ACLayer.ortho[0];
   float right = ACLayer.ortho[1];
@@ -720,11 +700,9 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
 
   int attach = ACLayer.attach;
 
-  float ratio;
-  if (!ACLayer.sizeDependent)
-    ratio = (float) dispWidth/dispHeight;
-  else
-    ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
+  const float ratio = !ACLayer.sizeDependent
+                    ? float(dispWidth) / float(dispHeight)
+                    : float(theWorkspace->Width()) / float(theWorkspace->Height());
 
   float delta;
   if (ratio >= 1.0) {
@@ -772,7 +750,10 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
     // tiling; scaling of graphics by matrix helps render a
     // part of a view (frame) in same viewport, but with higher
     // resolution
-    thePrintContext->LoadProjTransformation();
+
+    // set printing scale/tiling transformation
+    aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
+    aContext->ApplyProjectionMatrix();
 
     // printing operation also assumes other viewport dimension
     // to comply with transformation matrix or graphics scaling
@@ -781,7 +762,7 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
     GLsizei anViewportY = 0;
     thePrintContext->GetLayerViewport (anViewportX, anViewportY);
     if (anViewportX != 0 && anViewportY != 0)
-      glViewport (0, 0, anViewportX, anViewportY);
+      aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
   }
 #endif
 
@@ -809,131 +790,92 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
 
   glPopAttrib ();
 
-  glMatrixMode (GL_PROJECTION);
-  glPopMatrix ();
+  aContext->WorldViewState.Pop();
+  aContext->ProjectionState.Pop();
 
-  glMatrixMode( GL_MODELVIEW );
-  glPopMatrix ();
+  aContext->ApplyProjectionMatrix();
+  aContext->ApplyWorldViewMatrix();
 
   if (!ACLayer.sizeDependent)
-    glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
+    aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
 
   glFlush ();
+#endif
 }
 
 /*----------------------------------------------------------------------*/
 
-//call_togl_create_bg_texture
-void OpenGl_View::CreateBackgroundTexture (const Standard_CString  theFilePath,
-                                           const Aspect_FillMethod theFillStyle)
+void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
 {
-  if (myBgTexture.TexId != 0)
+  // display global trihedron
+  if (myToShowTrihedron)
   {
-    // delete existing texture
-    glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
-    myBgTexture.TexId = 0;
+    myTrihedron.Render (theWorkspace);
   }
-
-  // load image from file
-  Image_AlienPixMap anImageLoaded;
-  if (!anImageLoaded.Load (theFilePath))
+  if (myToShowGradTrihedron)
   {
-    return;
+    myGraduatedTrihedron.Render (theWorkspace);
   }
+}
 
-  Image_PixMap anImage;
-  if (anImageLoaded.RowExtraBytes() == 0 &&
-      (anImageLoaded.Format() == Image_PixMap::ImgRGB
-    || anImageLoaded.Format() == Image_PixMap::ImgRGB32
-    || anImageLoaded.Format() == Image_PixMap::ImgRGBA))
+/*----------------------------------------------------------------------*/
+
+//call_togl_create_bg_texture
+void OpenGl_View::CreateBackgroundTexture (const Standard_CString  theFilePath,
+                                           const Aspect_FillMethod theFillStyle)
+{
+  // Prepare aspect for texture storage
+  Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
+  Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
+  aTextureMap->EnableRepeat();
+  aTextureMap->DisableModulate();
+  aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
+                                        Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
+                                        Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
+  anAspect->SetTextureMap (aTextureMap);
+  anAspect->SetInteriorStyle (Aspect_IS_SOLID);
+  // Enable texture mapping
+  if (aTextureMap->IsDone())
   {
-    anImage.InitWrapper (anImageLoaded.Format(), anImageLoaded.ChangeData(),
-                         anImageLoaded.SizeX(), anImageLoaded.SizeY(), anImageLoaded.SizeRowBytes());
+    anAspect->SetTextureMapOn();
   }
   else
   {
-    // convert image to RGB format
-    if (!anImage.InitTrash (Image_PixMap::ImgRGB, anImageLoaded.SizeX(), anImageLoaded.SizeY()))
-    {
-      return;
-    }
+    anAspect->SetTextureMapOff();
+    return;
 
-    anImage.SetTopDown (false);
-    Quantity_Color aSrcColor;
-    for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
-    {
-      for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
-      {
-        aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
-        Image_ColorRGB& aColor = anImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
-        aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
-        aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
-        aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
-      }
-    }
-    anImageLoaded.Clear();
   }
 
-  // create MipMapped texture
-  glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
-
-  GLuint aTextureId = 0;
-  glGenTextures (1, &aTextureId);
-  glBindTexture (GL_TEXTURE_2D, aTextureId);
-
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_REPEAT);
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_REPEAT);
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+  // Set texture parameters
+  myTextureParams->SetAspect (anAspect);
 
-  const GLenum aDataFormat = (anImage.Format() == Image_PixMap::ImgRGB) ? GL_RGB : GL_RGBA;
-  gluBuild2DMipmaps (GL_TEXTURE_2D, 3/*4*/,
-                     GLint(anImage.SizeX()), GLint(anImage.SizeY()),
-                     aDataFormat, GL_UNSIGNED_BYTE, anImage.Data());
-
-  myBgTexture.TexId  = aTextureId;
-  myBgTexture.Width  = (Standard_Integer )anImage.SizeX();
-  myBgTexture.Height = (Standard_Integer )anImage.SizeY();
-  myBgTexture.Style  = theFillStyle;
+  myBgTextureArray->SetTextureParameters (theFillStyle);
 }
 
 /*----------------------------------------------------------------------*/
 
 //call_togl_set_bg_texture_style
-void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
+void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle)
 {
-  myBgTexture.Style = AFillStyle;
+  myBgTextureArray->SetTextureFillMethod (theFillStyle);
 }
 
 /*----------------------------------------------------------------------*/
 
 //call_togl_gradient_background
-void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
-                                        const Quantity_Color& AColor2,
-                                        const Aspect_GradientFillMethod AType)
+void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1,
+                                        const Quantity_Color& theColor2,
+                                        const Aspect_GradientFillMethod theType)
 {
-  Standard_Real R,G,B;
-  AColor1.Values( R, G, B, Quantity_TOC_RGB );
-  myBgGradient.color1.rgb[0] = ( Tfloat )R;
-  myBgGradient.color1.rgb[1] = ( Tfloat )G;
-  myBgGradient.color1.rgb[2] = ( Tfloat )B;
-  myBgGradient.color1.rgb[3] = 0.F;
-
-  AColor2.Values( R, G, B, Quantity_TOC_RGB );
-  myBgGradient.color2.rgb[0] = ( Tfloat )R;
-  myBgGradient.color2.rgb[1] = ( Tfloat )G;
-  myBgGradient.color2.rgb[2] = ( Tfloat )B;
-  myBgGradient.color2.rgb[3] = 0.F;
-
-  myBgGradient.type = AType;
+  myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType);
 }
 
 /*----------------------------------------------------------------------*/
 
 //call_togl_set_gradient_type
-void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
+void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType)
 {
-  myBgGradient.type = AType;
+  myBgGradientArray->SetGradientFillMethod (theType);
 }
 
 //=======================================================================
@@ -941,7 +883,7 @@ void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod ATy
 //purpose  :
 //=======================================================================
 
-void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
+void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
 {
   myZLayers.AddLayer (theLayerId);
 }
@@ -951,7 +893,7 @@ void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
 //purpose  :
 //=======================================================================
 
-void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
+void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
 {
   myZLayers.RemoveLayer (theLayerId);
 }
@@ -961,11 +903,12 @@ void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
 //purpose  :
 //=======================================================================
 
-void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
-                                    const Standard_Integer  thePriority)
+void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure,
+                                    const Standard_Integer             thePriority)
 {
-  Standard_Integer aZLayer = theStructure->GetZLayer ();
-  myZLayers.AddStructure (theStructure, aZLayer, thePriority);
+  const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
+  const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
+  myZLayers.AddStructure (aStruct, aZLayer, thePriority);
 }
 
 //=======================================================================
@@ -973,18 +916,19 @@ void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
 //purpose  :
 //=======================================================================
 
-void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructure)
+void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure)
 {
+  const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
   for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
        anIter.More(); anIter.Next())
   {
-    if (anIter.Value() == theStructure)
+    if (anIter.Value() == aStruct)
     {
       return;
     }
   }
 
-  myImmediateList.Append (theStructure);
+  myImmediateList.Append (aStruct);
 }
 
 //=======================================================================
@@ -992,10 +936,9 @@ void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructur
 //purpose  :
 //=======================================================================
 
-void OpenGl_View::EraseStructure (const OpenGl_Structure *theStructure)
+void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure)
 {
-  Standard_Integer aZLayer = theStructure->GetZLayer ();
-  myZLayers.RemoveStructure (theStructure, aZLayer);
+  myZLayers.RemoveStructure (theStructure);
 }
 
 //=======================================================================
@@ -1021,22 +964,44 @@ void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
 //purpose  :
 //=======================================================================
 
-void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
-                                const Standard_Integer  theNewLayerId)
+void OpenGl_View::ChangeZLayer (const OpenGl_Structure*  theStructure,
+                                const Graphic3d_ZLayerId theNewLayerId)
 {
-  Standard_Integer anOldLayer = theStructure->GetZLayer ();
+  const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
   myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
 }
 
+//=======================================================================
+//function : SetZLayerSettings
+//purpose  :
+//=======================================================================
+void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
+                                     const Graphic3d_ZLayerSettings& theSettings)
+{
+  myZLayers.SetLayerSettings (theLayerId, theSettings);
+}
+
+//=======================================================================
+//function : ChangePriority
+//purpose  :
+//=======================================================================
+void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
+                                  const Standard_Integer theNewPriority)
+{
+  const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
+  myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
+}
+
 //=======================================================================
 //function : RedrawScene
 //purpose  :
 //=======================================================================
 
 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
-                               const Handle(OpenGl_Workspace)& theWorkspace,
-                               const OpenGl_Matrix* theProjection,
-                               const OpenGl_Matrix* theOrientation)
+                               const Handle(OpenGl_Workspace)&      theWorkspace,
+                               OpenGl_FrameBuffer*                  theReadDrawFbo,
+                               const Graphic3d_CView&               theCView,
+                               const Standard_Boolean               theToDrawImmediate)
 {
   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
 
@@ -1069,7 +1034,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
     }
 
-    // do some "memory allocation"-wise optimization
+    // Specify slicing planes with identity transformation
     if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
     {
       Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
@@ -1088,7 +1053,17 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
     }
   }
 
-  // Apply user clipping planes
+#ifdef _WIN32
+  // set printing scale/tiling transformation
+  if (!thePrintContext.IsNull())
+  {
+    aContext->ProjectionState.Push();
+    aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
+    aContext->ApplyProjectionMatrix();
+  }
+#endif
+
+  // Specify clipping planes in view transformation space
   if (!myClipPlanes.IsEmpty())
   {
     Graphic3d_SequenceOfHClipPlane aUserPlanes;
@@ -1104,7 +1079,6 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
 
     if (!aUserPlanes.IsEmpty())
     {
-      // add planes at actual matrix state.
       aContext->ChangeClipping().AddWorld (aUserPlanes);
     }
 
@@ -1114,36 +1088,9 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
     }
   }
 
-  // Setup view projection
-  glMatrixMode (GL_PROJECTION);
-
-#ifdef _WIN32
-  // add printing scale/tiling transformation
-  if (!thePrintContext.IsNull())
-  {
-    thePrintContext->LoadProjTransformation();
-  }
-  else
-#endif
-    glLoadIdentity();
-
-  glMultMatrixf ((const GLfloat*)theProjection);
-
-  if (!thePrintContext.IsNull())
-  {
-    // update shader uniform projection matrix with new data
-    Tmatrix3 aResultProjection;
-    glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
-    aContext->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
-
-    // force shader uniform restore on next frame
-    myProjectionState = 0; 
-  }
-
-  // Setup view orientation
-  theWorkspace->SetViewMatrix (theOrientation);
-
+#if !defined(GL_ES_VERSION_2_0)
   // Apply Lights
+  if (aContext->core11 != NULL)
   {
     // setup lights
     Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
@@ -1154,7 +1101,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
     for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
          aLightIt.More(); aLightIt.Next())
     {
-      bind_light (aLightIt.Value(), aLightGlId, anAmbientColor);
+      bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
     }
 
     // apply accumulated ambient color
@@ -1171,10 +1118,14 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       glDisable (aLightGlId);
     }
   }
+#endif
 
   // Clear status bitfields
   theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
 
+  // Update state of surface detail level
+  theWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
+
   // Added PCT for handling of textures
   switch (mySurfaceDetail)
   {
@@ -1182,14 +1133,14 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
       theWorkspace->DisableTexture();
       // Render the view
-      RenderStructs (theWorkspace);
+      RenderStructs (theWorkspace, theReadDrawFbo, theCView, theToDrawImmediate);
       break;
 
     case Visual3d_TOD_ENVIRONMENT:
       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
       theWorkspace->EnableTexture (myTextureEnv);
       // Render the view
-      RenderStructs (theWorkspace);
+      RenderStructs (theWorkspace, theReadDrawFbo, theCView, theToDrawImmediate);
       theWorkspace->DisableTexture();
       break;
 
@@ -1197,7 +1148,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       // First pass
       theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
       // Render the view
-      RenderStructs (theWorkspace);
+      RenderStructs (theWorkspace, theReadDrawFbo, theCView, theToDrawImmediate);
       theWorkspace->DisableTexture();
 
       // Second pass
@@ -1207,13 +1158,15 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
         theWorkspace->EnableTexture (myTextureEnv);
 
         // Remember OpenGl properties
-        GLint aSaveBlendDst, aSaveBlendSrc;
+        GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
         GLint aSaveZbuffFunc;
         GLboolean aSaveZbuffWrite;
         glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
         glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
+      #if !defined(GL_ES_VERSION_2_0)
         glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
         glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
+      #endif
         GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
         GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
 
@@ -1228,7 +1181,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
         theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
 
         // Render the view
-        RenderStructs (theWorkspace);
+        RenderStructs (theWorkspace, theReadDrawFbo, theCView, theToDrawImmediate);
         theWorkspace->DisableTexture();
 
         // Restore properties back
@@ -1243,4 +1196,17 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       }
       break;
   }
+
+  // Apply restored view matrix.
+  aContext->ApplyWorldViewMatrix();
+
+#ifdef _WIN32
+  // set printing scale/tiling transformation
+  if (!thePrintContext.IsNull())
+  {
+    aContext->ProjectionState.Pop();
+    aContext->ApplyProjectionMatrix();
+  }
+#endif
+
 }