0023525: Disappearing of highlight in screenshot
[occt.git] / src / ViewerTest / ViewerTest_OpenGlCommands.cxx
index be1d682..9a152b7 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <ViewerTest.hxx>
 
+#include <Aspect_GraphicDevice.hxx>
+#include <AIS_InteractiveContext.hxx>
 #include <AIS_InteractiveObject.hxx>
 #include <Draw.hxx>
 #include <Draw_Interpretor.hxx>
 #include <OpenGl_AspectLine.hxx>
 #include <OpenGl_AspectMarker.hxx>
 #include <OpenGl_AspectText.hxx>
-#include <OpenGl_Callback.hxx>
 #include <OpenGl_Context.hxx>
 #include <OpenGl_Element.hxx>
 #include <OpenGl_ExtFBO.hxx>
 #include <OpenGl_GlCore20.hxx>
-#include <OpenGl_ResourceCleaner.hxx>
-#include <OpenGl_ResourceTexture.hxx>
-#include <OpenGl_ResourceVBO.hxx>
+#include <OpenGl_GraphicDriver.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <Prs3d_Presentation.hxx>
 #include <Prs3d_Root.hxx>
 #include <Select3D_SensitiveCurve.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_Selection.hxx>
+#include <V3d_Viewer.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <V3d_View.hxx>
+#include <Visual3d_View.hxx>
 
 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
                                            const Handle(AIS_InteractiveObject)& theAISObj,
@@ -99,6 +101,11 @@ public:
         myIObj->Render(theWorkspace);
     }
 
+    virtual void Release (const Handle(OpenGl_Context)& theGlCtx)
+    {
+      //
+    }
+
   public:
     DEFINE_STANDARD_ALLOC
   };
@@ -165,7 +172,6 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
   // To test linking against OpenGl_Workspace and all aspect classes
   const OpenGl_AspectLine* aLA = theWorkspace->AspectLine(0);
   const OpenGl_AspectFace* aFA = theWorkspace->AspectFace(0);
-  aFA->Context();
   const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker(0);
   aMA->Type();
   const OpenGl_AspectText* aTA = theWorkspace->AspectText(0);
@@ -174,21 +180,7 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
     *(theWorkspace->HighlightColor) : aLA->Color();
 
   // To test OpenGl_Window
-  Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
-  GLCONTEXT aGlContext = theWorkspace->GetGContext();
-
-  // To link against OpenGl_Context and extensions
-  GLuint aVboId = -1, aTexId = -1;
-  if (aCtx->arbVBO)
-    aCtx->arbVBO->glGenBuffersARB(1, &aVboId);
-  glGenTextures(1, &aTexId);
-
-  // To link against OpenGl_ResourceCleaner, OpenGl_ResourceVBO, OpenGl_ResourceTexture
-  OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
-  if (aVboId != (GLuint)-1)
-    aResCleaner->AddResource(aGlContext, new OpenGl_ResourceVBO(aVboId));
-  if (aTexId != (GLuint)-1)
-    aResCleaner->AddResource(aGlContext, new OpenGl_ResourceTexture(aTexId));
+  //Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
 
   // Finally draw something to make sure UserDraw really works
   glPushAttrib(GL_ENABLE_BIT);
@@ -203,8 +195,6 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
   glPopAttrib();
 }
 
