From 3c4153af69d915ad06c80f7ce7561a53a52c8b18 Mon Sep 17 00:00:00 2001 From: kgv Date: Wed, 27 Jun 2012 16:41:03 +0400 Subject: [PATCH] 0023227: New Draw Harness command to estimate current geometry complexity of OpenGL scene New command vfeedback proposed to capture GL info using GL_FEEDBACK functionality --- src/ViewerTest/ViewerTest_OpenGlCommands.cxx | 156 +++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx index be1d6824ce..2d36855400 100644 --- a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx +++ b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx @@ -47,6 +47,7 @@ #include #include #include +#include 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); } -- 2.39.5