0024637: Visualization - clean up implementation of rendering in immediate mode
[occt.git] / src / OpenGl / OpenGl_Workspace_2.cxx
index cf34c95..6ab47d6 100644 (file)
@@ -1,7 +1,17 @@
-// File:      OpenGl_Workspace_2.cxx
-// Created:   20 September 2011
-// Author:    Sergey ZERCHANINOV
-// Copyright: OPEN CASCADE 2011
+// Created on: 2011-09-20
+// Created by: Sergey ZERCHANINOV
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 #include <OpenGl_GlCore11.hxx>
 
 #include <TColStd_Array2OfReal.hxx>
 #include <OpenGl_telem_util.hxx>
 
-#ifdef HAVE_FREEIMAGE
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_FREEIMAGE)
   #include <NCollection_Handle.hxx>
   #include <FreeImagePlus.h>
   #ifdef _MSC_VER
-  #pragma comment( lib, "FreeImage.lib" )
-  #pragma comment( lib, "FreeImagePlus.lib" )
+    #pragma comment( lib, "FreeImage.lib" )
+    #pragma comment( lib, "FreeImagePlus.lib" )
   #endif
   typedef NCollection_Handle<fipImage> FipHandle;
 #endif
 #include <OpenGl_View.hxx>
 #include <OpenGl_Display.hxx>
 
