]> OCCT Git - occt-copy.git/commitdiff
0025091: Visualization - use FBO for layer with immediate objects
authorkgv <kgv@opencascade.com>
Tue, 23 Dec 2014 19:50:47 +0000 (22:50 +0300)
committerkgv <kgv@opencascade.com>
Thu, 25 Dec 2014 09:11:45 +0000 (12:11 +0300)
src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_FrameBuffer.hxx
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx

index 4d45461cd020d995f0e8e09e476d029bf897b083..6b8cd97363aa248554813f1499b8fec3f1e04eb7 100644 (file)
@@ -176,6 +176,24 @@ void OpenGl_FrameBuffer::BindBuffer (const Handle(OpenGl_Context)& theGlCtx)
   theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
 }
 
+// =======================================================================
+// function : BindDrawBuffer
+// purpose  :
+// =======================================================================
+void OpenGl_FrameBuffer::BindDrawBuffer (const Handle(OpenGl_Context)& theGlCtx)
+{
+  theGlCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myGlFBufferId);
+}
+
+// =======================================================================
+// function : BindReadBuffer
+// purpose  :
+// =======================================================================
+void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx)
+{
+  theGlCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, myGlFBufferId);
+}
+
 // =======================================================================
 // function : UnbindBuffer
 // purpose  :
index 3a4eeb4530e96fe6cb7d96c41c99561697d54c78..b091e50aae82b2f6ab0f214c27e6395c6a4656ed 100644 (file)
@@ -92,9 +92,15 @@ public:
   Standard_EXPORT void ChangeViewport (const GLsizei theVPSizeX,
                                        const GLsizei theVPSizeY);
 
-  //! Bind frame buffer (to render into the texture).
+  //! Bind frame buffer for drawing and reading (to render into the texture).
   Standard_EXPORT virtual void BindBuffer (const Handle(OpenGl_Context)& theGlCtx);
 
+  //! Bind frame buffer for drawing GL_DRAW_FRAMEBUFFER (to render into the texture).
+  Standard_EXPORT virtual void BindDrawBuffer (const Handle(OpenGl_Context)& theGlCtx);
+
+  //! Bind frame buffer for reading GL_READ_FRAMEBUFFER
+  Standard_EXPORT virtual void BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx);
+
   //! Unbind frame buffer.
   Standard_EXPORT virtual void UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx);
 
index a4013e8b5d3dc1e538c2dbf5d4f22e479ddb5459..c567017efb4c87f077673d0b5bded0bcd65aadfa 100644 (file)
@@ -73,10 +73,10 @@ public:
     const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
 
     glDisable (GL_LIGHTING);
-    if ((theWorkspace->NamedStatus & OPENGL_NS_IMMEDIATE) != 0)
+    /**if ((theWorkspace->NamedStatus & OPENGL_NS_IMMEDIATE) != 0)
     {
       glDepthMask (GL_FALSE);
-    }
+    }*/
 
     // Use highlight colors
     theWorkspace->GetGlContext()->core11->glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
index c737d42a6666ff1c8282a4832de994d375314a5e..1d2b049c258a909c15ea19c3692e10e2ad9fa768 100644 (file)
@@ -14,6 +14,7 @@
 // commercial license or contractual agreement.
 
 #include <OpenGl_GlCore15.hxx>
+#include <OpenGl_ArbFBO.hxx>
 
 #include <InterfaceGraphic.hxx>
 
@@ -180,6 +181,7 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDrive
   PolygonOffset_applied (THE_DEFAULT_POFFSET)
 {
   myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+  myResultFBO = new OpenGl_FrameBuffer();
 
   if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
   {
@@ -235,6 +237,12 @@ OpenGl_Workspace::~OpenGl_Workspace()
     myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
   }
 
+  if (!myResultFBO.IsNull())
+  {
+    myResultFBO->Release (myGlContext.operator->());
+    myResultFBO.Nullify();
+  }
+
   ReleaseRaytraceResources();
 }
 
@@ -650,6 +658,22 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
     aGlCtx->core11fwd->glViewport (0, 0, myWidth, myHeight);
   }
 
+  Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
+  Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
+
+  if (myResultFBO->GetVPSizeX() != aSizeX
+   || myResultFBO->GetVPSizeY() != aSizeY)
+  {
+    myResultFBO->Init (aGlCtx, aSizeX, aSizeY);
+  }
+  if (myResultFBO->IsValid())
+  {
+    myResultFBO->SetupViewport (aGlCtx);
+  }
+
+  const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty()
+                                     || myResultFBO->IsValid();
+
   myToRedrawGL = Standard_True;
   if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
    && myComputeInitStatus != OpenGl_RT_FAIL)
@@ -663,9 +687,6 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
       myRaytraceFilter->SetPrevRenderFilter (aRenderFilter);
       SetRenderFilter (myRaytraceFilter);
 
