0023227: New Draw Harness command to estimate current geometry complexity of OpenGL...
authorkgv <kgv@opencascade.com>
Wed, 27 Jun 2012 12:41:03 +0000 (16:41 +0400)
committerkgv <kgv@opencascade.com>
Tue, 3 Jul 2012 10:07:02 +0000 (14:07 +0400)
New command vfeedback proposed to capture GL info using GL_FEEDBACK functionality

src/ViewerTest/ViewerTest_OpenGlCommands.cxx

index be1d682..2d36855 100644 (file)
@@ -47,6 +47,7 @@
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <V3d_View.hxx>
 
 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
                                            const Handle(AIS_InteractiveObject)& theAISObj,
@@ -245,6 +246,158 @@ 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 : OpenGlCommands
 //purpose  :
@@ -257,4 +410,7 @@ 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);
 }