-#include <GL/glu.h> // gluOrtho2D()
-
-//10-05-96 : CAL ; Ajout d'un nouveau delta dans les copies de pixels (voir CALL_DEF_DELTA)
-#define CALL_DEF_DELTA 10
-
-// ---------------------------------------------------------------
-// Function: getNearestPowOfTwo
-// Purpose:  get the nearest power of two for theNumber
-// ---------------------------------------------------------------
-static GLsizei getNearestPowOfTwo (const GLsizei theNumber)
-{
-  GLsizei aLast = 1;
-  for (GLsizei p2 = 1; p2 <= theNumber; aLast = p2, p2 <<= 1);
-  return aLast;
-}
-
-// ---------------------------------------------------------------
-// Function: getMaxFrameSize
-// Purpose:  get the maximum possible frame size
-// ---------------------------------------------------------------
-static void getMaxFrameSize(Standard_Integer& theWidth,
-                            Standard_Integer& theHeight)
-{
-  GLsizei aMaxX, aMaxY;
-  GLint aVpDim[2];
-  GLint aTexDim = 2048;
-  glGetIntegerv (GL_MAX_VIEWPORT_DIMS, (GLint*) &aVpDim);
-  glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aTexDim);
-  (aVpDim[0] >= aTexDim) ? aMaxX = (GLsizei) aTexDim : 
-                           aMaxX = getNearestPowOfTwo((GLsizei)aVpDim[0]);
-  (aVpDim[1] >= aTexDim) ? aMaxY = (GLsizei) aTexDim :
-                           aMaxY = getNearestPowOfTwo((GLsizei)aVpDim[1]);
-
-  theWidth  = (Standard_Integer)aMaxX;
-  theHeight = (Standard_Integer)aMaxY;
-}
-
-// ---------------------------------------------------------------
-// Function: fitDimensionsRatio
-// Purpose:  calculate correct width/height ratio for theWidth and
-//           theHeight parameters
-// ---------------------------------------------------------------
-static void fitDimensionsRatio (Standard_Integer& theWidth,
-                                Standard_Integer& theHeight,
-                                const Standard_Real theViewRatio)
-{
-  // set dimensions in accordance with the viewratio
-  if (theHeight <  theWidth/theViewRatio)
-      theWidth  = (Standard_Integer)(theHeight*theViewRatio);
-
-  if (theWidth  <  theHeight*theViewRatio)
-      theHeight = (Standard_Integer)(theWidth/theViewRatio);
-}
-
-// ---------------------------------------------------------------
-// Function: getDimensionsTiling
-// Purpose:  calculate maximum possible dimensions for framebuffer 
-//           in tiling mode according to the view size
-// ---------------------------------------------------------------
-static void getDimensionsTiling (Standard_Integer& theFrameWidth,
-                                 Standard_Integer& theFrameHeight,
-                                 const int theViewWidth,
-                                 const int theViewHeight)
-{
-  // fit the maximum dimensions into the printing area
-  if (theFrameWidth > theViewWidth)
-      theFrameWidth = theViewWidth;
-
-  if (theFrameHeight > theViewHeight)
-      theFrameHeight = theViewHeight;
-}
-
-// ---------------------------------------------------------------
-// Function: initBufferStretch
-// Purpose:  calculate initialization sizes for frame buffer
-//           when the stretch algorithm is selected
-// ---------------------------------------------------------------
-static void initBufferStretch (Standard_Integer& theFrameWidth,
-                               Standard_Integer& theFrameHeight,
-                               const int theViewWidth,
-                               const int theViewHeight)
-{
-
-  // Calculate correct width/height for framebuffer
-  Standard_Real aViewRatio = (Standard_Real)theViewWidth/theViewHeight;
-  fitDimensionsRatio (theFrameWidth, theFrameHeight, aViewRatio);
-
-  // downscale the framebuffer if it is too large
-  Standard_Real aWidthRate  = (Standard_Real)theFrameWidth /theViewWidth;
-  Standard_Real aHeightRate = (Standard_Real)theFrameHeight/theViewHeight;
 
-  if ((aWidthRate > 1 && aHeightRate > 1 && aWidthRate >= aHeightRate) || 
-      (aWidthRate > 1 && aHeightRate <= 1))
-  {
-    theFrameWidth  = (Standard_Integer)(theFrameWidth /aWidthRate);
-    theFrameHeight = (Standard_Integer)(theFrameHeight/aWidthRate);
-  }
-  else if ((aWidthRate  > 1 && aHeightRate > 1 && aWidthRate < aHeightRate) ||
-           (aWidthRate <= 1 && aHeightRate > 1))
-  {
-    theFrameWidth  = (Standard_Integer)(theFrameWidth /aHeightRate);
-    theFrameHeight = (Standard_Integer)(theFrameHeight/aHeightRate);
-  }
+#ifdef _WIN32
 
-}
-
-// ---------------------------------------------------------------
-// Function: initBufferTiling
-// Purpose:  calculate initialization sizes for frame buffer
-//           when the tile algorithm is selected
-// ---------------------------------------------------------------
-static void initBufferTiling (Standard_Integer& theFrameWidth,
-                              Standard_Integer &theFrameHeight,
-                              const int theViewWidth,
-                              const int theViewHeight)
-{
-  // fit framebuffer into the printing area
-  if (theFrameWidth > theViewWidth)
-      theFrameWidth = theViewWidth;
-
-  if (theFrameHeight > theViewHeight)
-      theFrameHeight = theViewHeight;
-}
+#ifndef HAVE_FREEIMAGE
 
 // ---------------------------------------------------------------
 // Function: initBitmapBuffer
 // Purpose:  init device independent bitmap to hold printing data
 // ---------------------------------------------------------------