-      Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
-      Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
-
       if (myOpenGlFBO.IsNull())
       {
         myOpenGlFBO = new OpenGl_FrameBuffer();
@@ -685,13 +706,13 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
       redraw1 (theCView, anEmptyCLayer, anEmptyCLayer, 0);
       myOpenGlFBO->UnbindBuffer (aGlCtx);
 
-      const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
       Raytrace (theCView, aSizeX, aSizeY, isImmediate ? 0 : toSwap,
-                theCOverLayer, theCUnderLayer, aFrameBuffer);
+                theCOverLayer, theCUnderLayer,
+                myResultFBO->IsValid() ? myResultFBO.operator->() : aFrameBuffer);
 
       if (isImmediate)
       {
-        RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
+        RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True, aFrameBuffer);
       }
 
       SetRenderFilter (aRenderFilter);
@@ -703,16 +724,19 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
   if (myToRedrawGL)
   {
     // draw entire frame using normal OpenGL pipeline
-    if (aFrameBuffer != NULL)
+    if (myResultFBO->IsValid())
+    {
+      myResultFBO->BindBuffer (aGlCtx);
+    }
+    else if (aFrameBuffer != NULL)
     {
       aFrameBuffer->BindBuffer (aGlCtx);
     }
 
-    const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
     redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
     if (isImmediate)
     {
-      RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
+      RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True, aFrameBuffer);
     }
 
     theCView.WasRedrawnGL = Standard_True;
@@ -896,7 +920,8 @@ void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
 void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
                                         const Aspect_CLayer2d& theCUnderLayer,
                                         const Aspect_CLayer2d& theCOverLayer,
-                                        const Standard_Boolean theToForce)
+                                        const Standard_Boolean theToForce,
+                                        OpenGl_FrameBuffer*    theTargetFBO)
 {
   if (!Activate())
   {
@@ -907,7 +932,8 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
 #if !defined(GL_ES_VERSION_2_0)
   glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer);
 #endif
-  if (myView->ImmediateStructures().IsEmpty())
+  if (myView->ImmediateStructures().IsEmpty()
+  && !myResultFBO->IsValid())
   {
     if (theToForce
      || !myIsImmediateDrawn)
@@ -929,7 +955,36 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
     return;
   }
 
-  if (isDoubleBuffer && myTransientDrawToFront)
+  if (myResultFBO->IsValid())
+  {
+    if (!myBackBufferRestored)
+    {
+      Redraw (theCView, theCUnderLayer, theCOverLayer);
+      return;
+    }
+
+    myResultFBO->BindReadBuffer (myGlContext);
+    if (theTargetFBO != NULL)
+    {
+      theTargetFBO->BindDrawBuffer (myGlContext);
+    }
+    else
+    {
+      myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
+    }
+    myGlContext->arbFBO->glBlitFramebuffer (0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(),
+                                            0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(),
+                                            GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+    if (theTargetFBO != NULL)
+    {
+      theTargetFBO->BindBuffer (myGlContext);
+    }
+    else
+    {
+      myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
+    }
+  }
+  else if (isDoubleBuffer && myTransientDrawToFront)
   {
     if (!myBackBufferRestored)
     {
@@ -946,8 +1001,11 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
   myIsImmediateDrawn = Standard_True;
 
   NamedStatus |= OPENGL_NS_IMMEDIATE;
-  ///glDisable (GL_LIGHTING);
-  glDisable (GL_DEPTH_TEST);
+
+  ///glDisable (GL_DEPTH_TEST);
+  glDepthFunc (GL_LEQUAL);
+  glDepthMask (GL_TRUE);
+  glEnable (GL_DEPTH_TEST);
 
   Handle(OpenGl_Workspace) aWS (this);
   for (OpenGl_SequenceOfStructure::Iterator anIter (myView->ImmediateStructures());
@@ -969,7 +1027,14 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
 
   NamedStatus &= ~OPENGL_NS_IMMEDIATE;
 
-  if (isDoubleBuffer && myTransientDrawToFront)
+  if (myResultFBO->IsValid())
+  {
+    if (theTargetFBO == NULL)
+    {
+      myGlContext->SwapBuffers();
+    }
+  }
+  else if (isDoubleBuffer && myTransientDrawToFront)
   {
     glFlush();
     MakeBackBufCurrent();
index 5d02e1561062371538e6f1591efcbcd883470aa6..43d2c3eab71d2fda65f6923175560746cf0f6d52 100644 (file)
@@ -160,7 +160,8 @@ public:
   void RedrawImmediate (const Graphic3d_CView& theCView,
                         const Aspect_CLayer2d& theCUnderLayer,
                         const Aspect_CLayer2d& theCOverLayer,
-                        const Standard_Boolean theToForce = Standard_False);
+                        const Standard_Boolean theToForce = Standard_False,
+                        OpenGl_FrameBuffer*    theTargetFBO = NULL);
 
   void Invalidate (const Graphic3d_CView& /*theCView*/)
   {
@@ -642,6 +643,8 @@ protected: //! @name fields related to ray-tracing
   //! Framebuffer (FBO) for pre-raytrace rendering by OpenGL.
   Handle(OpenGl_FrameBuffer) myOpenGlFBO;
 
+  Handle(OpenGl_FrameBuffer) myResultFBO;
+
   //! State of OpenGL view.
   Standard_Size myViewModificationStatus;
   //! State of OpenGL layer list.