-
-
 OpenGl_Element* VUserDrawCallback(const CALL_DEF_USERDRAW * theUserDraw)
 {
   Handle(VUserDrawObj) anIObj = (VUserDrawObj*)theUserDraw->Data;
@@ -227,6 +217,13 @@ static Standard_Integer VUserDraw (Draw_Interpretor& di,
     return 1;
   }
 
+  Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Device()->GraphicDriver());
+  if (aDriver.IsNull())
+  {
+    std::cerr << "Graphic driver not available.\n";
+    return 1;
+  }
+
   if (argc > 2)
   {
     di << argv[0] << "Wrong number of arguments, only the object name expected\n";
@@ -237,7 +234,7 @@ static Standard_Integer VUserDraw (Draw_Interpretor& di,
   VDisplayAISObject(aName, Handle(AIS_InteractiveObject)());
 
   // register the custom element factory function
-  ::UserDrawCallback() = VUserDrawCallback;
+  aDriver->UserDrawCallback() = VUserDrawCallback;
 
   Handle(VUserDrawObj) anIObj = new VUserDrawObj();
   VDisplayAISObject(aName, anIObj);
@@ -245,6 +242,196 @@ static Standard_Integer VUserDraw (Draw_Interpretor& di,
   return 0;
 }
 
+//==============================================================================
+//function : VFeedback
+//purpose  :
+//==============================================================================
+
+static int VFeedback (Draw_Interpretor& theDI,
+                      Standard_Integer  theArgNb,
+                      const char**      theArgVec)
+{
+  // get the active view
+  Handle(V3d_View) aView = ViewerTest::CurrentView();
+  if (aView.IsNull())
+  {
+    std::cerr << "No active view. Please call vinit.\n";
+    return 1;
+  }
+
+  unsigned int aBufferSize = 1024 * 1024;
+  for (;;)
+  {
+    size_t aBytes = (size_t )aBufferSize * sizeof(GLfloat);
+    if (aBytes / sizeof(GLfloat) != (size_t )aBufferSize)
+    {
+      // finito la commedia
+      std::cerr << "Can not allocate buffer - requested size ("
+                << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
+                << " MiB) is out of address space\n";
+      return 1;
+    }
+
+    GLfloat* aBuffer = (GLfloat* )Standard::Allocate (aBytes);
+    if (aBuffer == NULL)
+    {
+      // finito la commedia
+      std::cerr << "Can not allocate buffer with size ("
+                << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
+                << " MiB)\n";
+      return 1;
+    }
+
+    glFeedbackBuffer ((GLsizei )aBufferSize, GL_2D, aBuffer);
+    glRenderMode (GL_FEEDBACK);
+
+    aView->Redraw();
+
+    GLint aResult = glRenderMode (GL_RENDER);
+    if (aResult < 0)
+    {
+      aBufferSize *= 2;
+
+      void* aPtr = aBuffer;
+      Standard::Free (aPtr);
+      aBuffer = NULL;
+      continue;
+    }
+
+    std::cout << "FeedBack result= " << aResult << "\n";
+    GLint aPntNb     = 0;
+    GLint aTriNb     = 0;
+    GLint aQuadsNb   = 0;
+    GLint aPolyNb    = 0;
+    GLint aNodesNb   = 0;
+    GLint aLinesNb   = 0;
+    GLint aBitmapsNb = 0;
+    GLint aPassThrNb = 0;
+    GLint aUnknownNb = 0;
+    const GLint NODE_VALUES = 2; // GL_2D
+    for (GLint anIter = 0; anIter < aResult;)
+    {
+        const GLfloat aPos = aBuffer[anIter];
+        switch ((GLint )aPos)
+        {
+          case GL_POINT_TOKEN:
+          {
+            ++aPntNb;
+            ++aNodesNb;
+            anIter += 1 + NODE_VALUES;
+            break;
+          }
+          case GL_LINE_RESET_TOKEN:
+          case GL_LINE_TOKEN:
+          {
+            ++aLinesNb;
+            aNodesNb += 2;
+            anIter += 1 + 2 * NODE_VALUES;
+            break;
+          }
+          case GL_POLYGON_TOKEN:
+          {
+            const GLint aCount = (GLint )aBuffer[++anIter];
+            aNodesNb += aCount;
+            anIter += aCount * NODE_VALUES + 1;
+            if (aCount == 3)
+            {
+              ++aTriNb;
+            }
+            else if (aCount == 4)
+            {
+              ++aQuadsNb;
+            }
+            else
+            {
+              ++aPolyNb;
+            }
+            break;
+          }
+          case GL_BITMAP_TOKEN:
+          case GL_DRAW_PIXEL_TOKEN:
+          case GL_COPY_PIXEL_TOKEN:
+          {
+            ++aBitmapsNb;
+            anIter += 1 + NODE_VALUES;
+            break;
+          }
+          case GL_PASS_THROUGH_TOKEN:
+          {
+            ++aPassThrNb;
+            anIter += 2; // header + value
+            break;
+          }
+          default:
+          {
+            ++anIter;
+            ++aUnknownNb;
+            break;
+          }
+       }
+    }
+    void* aPtr = aBuffer;
+    Standard::Free (aPtr);
+
+    // return statistics
+    theDI << "Total nodes:   " << aNodesNb   << "\n"
+          << "Points:        " << aPntNb     << "\n"
+          << "Line segments: " << aLinesNb   << "\n"
+          << "Triangles:     " << aTriNb     << "\n"
+          << "Quads:         " << aQuadsNb   << "\n"
+          << "Polygons:      " << aPolyNb    << "\n"
+          << "Bitmap tokens: " << aBitmapsNb << "\n"
+          << "Pass through:  " << aPassThrNb << "\n"
+          << "UNKNOWN:       " << aUnknownNb << "\n";
+
+    double aLen2D      = double(aNodesNb * 2 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
+    double aLen3D      = double(aNodesNb * 3 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
+    double aLen3D_rgba = double(aNodesNb * 7 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
+    theDI << "Buffer size GL_2D:       " << aLen2D      * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
+          << "Buffer size GL_3D:       " << aLen3D      * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
+          << "Buffer size GL_3D_COLOR: " << aLen3D_rgba * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n";
+    return 0;
+  }
+}
+
+//==============================================================================
+//function : VImmediateFront
+//purpose  :
+//==============================================================================
+
+static int VImmediateFront (Draw_Interpretor& theDI,
+                            Standard_Integer  theArgNb,
+                            const char**      theArgVec)
+{
+  // get the context
+  Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
+  if (aContextAIS.IsNull())
+  {
+    std::cerr << "No active view. Please call vinit.\n";
+    return 1;
+  }
+
+  Handle(Graphic3d_GraphicDriver) aDriver =
+         Handle(Graphic3d_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Device()->GraphicDriver());
+  if (aDriver.IsNull())
+  {
+    std::cerr << "Graphic driver not available.\n";
+    return 1;
+  }
+
+  if (theArgNb < 2)
+  {
+    //theDI << "VBO: " << aDriver->ToUseVBO() << "\n";
+    //return 0;
+    std::cerr << "Wrong number of arguments.\n";
+    return 1;
+  }
+
+  Graphic3d_CView* aCView = (Graphic3d_CView* )(ViewerTest::CurrentView()->View()->CView());
+  aDriver->SetImmediateModeDrawToFront (*aCView, atoi(theArgVec[1]) != 0);
+  return 0;
+}
+
 //=======================================================================
 //function : OpenGlCommands
 //purpose  :
@@ -257,4 +444,11 @@ void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
   theCommands.Add("vuserdraw",
     "vuserdraw : name - simulates drawing with help of UserDraw",
     __FILE__, VUserDraw, aGroup);
+  theCommands.Add("vfeedback",
+    "vfeedback       : perform test GL feedback rendering",
+    __FILE__, VFeedback, aGroup);
+  theCommands.Add("vimmediatefront",
+    "vimmediatefront : render immediate mode to front buffer or to back buffer",
+    __FILE__, VImmediateFront, aGroup);
+
 }