0025804: Visualization, TKOpenGl - specify correct primitives type in OpenGl_Backgrou...
[occt.git] / src / OpenGl / OpenGl_View_2.cxx
index 4cced5d..7980367 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>
 
@@ -31,6 +33,7 @@
 #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>
@@ -160,210 +163,99 @@ static void bindLight (const OpenGl_Light&             theLight,
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
+void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
 {
-#if !defined(GL_ES_VERSION_2_0)
-  if ( (theWorkspace.NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
-       ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
-  {
-    const Standard_Integer aViewWidth = theWorkspace.Width();
-    const Standard_Integer aViewHeight = theWorkspace.Height();
-
-    glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
+  const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
 
-    const Handle(OpenGl_Context)& aContext = theWorkspace.GetGlContext();
-
-    aContext->WorldViewState.Push();
-    aContext->ProjectionState.Push();
+  if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
+    || (!myBgTextureArray->IsDefined()                       // no texture
+     && !myBgGradientArray->IsDefined()))                    // no gradient
+  {
+    return;
+  }
 
-    aContext->WorldViewState.SetIdentity();
-    aContext->ProjectionState.SetIdentity();
+  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
 
-    aContext->ApplyProjectionMatrix();
-    aContext->ApplyWorldViewMatrix();
+    if (myBgGradientArray->IsDataChanged())
+    {
+      myBgGradientArray->Init (theWorkspace);
+    }
 
-    if ( glIsEnabled( GL_DEPTH_TEST ) )
-      glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
+    myBgGradientArray->Render (theWorkspace);
 
-    // 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 ) )
+  #if !defined(GL_ES_VERSION_2_0)
+    if (aCtx->core11 != NULL)
     {
-      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;
-      }
-
-      // Save GL parameters
-      glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
+      aCtx->core11->glShadeModel (aShadingModelOld);
+    }
+  #endif
+  }
 
-      GLint curSM;
-      glGetIntegerv( GL_SHADE_MODEL, &curSM );
-      if ( curSM != GL_SMOOTH )
-        glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
+  // 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);
 
-      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();
+    const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
 
-      // 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 (myBgTextureArray->IsDataChanged()
+     || myBgTextureArray->IsViewSizeChanged (theWorkspace))
     {
-      GLfloat texX_range = 1.F; // texture <s> coordinate
-      GLfloat texY_range = 1.F; // texture <t> coordinate
-
-      // 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;
-        }
-      }
-
-      // 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();
+      myBgTextureArray->Init (theWorkspace);
     }
 
-    aContext->WorldViewState.Pop();
-    aContext->ProjectionState.Pop();
+    myBgTextureArray->Render (theWorkspace);
 
-    aContext->ApplyProjectionMatrix();
+    // restore aspects
+    theWorkspace->SetAspectFace (anOldAspectFace);
+  }
 
-    glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
+  aCtx->WorldViewState.Pop();
+  aCtx->ProjectionState.Pop();
+  aCtx->ApplyProjectionMatrix();
 
-    if (theWorkspace.UseZBuffer())
-    {
-      glEnable (GL_DEPTH_TEST);
-    }
+  if (theWorkspace->UseZBuffer())
+  {
+    aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
   }
-#endif
 }
 
 /*----------------------------------------------------------------------*/
 
 //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,
+                          const Graphic3d_CView&               theCView,
+                          const Aspect_CLayer2d&               theCUnderLayer,
+                          const Aspect_CLayer2d&               theCOverLayer,
+                          const Standard_Boolean               theToDrawImmediate)
 {
   // ==================================
   //      Step 1: Prepare for redraw
@@ -448,9 +340,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   // ====================================
 
   // Render background
-  if (theWorkspace->ToRedrawGL())
+  if (theWorkspace->ToRedrawGL()
+  && !theToDrawImmediate)
   {
-    DrawBackground (*theWorkspace);
+    DrawBackground (theWorkspace);
   }
 
 #if !defined(GL_ES_VERSION_2_0)
@@ -461,8 +354,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   // =================================
   //      Step 3: Draw underlayer
   // =================================
-
-  RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer);
+  if (!theToDrawImmediate)
+  {
+    RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer);
+  }
 
   // =================================
   //      Step 4: Redraw main plane
@@ -552,7 +447,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   {
     // single-pass monographic rendering
     // redraw scene with normal orientation and projection
-    RedrawScene (thePrintContext, theWorkspace);
+    RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate);
   }
   else
   {
@@ -565,7 +460,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     aContext->ApplyProjectionMatrix();
 
     // redraw left Eye
-    RedrawScene (thePrintContext, theWorkspace);
+    RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate);
 
     // reset depth buffer of first rendering pass
     if (theWorkspace->UseDepthTest())
@@ -579,7 +474,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     aContext->ApplyProjectionMatrix();
 
     // redraw right Eye
-    RedrawScene (thePrintContext, theWorkspace);
+    RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate);
 
     // switch back to monographic rendering
     aContext->SetDrawBufferMono();
@@ -609,7 +504,8 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   }
 
   // Render trihedron
-  if (theWorkspace->ToRedrawGL())
+  if (theWorkspace->ToRedrawGL()
+  && !theToDrawImmediate)
   {
     RedrawTrihedron (theWorkspace);
 
@@ -629,13 +525,15 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   // ===============================
   //      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, theWorkspace, theCView, theCOverLayer);
+    RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
 
-  theWorkspace->DisplayCallback (theCView, aMode);
+    theWorkspace->DisplayCallback (theCView, aMode);
+  }
 
   // ===============================
   //      Step 7: Finalize
@@ -671,7 +569,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
 // function : InvalidateBVHData
 // purpose  :
 // =======================================================================