-#ifdef WNT
-#ifndef HAVE_FREEIMAGE
 static void initBitmapBuffer (const HDC theMemoryDC,
                               HBITMAP &theMemoryBmp,
                               const   Standard_Integer theBmpWidth,
@@ -179,19 +72,21 @@ static void initBitmapBuffer (const HDC theMemoryDC,
   theMemoryBmp = CreateDIBSection (theMemoryDC, &aBitmapData, DIB_RGB_COLORS,
                                    &theBufferPtr, NULL, 0);
 }
-#else
+
+#else /* HAVE_FREEIMAGE */
+
 // ---------------------------------------------------------------
 // Function: imagePasteDC
 // Purpose:  copy the data from image buffer to the device context
 // ---------------------------------------------------------------
 static bool imagePasteDC(HDC theDstDC,    FipHandle theImage, int theOffsetX,
-                         int theOffsetY,  int theWidth, int theHeight, 
+                         int theOffsetY,  int theWidth, int theHeight,
                          int theLeft = 0, int theTop = 0)
 {
   // get image parameters
   BITMAPINFO* aBitmapData = theImage->getInfo ();
   SetStretchBltMode (theDstDC, STRETCH_HALFTONE);
+
   // organize blocks data passing if memory isn't enough to pass all the data
   // at once
   int aLinesComplete = 0, aMaxBlockWidth = theHeight, aBlockWidth = 0,
@@ -260,28 +155,131 @@ static bool imageStretchDC(HDC theDstDC,   FipHandle theImage, int theOffsetX,
   unsigned int heightPx   = theImage->getHeight ();
   BITMAPINFO* aBitmapData = theImage->getInfo ();
   SetStretchBltMode (theDstDC, STRETCH_HALFTONE);
-  
+
   // pass lines and check if operation is succesfull
   int aPassed = 0;
   aPassed = StretchDIBits (theDstDC, theOffsetX, theOffsetY, theWidth,
                            theHeight, 0, 0, widthPx, heightPx, aDataPtr,
                            aBitmapData, DIB_RGB_COLORS, SRCCOPY);
 
-  if (aPassed != heightPx)
+  if ((unsigned)aPassed != heightPx)
     return false;
+
   return true;
 }
-#endif
-#endif
+
+#endif /* HAVE_FREEIMAGE */
+
+// ---------------------------------------------------------------
+// Function: getNearestPowOfTwo
+// Purpose:  get the nearest power of two for theNumber
+// ---------------------------------------------------------------
+static GLsizei getNearestPowOfTwo (const GLsizei theNumber)
+{
+  GLsizei aLast = 1;
+  for (GLsizei p2 = 1; p2 <= theNumber; aLast = p2, p2 <<= 1);
+  return aLast;
+}
+
+// ---------------------------------------------------------------
+// Function: getMaxFrameSize
+// Purpose:  get the maximum possible frame size
+// ---------------------------------------------------------------
+static void getMaxFrameSize(Standard_Integer& theWidth,
+                            Standard_Integer& theHeight)
+{
+  GLsizei aMaxX, aMaxY;
+  GLint aVpDim[2];
+  GLint aTexDim = 2048;
+  glGetIntegerv (GL_MAX_VIEWPORT_DIMS, (GLint*) &aVpDim);
+  glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aTexDim);
+  (aVpDim[0] >= aTexDim) ? aMaxX = (GLsizei) aTexDim :
+                           aMaxX = getNearestPowOfTwo((GLsizei)aVpDim[0]);
+  (aVpDim[1] >= aTexDim) ? aMaxY = (GLsizei) aTexDim :
+                           aMaxY = getNearestPowOfTwo((GLsizei)aVpDim[1]);
+
+  theWidth  = (Standard_Integer)aMaxX;
+  theHeight = (Standard_Integer)aMaxY;
+}
+
+// ---------------------------------------------------------------
+// Function: fitDimensionsRatio
+// Purpose:  calculate correct width/height ratio for theWidth and
+//           theHeight parameters
+// ---------------------------------------------------------------
+static void fitDimensionsRatio (Standard_Integer& theWidth,
+                                Standard_Integer& theHeight,
+                                const Standard_Real theViewRatio)
+{
+  // set dimensions in accordance with the viewratio
+  if (theHeight <  theWidth/theViewRatio)
+      theWidth  = (Standard_Integer)(theHeight*theViewRatio);
+
+  if (theWidth  <  theHeight*theViewRatio)
+      theHeight = (Standard_Integer)(theWidth/theViewRatio);
+}
+
+// ---------------------------------------------------------------
+// Function: initBufferStretch
+// Purpose:  calculate initialization sizes for frame buffer
+//           when the stretch algorithm is selected
+// ---------------------------------------------------------------
+static void initBufferStretch (Standard_Integer& theFrameWidth,
+                               Standard_Integer& theFrameHeight,
+                               const int theViewWidth,
+                               const int theViewHeight)
+{
+
+  // Calculate correct width/height for framebuffer
+  Standard_Real aViewRatio = (Standard_Real)theViewWidth/theViewHeight;
+  fitDimensionsRatio (theFrameWidth, theFrameHeight, aViewRatio);
+
+  // downscale the framebuffer if it is too large
+  Standard_Real aWidthRate  = (Standard_Real)theFrameWidth /theViewWidth;
+  Standard_Real aHeightRate = (Standard_Real)theFrameHeight/theViewHeight;
+
+  if ((aWidthRate > 1 && aHeightRate > 1 && aWidthRate >= aHeightRate) ||
+      (aWidthRate > 1 && aHeightRate <= 1))
+  {
+    theFrameWidth  = (Standard_Integer)(theFrameWidth /aWidthRate);
+    theFrameHeight = (Standard_Integer)(theFrameHeight/aWidthRate);
+  }
+  else if ((aWidthRate  > 1 && aHeightRate > 1 && aWidthRate < aHeightRate) ||
+           (aWidthRate <= 1 && aHeightRate > 1))
+  {
+    theFrameWidth  = (Standard_Integer)(theFrameWidth /aHeightRate);
+    theFrameHeight = (Standard_Integer)(theFrameHeight/aHeightRate);
+  }
+}
+// ---------------------------------------------------------------
+// Function: initBufferTiling
+// Purpose:  calculate initialization sizes for frame buffer
+//           when the tile algorithm is selected
+// ---------------------------------------------------------------
+static void initBufferTiling (Standard_Integer& theFrameWidth,
+                              Standard_Integer &theFrameHeight,
+                              const int theViewWidth,
+                              const int theViewHeight)
+{
+  // fit framebuffer into the printing area
+  if (theFrameWidth > theViewWidth)
+      theFrameWidth = theViewWidth;
+
+  if (theFrameHeight > theViewHeight)
+      theFrameHeight = theViewHeight;
+}
+
+#endif /* _WIN32 */
 
 // ---------------------------------------------------------------
 // ---------------------------------------------------------------
 
 //call_togl_print
+
 Standard_Boolean OpenGl_Workspace::Print
-  (const Graphic3d_CView& ACView, 
-   const Aspect_CLayer2d& ACUnderLayer, 
+  (const Handle(OpenGl_PrinterContext)& thePrintContext,
+   const Graphic3d_CView& ACView,
+   const Aspect_CLayer2d& ACUnderLayer,
    const Aspect_CLayer2d& ACOverLayer,
    const Aspect_Handle    hPrintDC,// const Aspect_Drawable hPrintDC,
    const Standard_Boolean showBackground,
@@ -289,7 +287,12 @@ Standard_Boolean OpenGl_Workspace::Print
    const Aspect_PrintAlgo printAlgorithm,
    const Standard_Real theScaleFactor)
 {
-#ifdef WNT
+  if (thePrintContext.IsNull())
+  {
+    return Standard_False;
+  }
+
+#ifdef _WIN32
 
   if (!Activate())
   {
@@ -374,9 +377,10 @@ Standard_Boolean OpenGl_Workspace::Print
     }
     else if (IsTiling)
     {
-      getDimensionsTiling (aFrameWidth, aFrameHeight, width, height);
-      if (aPrevWidth >= aFrameWidth && aPrevHeight >= aFrameHeight)
-        isUsable = true;
+      // use previous frame buffer with its dimensions
+      aFrameWidth  = aPrevWidth;
+      aFrameHeight = aPrevHeight;
+      isUsable = true;
     }
 
     // if it is enough memory for image paste dc operation
@@ -404,7 +408,7 @@ Standard_Boolean OpenGl_Workspace::Print
       }
 #else
       // try to allocate compatible bitmap and necessary resources
-      initBitmapBuffer (hMemDC, hViewBitmap, 
+      initBitmapBuffer (hMemDC, hViewBitmap,
                         aFrameWidth, aFrameHeight, aViewBuffer);
       if (!aViewBuffer)
       {
@@ -466,7 +470,7 @@ Standard_Boolean OpenGl_Workspace::Print
 
         if (!aViewBuffer)
         {
-          aFrameBuffer->Release (GetGlContext());
+          aFrameBuffer->Release (GetGlContext().operator->());
           aViewBuffer = NULL;
           aViewImage  = NULL;
         }
@@ -474,13 +478,13 @@ Standard_Boolean OpenGl_Workspace::Print
           break;
 #else
         // try to allocate compatible bitmap and necessary resources
-        initBitmapBuffer (hMemDC, hViewBitmap, 
+        initBitmapBuffer (hMemDC, hViewBitmap,
                           aFrameWidth, aFrameHeight, aViewBuffer);
         if (!aViewBuffer)
         {
           if (hViewBitmap)
             DeleteObject (hViewBitmap);
-          aFrameBuffer->Release (GetGlContext());
+          aFrameBuffer->Release (GetGlContext().operator->());
           hViewBitmap = NULL;
         }
         else
@@ -496,7 +500,7 @@ Standard_Boolean OpenGl_Workspace::Print
       aMaxHeight = aMaxHeight >> 1;
     }
 
-    // check if there are proper dimensions 
+    // check if there are proper dimensions
     if (aMaxWidth <= 1 || aMaxHeight <= 1)
     {
       MessageBox (NULL, "Print failed: can't allocate buffer for printing.",
@@ -514,12 +518,11 @@ Standard_Boolean OpenGl_Workspace::Print
   }
 
   // setup printing context and viewport
-  GLint aViewPortBack[4]; 
-  GLint anAlignBack     = 1;
-
-  OpenGl_PrinterContext aPrinterContext (myGContext);
-  aPrinterContext.SetLayerViewport ((GLsizei)aFrameWidth,
-                                    (GLsizei)aFrameHeight);
+  myPrintContext = thePrintContext;
+  GLint aViewPortBack[4];
+  GLint anAlignBack = 1;
+  myPrintContext->SetLayerViewport ((GLsizei )aFrameWidth,
+                                    (GLsizei )aFrameHeight);
   glGetIntegerv (GL_VIEWPORT, aViewPortBack);
   glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
   glPixelStorei (GL_PACK_ALIGNMENT, 4);
@@ -548,6 +551,7 @@ Standard_Boolean OpenGl_Workspace::Print
       DeleteDC (hMemDC);
 #endif
 
+      myPrintContext.Nullify();
       return Standard_False;
     }
   }
@@ -568,11 +572,15 @@ Standard_Boolean OpenGl_Workspace::Print
 
   if (!IsTiling)
   {
-    aPrinterContext.SetScale ((GLfloat)aFrameWidth /viewWidth,
-                              (GLfloat)aFrameHeight/viewHeight);
-    aFrameBuffer->SetupViewport ();
-    Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
-    RedrawImmediatMode();
+    myPrintContext->SetScale ((GLfloat )aFrameWidth /viewWidth,
+                              (GLfloat )aFrameHeight/viewHeight);
+    aFrameBuffer->SetupViewport (GetGlContext());
+    redraw1 (ACView, ACUnderLayer, ACOverLayer, 0);
+    if (!myTransientDrawToFront)
+    {
+      // render to FBO only if allowed to render to back buffer
+      RedrawImmediate (ACView, ACUnderLayer, ACOverLayer, Standard_True);
+    }
     glReadPixels (0, 0, aFrameWidth, aFrameHeight,
                   GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
 
@@ -586,13 +594,13 @@ Standard_Boolean OpenGl_Workspace::Print
     if (width > aFrameWidth && height > aFrameHeight)
     {
       SetStretchBltMode (hPrnDC, STRETCH_HALFTONE);
-      isDone = StretchBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
-                           hMemDC, 0, 0, aFrameWidth, aFrameHeight, SRCCOPY);
+      isDone = (StretchBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
+                            hMemDC, 0, 0, aFrameWidth, aFrameHeight, SRCCOPY) != 0); // to avoid warning C4800
     }
     else
     {
-      isDone = BitBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
-                       hMemDC, 0, 0, SRCCOPY);
+      isDone = (BitBlt (hPrnDC, aDevOffx, aDevOffy, width, height,
+                        hMemDC, 0, 0, SRCCOPY) != 0); // to avoid warning C4800
     }
 #endif
   }
@@ -601,9 +609,9 @@ Standard_Boolean OpenGl_Workspace::Print
     // calculate total count of frames and cropping size
     Standard_Integer aPxCropx = 0;
     Standard_Integer aPxCropy = 0;
-    Standard_Integer aTotalx = 
+    Standard_Integer aTotalx =
                      (Standard_Integer)floor ((float)width /aFrameWidth);
-    Standard_Integer aTotaly = 
+    Standard_Integer aTotaly =
                      (Standard_Integer)floor ((float)height/aFrameHeight);
     if (width %aFrameWidth != 0)
     {
@@ -626,8 +634,8 @@ Standard_Boolean OpenGl_Workspace::Print
     // calculate and set the text scaling factor for printing context
     GLfloat aScaleRatex = (GLfloat)aFrameWidth /viewWidth;
     GLfloat aScaleRatey = (GLfloat)aFrameHeight/viewHeight;
-    aPrinterContext.SetScale (aScaleRatex*(GLfloat)aScalex,
-                              aScaleRatey*(GLfloat)aScaley);
+    myPrintContext->SetScale (aScaleRatex * (GLfloat )aScalex,
+                              aScaleRatey * (GLfloat )aScaley);
 
     // initialize projection matrix for printer context
     TColStd_Array2OfReal aProj (0, 3, 0, 3);
@@ -669,7 +677,7 @@ Standard_Boolean OpenGl_Workspace::Print
         // set projection matrix
         aProj(0,0) = aScalex;
         aProj(1,1) = aScaley;
-        aPrinterContext.SetProjTransformation (aProj);
+        myPrintContext->SetProjTransformation (aProj);
 
         // calculate cropped frame rect
         aTop    = (j == 0)         ? aPxCropy : 0;
@@ -677,9 +685,13 @@ Standard_Boolean OpenGl_Workspace::Print
                                      aFrameHeight;
 
         // draw to the offscreen buffer and capture the result
-        aFrameBuffer->SetupViewport ();
-        Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
-        RedrawImmediatMode();
+        aFrameBuffer->SetupViewport (GetGlContext());
+        redraw1 (ACView, ACUnderLayer, ACOverLayer, 0);
+        if (!myTransientDrawToFront)
+        {
+          // render to FBO only if forces to render to back buffer
+          RedrawImmediate (ACView, ACUnderLayer, ACOverLayer, Standard_True);
+        }
         glReadPixels (0, 0, aFrameWidth, aFrameHeight,
                       GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
 #ifdef HAVE_FREEIMAGE
@@ -687,8 +699,8 @@ Standard_Boolean OpenGl_Workspace::Print
         isDone = imagePasteDC (hPrnDC, aViewImage, aSubLeft, aSubTop,
                                aRight-aLeft, aBottom-aTop, aLeft, aTop);
 #else
-        isDone = BitBlt (hPrnDC, aSubLeft, aSubTop, aRight-aLeft, aBottom-aTop,
-                         hMemDC, aLeft, aTop, SRCCOPY);
+        isDone = (BitBlt (hPrnDC, aSubLeft, aSubTop, aRight-aLeft, aBottom-aTop,
+                          hMemDC, aLeft, aTop, SRCCOPY) != 0); // to avoid warning C4800
 #endif
 
         // stop operation if errors
@@ -703,7 +715,7 @@ Standard_Boolean OpenGl_Workspace::Print
       // stop operation if errors
       if (!isDone)
         break;
+
       // calculate new view offset for x-coordinate
       aOffsetx += 2.0;
       aSubLeft += aRight-aLeft;
@@ -723,17 +735,21 @@ Standard_Boolean OpenGl_Workspace::Print
     if (GetObjectType (hPrnDC) == OBJ_DC)
       AbortDoc (hPrnDC);
   }
-  
+
   // return OpenGl to the previous state
-  aPrinterContext.Deactivate ();
   glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
   aFrameBuffer->UnbindBuffer (GetGlContext());
-  glViewport (aViewPortBack[0], aViewPortBack[1], 
+  glViewport (aViewPortBack[0], aViewPortBack[1],
               aViewPortBack[2], aViewPortBack[3]);
   if (aPrevBuffer)
+  {
     aPrevBuffer->ChangeViewport (aPrevBufferX, aPrevBufferY);
+  }
   else
+  {
+    aFrameBuffer->Release (GetGlContext().operator->());
     delete aFrameBuffer;
+  }
 
   // delete resources
 #ifndef HAVE_FREEIMAGE
@@ -748,210 +764,11 @@ Standard_Boolean OpenGl_Workspace::Print
   // Reset status after printing
   NamedStatus &= ~OPENGL_NS_WHITEBACK;
 
+  myPrintContext.Nullify();
   return (Standard_Boolean) isDone;
 
-#else // not WNT
+#else // not _WIN32
+  myPrintContext.Nullify();
   return Standard_False;
-#endif 
-}
-
-/*----------------------------------------------------------------------*/
-
-//redrawView
-void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView, 
-                               const Aspect_CLayer2d& ACUnderLayer, 
-                               const Aspect_CLayer2d& ACOverLayer,
-                               const int aswap)
-{
-  if (myDisplay.IsNull() || myView.IsNull())
-    return;
-
-  myDisplay->UpdateUserMarkers();
-
-  // Request reset of material
-  NamedStatus |= OPENGL_NS_RESMAT;
-
-  /* GL_DITHER on/off pour le background */
-  if (myBackDither)
-    glEnable (GL_DITHER);
-  else
-    glDisable (GL_DITHER);
-
-  GLbitfield toClear = GL_COLOR_BUFFER_BIT;
-  if ( myUseZBuffer )
-  {
-    glDepthFunc(GL_LEQUAL);
-    glDepthMask(GL_TRUE);
-
-    // SAV checking if depth test was deprecated somewhere outside
-    if ( myUseDepthTest )
-      glEnable(GL_DEPTH_TEST);
-    else
-      glDisable(GL_DEPTH_TEST);
-
-    glClearDepth(1.0);
-       toClear |= GL_DEPTH_BUFFER_BIT;
-  }
-  else
-  {
-    glDisable(GL_DEPTH_TEST);
-  }
-
-  if ( NamedStatus & OPENGL_NS_WHITEBACK )
-  {
-    // Set background to white
-    glClearColor (1.F, 1.F, 1.F, 1.F);
-       toClear |= GL_DEPTH_BUFFER_BIT;
-  }
-  else
-  {
-    glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.F);
-  }
-  glClear (toClear);
-
-  Handle(OpenGl_Workspace) aWS(this);
-  myView->Render(aWS,ACView,ACUnderLayer,ACOverLayer);
-
-  // Swap the buffers
-  if ( aswap )
-  {
-#ifndef WNT
-    glXSwapBuffers ((Display*)myDisplay->GetDisplay (), myWindow );
-#else
-    SwapBuffers ( wglGetCurrentDC () );
-    glFlush();
-#endif  /* WNT */
-    myBackBufferRestored = Standard_False;
-  }
-  else
-    glFlush();
-
-  myIsUpdated = Standard_True;
-}
-
-/*----------------------------------------------------------------------*/
-
-//TelCopyBuffers
-void OpenGl_Workspace::CopyBuffers (Tint vid, int FrontToBack, Tfloat xm, Tfloat ym, Tfloat zm, Tfloat XM, Tfloat YM, Tfloat ZM, Tint flag)
-{
-  if (FrontToBack) myBackBufferRestored = Standard_False;
-
-  glMatrixMode (GL_PROJECTION);
-  glPushMatrix ();
-  glLoadIdentity ();
-  gluOrtho2D ((GLdouble) 0., (GLdouble) myWidth, 0., (GLdouble) myHeight);
-  glMatrixMode (GL_MODELVIEW);
-  glPushMatrix ();
-  glLoadIdentity ();
-
-  DisableFeatures();
-
-  GLsizei width = myWidth+1, height = myHeight+1;
-  Tfloat xmr = 0, ymr = 0;
-
-  if (flag) 
-  {
-    if (!myView.IsNull()) //szvgl: use vid here!
-       {
-    // Calculate bounding box and store the projected rectangle
-    Tfloat xr[8], yr[8];
-    // Project bounding box
-    if (myView->ProjectObjectToRaster (myWidth, myHeight, xm, ym, zm, xr[0], yr[0]) &&
-        myView->ProjectObjectToRaster (myWidth, myHeight, xm, YM, zm, xr[1], yr[1]) &&
-        myView->ProjectObjectToRaster (myWidth, myHeight, XM, YM, zm, xr[2], yr[2]) &&
-        myView->ProjectObjectToRaster (myWidth, myHeight, XM, ym, zm, xr[3], yr[3]) &&
-        myView->ProjectObjectToRaster (myWidth, myHeight, xm, ym, ZM, xr[4], yr[4]) &&
-        myView->ProjectObjectToRaster (myWidth, myHeight, xm, YM, ZM, xr[5], yr[5]) &&
-        myView->ProjectObjectToRaster (myWidth, myHeight, XM, YM, ZM, xr[6], yr[6]) &&
-        myView->ProjectObjectToRaster (myWidth, myHeight, XM, ym, ZM, xr[7], yr[7]))
-    {
-      Tfloat XMR, YMR;
-      xmr = ymr = (float ) shortreallast ();
-      XMR = YMR = (float ) shortrealfirst ();
-      /*
-      * Recherche du rectangle projete
-      */
-      Tint i;
-      for (i=0; i<8; i++) {
-        if (xmr > xr[i]) xmr = xr[i];
-        if (ymr > yr[i]) ymr = yr[i];
-        if (XMR < xr[i]) XMR = xr[i];
-        if (YMR < yr[i]) YMR = yr[i];
-      }
-      /* pour eviter les bavures de pixels ! */
-      xmr--;ymr--;
-      XMR++;YMR++;
-
-      /*
-      * Ajout CAL : 10/05/96
-      * Si les MinMax viennent d'un ensemble de markers
-      * on ne tient pas compte du scale factor de ceux-ci
-      * dans les valeurs de MinMax. En effet, ce facteur
-      * est dans l'espace pixel et les MinMax dans l'espace
-      * du modele. Donc ajout d'un delta de pixels
-      * en esperant que les applis n'utilisent pas des
-      * markers tres gros !
-      */
-      xmr -= CALL_DEF_DELTA; ymr -= CALL_DEF_DELTA;
-      XMR += CALL_DEF_DELTA; YMR += CALL_DEF_DELTA;
-
-      /*
-      * Le rectangle projete peut-etre clippe
-      */
-      width = (GLsizei) (XMR-xmr+1);
-      height = (GLsizei) (YMR-ymr+1);
-      /*
-      * (xmr,ymr) coin inferieur gauche
-      * (XMR,YMR) coin superieur droit
-      */
-      /* cas ou 1 coin est en dehors de la fenetre */
-      if (xmr < 0) { width  = (GLsizei) (XMR+1); xmr = 0; }
-      if (ymr < 0) { height = (GLsizei) (YMR+1); ymr = 0; }
-      if (XMR > myWidth)  { width  = (GLsizei) (myWidth-xmr+1); }
-      if (YMR > myHeight) { height = (GLsizei) (myHeight-ymr+1); }
-
-      /* cas ou les 2 coins sont en dehors de la fenetre */
-      if (XMR < 0) { xmr = 0; width = height = 1; }
-      if (YMR < 0) { ymr = 0; width = height = 1; }
-      if (xmr > myWidth)  { xmr = 0; width = height = 1; }
-      if (ymr > myHeight) { ymr = 0; width = height = 1; }
-    }
-       }
-  }
-
-  glDrawBuffer (FrontToBack? GL_BACK : GL_FRONT);
-  glReadBuffer (FrontToBack? GL_FRONT : GL_BACK);
-  /* copie complete */
-  glRasterPos2i ((GLint) xmr, (GLint) ymr);
-  glCopyPixels ((GLint) xmr, (GLint) ymr, width, height, GL_COLOR);
-
-  EnableFeatures();
-
-  glMatrixMode (GL_PROJECTION);
-  glPopMatrix ();
-  glMatrixMode (GL_MODELVIEW);
-  glPopMatrix ();
-
-  glDrawBuffer (GL_BACK);
-}
-
-/*----------------------------------------------------------------------*/
-
-//call_subr_displayCB
-void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& ACView, int reason)
-{
-  if( ACView.GDisplayCB )
-  {
-    Aspect_GraphicCallbackStruct callData;
-    callData.reason = reason;
-    callData.display = (DISPLAY*)myDisplay->GetDisplay();
-    callData.window = (WINDOW)myWindow;
-    callData.wsID = ACView.WsId;
-    callData.viewID = ACView.ViewId;
-    callData.gcontext = myGContext;
-
-    int status = (*ACView.GDisplayCB)( ACView.DefWindow.XWindow, ACView.GClientData, &callData );
-  }
+#endif
 }
-
-/*----------------------------------------------------------------------*/