0024637: Visualization - clean up implementation of rendering in immediate mode
[occt.git] / src / OpenGl / OpenGl_Workspace_2.cxx
index d5a23e2..6ab47d6 100644 (file)
@@ -1,22 +1,17 @@
 // Created on: 2011-09-20
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 #include <OpenGl_GlCore11.hxx>
 
 #include <OpenGl_View.hxx>
 #include <OpenGl_Display.hxx>
 
-//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;
-}
+#ifdef _WIN32
 
-// ---------------------------------------------------------------
-// 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;
-}
+#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,
@@ -196,7 +72,9 @@ 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
@@ -284,18 +162,120 @@ static bool imageStretchDC(HDC theDstDC,   FipHandle theImage, int theOffsetX,
                            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 Handle(OpenGl_PrinterContext)& thePrintContext,
    const Graphic3d_CView& ACView,
@@ -312,7 +292,7 @@ Standard_Boolean OpenGl_Workspace::Print
     return Standard_False;
   }
 
-#ifdef WNT
+#ifdef _WIN32
 
   if (!Activate())
   {
@@ -397,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
@@ -489,7 +470,7 @@ Standard_Boolean OpenGl_Workspace::Print
 
         if (!aViewBuffer)
         {
-          aFrameBuffer->Release (GetGlContext());
+          aFrameBuffer->Release (GetGlContext().operator->());
           aViewBuffer = NULL;
           aViewImage  = NULL;
         }
@@ -503,7 +484,7 @@ Standard_Boolean OpenGl_Workspace::Print
         {
           if (hViewBitmap)
             DeleteObject (hViewBitmap);
-          aFrameBuffer->Release (GetGlContext());
+          aFrameBuffer->Release (GetGlContext().operator->());
           hViewBitmap = NULL;
         }
         else
@@ -593,12 +574,12 @@ Standard_Boolean OpenGl_Workspace::Print
   {
     myPrintContext->SetScale ((GLfloat )aFrameWidth /viewWidth,
                               (GLfloat )aFrameHeight/viewHeight);
-    aFrameBuffer->SetupViewport ();
-    Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
+    aFrameBuffer->SetupViewport (GetGlContext());
+    redraw1 (ACView, ACUnderLayer, ACOverLayer, 0);
     if (!myTransientDrawToFront)
     {
       // render to FBO only if allowed to render to back buffer
-      RedrawImmediatMode();
+      RedrawImmediate (ACView, ACUnderLayer, ACOverLayer, Standard_True);
     }
     glReadPixels (0, 0, aFrameWidth, aFrameHeight,
                   GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
@@ -704,12 +685,12 @@ Standard_Boolean OpenGl_Workspace::Print
                                      aFrameHeight;
 
         // draw to the offscreen buffer and capture the result
-        aFrameBuffer->SetupViewport ();
-        Redraw1(ACView, ACUnderLayer, ACOverLayer, 0);
+        aFrameBuffer->SetupViewport (GetGlContext());
+        redraw1 (ACView, ACUnderLayer, ACOverLayer, 0);
         if (!myTransientDrawToFront)
         {
           // render to FBO only if forces to render to back buffer
-          RedrawImmediatMode();
+          RedrawImmediate (ACView, ACUnderLayer, ACOverLayer, Standard_True);
         }
         glReadPixels (0, 0, aFrameWidth, aFrameHeight,
                       GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
@@ -766,7 +747,7 @@ Standard_Boolean OpenGl_Workspace::Print
   }
   else
   {
-    aFrameBuffer->Release (GetGlContext ());
+    aFrameBuffer->Release (GetGlContext().operator->());
     delete aFrameBuffer;
   }
 
@@ -786,132 +767,8 @@ Standard_Boolean OpenGl_Workspace::Print
   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 (myPrintContext, aWS, ACView, ACUnderLayer, ACOverLayer);
-
-  // Swap the buffers
-  if ( aswap )
-  {
-    GetGlContext()->SwapBuffers();
-    myBackBufferRestored = Standard_False;
-  }
-  else
-    glFlush();
-}
-
-/*----------------------------------------------------------------------*/
-
-//TelCopyBuffers
-void OpenGl_Workspace::CopyBuffers (const Standard_Boolean theFrontToBack)
-{
-  if (theFrontToBack)
-  {
-    myBackBufferRestored = Standard_False;
-  }
-
-  glMatrixMode (GL_PROJECTION);
-  glPushMatrix ();
-  glLoadIdentity ();
-  gluOrtho2D ((GLdouble) 0., (GLdouble) myWidth, 0., (GLdouble) myHeight);
-  glMatrixMode (GL_MODELVIEW);
-  glPushMatrix ();
-  glLoadIdentity ();
-
-  DisableFeatures();
-
-  glDrawBuffer (theFrontToBack ? GL_BACK  : GL_FRONT);
-  glReadBuffer (theFrontToBack ? GL_FRONT : GL_BACK);
-
-  glRasterPos2i (0, 0);
-  glCopyPixels  (0, 0, myWidth  + 1, myHeight + 1, GL_COLOR);
-
-  EnableFeatures();
-
-  glMatrixMode (GL_PROJECTION);
-  glPopMatrix ();
-  glMatrixMode (GL_MODELVIEW);
-  glPopMatrix ();
-
-  glDrawBuffer (GL_BACK);
-}
-
-/*----------------------------------------------------------------------*/
-
-//call_subr_displayCB
-void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
-                                        int theReason)
-{
-  if (theCView.GDisplayCB == NULL)
-  {
-    return;
-  }
-
-  Aspect_GraphicCallbackStruct aCallData;
-  aCallData.reason    = theReason;
-  aCallData.glContext = GetGlContext();
-  aCallData.wsID      = theCView.WsId;
-  aCallData.viewID    = theCView.ViewId;
-  theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
-}
-
-/*----------------------------------------------------------------------*/