-void OpenGl_View::InvalidateBVHData (const Standard_Integer theLayerId)
+void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
 {
   myZLayers.InvalidateBVHData (theLayerId);
 }
@@ -679,7 +577,8 @@ void OpenGl_View::InvalidateBVHData (const Standard_Integer theLayerId)
 /*----------------------------------------------------------------------*/
 
 //ExecuteViewDisplay
-void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
+void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& AWorkspace,
+                                 const Standard_Boolean          theToDrawImmediate)
 {
   if ( myZLayers.NbStructures() <= 0 )
     return;
@@ -718,7 +617,7 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
     }
   }
 
-  myZLayers.Render (AWorkspace);
+  myZLayers.Render (AWorkspace, theToDrawImmediate);
 
 #if !defined(GL_ES_VERSION_2_0)
   //TsmPopAttri(); /* restore previous graphics context; before update lights */
@@ -731,7 +630,7 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
 //call_togl_redraw_layer2d
 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
                                  const Handle(OpenGl_Workspace)&      theWorkspace,
-                                 const Graphic3d_CView&               ACView,
+                                 const Graphic3d_CView&               /*ACView*/,
                                  const Aspect_CLayer2d&               ACLayer)
 {
 #if !defined(GL_ES_VERSION_2_0)
@@ -754,7 +653,7 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
   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];
@@ -763,11 +662,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) {
@@ -827,7 +724,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
 
@@ -862,7 +759,7 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
   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
@@ -889,116 +786,58 @@ void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
 void OpenGl_View::CreateBackgroundTexture (const Standard_CString  theFilePath,
                                            const Aspect_FillMethod theFillStyle)
 {
-  if (myBgTexture.TexId != 0)
+  // 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())
   {
-    // delete existing texture
-    glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
-    myBgTexture.TexId = 0;
+    anAspect->SetTextureMapOn();
   }
-
-  // load image from file
-  Image_AlienPixMap anImageLoaded;
-  if (!anImageLoaded.Load (theFilePath))
+  else
   {
+    anAspect->SetTextureMapOff();
     return;
-  }
 
-  Image_PixMap anImage;
-  if (anImageLoaded.RowExtraBytes() == 0 &&
-      (anImageLoaded.Format() == Image_PixMap::ImgRGB
-    || anImageLoaded.Format() == Image_PixMap::ImgRGB32
-    || anImageLoaded.Format() == Image_PixMap::ImgRGBA))
-  {
-    anImage.InitWrapper (anImageLoaded.Format(), anImageLoaded.ChangeData(),
-                         anImageLoaded.SizeX(), anImageLoaded.SizeY(), anImageLoaded.SizeRowBytes());
   }
-  else
-  {
-    // convert image to RGB format
-    if (!anImage.InitTrash (Image_PixMap::ImgRGB, anImageLoaded.SizeX(), anImageLoaded.SizeY()))
-    {
-      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;
-
-#if !defined(GL_ES_VERSION_2_0)
-  gluBuild2DMipmaps (GL_TEXTURE_2D, 3/*4*/,
-                     GLint(anImage.SizeX()), GLint(anImage.SizeY()),
-                     aDataFormat, GL_UNSIGNED_BYTE, anImage.Data());
-#endif
-
-  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);
 }
 
 //=======================================================================
@@ -1006,7 +845,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);
 }
@@ -1016,7 +855,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);
 }
@@ -1026,11 +865,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);
 }
 
 //=======================================================================
@@ -1038,18 +878,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);
 }
 
 //=======================================================================
@@ -1057,10 +898,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);
 }
 
 //=======================================================================
@@ -1086,10 +926,10 @@ 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);
 }
 
@@ -1097,10 +937,10 @@ void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
 //function : SetZLayerSettings
 //purpose  :
 //=======================================================================
-void OpenGl_View::SetZLayerSettings (const Standard_Integer theLayerId,
-                                     const Graphic3d_ZLayerSettings theSettings)
+void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
+                                     const Graphic3d_ZLayerSettings& theSettings)
 {
-  myZLayers.Layer (theLayerId).SetLayerSettings (theSettings);
+  myZLayers.SetLayerSettings (theLayerId, theSettings);
 }
 
 //=======================================================================
@@ -1110,7 +950,7 @@ void OpenGl_View::SetZLayerSettings (const Standard_Integer theLayerId,
 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
                                   const Standard_Integer theNewPriority)
 {
-  Standard_Integer aLayerId = theStructure->GetZLayer();
+  const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
   myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
 }
 
@@ -1120,7 +960,8 @@ void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
 //=======================================================================
 
 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
-                               const Handle(OpenGl_Workspace)& theWorkspace)
+                               const Handle(OpenGl_Workspace)&      theWorkspace,
+                               const Standard_Boolean               theToDrawImmediate)
 {
   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
 
@@ -1248,14 +1089,14 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
       theWorkspace->DisableTexture();
       // Render the view
-      RenderStructs (theWorkspace);
+      RenderStructs (theWorkspace, theToDrawImmediate);
       break;
 
     case Visual3d_TOD_ENVIRONMENT:
       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
       theWorkspace->EnableTexture (myTextureEnv);
       // Render the view
-      RenderStructs (theWorkspace);
+      RenderStructs (theWorkspace, theToDrawImmediate);
       theWorkspace->DisableTexture();
       break;
 
@@ -1263,7 +1104,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       // First pass
       theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
       // Render the view
-      RenderStructs (theWorkspace);
+      RenderStructs (theWorkspace, theToDrawImmediate);
       theWorkspace->DisableTexture();
 
       // Second pass
@@ -1296,7 +1137,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
         theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
 
         // Render the view
-        RenderStructs (theWorkspace);
+        RenderStructs (theWorkspace, theToDrawImmediate);
         theWorkspace->DisableTexture();
 
         // Restore properties back