/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #ifndef OSGUTIL_STATISTICS #define OSGUTIL_STATISTICS 1 #include #include #include #include #include #include #include #include #include #include #include namespace osgUtil { /** * Statistics base class. Used to extract primitive information from * the renderBin(s). Add a case of getStats(osgUtil::Statistics *stat) * for any new drawable (or drawable derived class) that you generate * (eg see Geometry.cpp). There are 20 types of drawable counted - actually only * 14 cases can occur in reality. these represent sets of GL_POINTS, GL_LINES * GL_LINESTRIPS, LOOPS, TRIANGLES, TRI-fans, tristrips, quads, quadstrips etc * The number of triangles rendered is inferred: * each triangle = 1 triangle (number of vertices/3) * each quad = 2 triangles (nverts/2) * each trifan or tristrip = (length-2) triangles and so on. */ class Statistics : public osg::PrimitiveFunctor { public: typedef std::pair PrimitivePair; typedef std::map PrimitiveValueMap; typedef std::map PrimitiveCountMap; Statistics(); enum StatsType { STAT_NONE, // default STAT_FRAMERATE, STAT_GRAPHS, STAT_PRIMS, STAT_PRIMSPERVIEW, STAT_PRIMSPERBIN, STAT_DC, STAT_RESTART // hint to restart the stats }; void reset(); void setType(StatsType t) {stattype=t;} virtual void setVertexArray(unsigned int count,const osg::Vec3*) { _vertexCount += count; } virtual void setVertexArray(unsigned int count,const osg::Vec2*) { _vertexCount += count; } virtual void setVertexArray(unsigned int count,const osg::Vec4*) { _vertexCount += count; } virtual void drawArrays(GLenum mode,GLint,GLsizei count); virtual void drawElements(GLenum mode,GLsizei count,const GLubyte*); virtual void drawElements(GLenum mode,GLsizei count,const GLushort*); virtual void drawElements(GLenum mode,GLsizei count,const GLuint*); virtual void begin(GLenum mode); inline void vertex() { PrimitivePair& prim = _primitiveCount[_currentPrimitiveFunctorMode]; ++prim.second; _number_of_vertexes++; } virtual void vertex(float,float,float) { vertex(); } virtual void vertex(const osg::Vec3&) { vertex(); } virtual void vertex(const osg::Vec2&) { vertex(); } virtual void vertex(const osg::Vec4&) { vertex(); } virtual void vertex(float,float) { vertex(); } virtual void vertex(float,float,float,float) { vertex(); } virtual void end(); void addDrawable() { numDrawables++;} void addMatrix() { nummat++;} void addLight(int np) { nlights+=np;} void addImpostor(int np) { nimpostor+= np; } inline int getBins() { return nbins;} void setDepth(int d) { depth=d; } void addBins(int np) { nbins+= np; } void setBinNo(int n) { _binNo=n;} void add(const Statistics& stats); public: PrimitiveCountMap::iterator GetPrimitivesBegin() { return _primitives_count.begin(); } PrimitiveCountMap::iterator GetPrimitivesEnd() { return _primitives_count.end(); } int numDrawables, nummat, nbins; int nlights; int depth; // depth into bins - eg 1.1,1.2,1.3 etc int _binNo; StatsType stattype; int nimpostor; // number of impostors rendered unsigned int _vertexCount; PrimitiveValueMap _primitiveCount; GLenum _currentPrimitiveFunctorMode; private: PrimitiveCountMap _primitives_count; unsigned int _total_primitives_count; unsigned int _number_of_vertexes; inline unsigned int _calculate_primitives_number_by_mode(GLenum, GLsizei); }; inline unsigned int Statistics::_calculate_primitives_number_by_mode(GLenum mode, GLsizei count) { switch (mode) { case GL_POINTS: case GL_LINE_LOOP: case GL_POLYGON: return count; case GL_LINES: return count / 2; case GL_LINE_STRIP: return count - 1; case GL_TRIANGLES: return count / 3; case GL_TRIANGLE_STRIP: case GL_TRIANGLE_FAN: return count - 2; case GL_QUADS: return count / 4; case GL_QUAD_STRIP: return count / 2 - 1; default: return 0; } } /** StatsVisitor for collecting statistics about scene graph.*/ class StatsVisitor : public osg::NodeVisitor { public: typedef std::set NodeSet; typedef std::set DrawableSet; typedef std::set StateSetSet; StatsVisitor(); void reset(); void apply(osg::Node& node); void apply(osg::Group& node); void apply(osg::Transform& node); void apply(osg::LOD& node); void apply(osg::Switch& node); void apply(osg::Geode& node); void apply(osg::Drawable& drawable); void totalUpStats(); void print(std::ostream& out); unsigned int _numInstancedGroup; unsigned int _numInstancedSwitch; unsigned int _numInstancedLOD; unsigned int _numInstancedTransform; unsigned int _numInstancedGeode; unsigned int _numInstancedDrawable; unsigned int _numInstancedGeometry; unsigned int _numInstancedStateSet; NodeSet _groupSet; NodeSet _transformSet; NodeSet _lodSet; NodeSet _switchSet; NodeSet _geodeSet; DrawableSet _drawableSet; DrawableSet _geometrySet; StateSetSet _statesetSet; osgUtil::Statistics _uniqueStats; osgUtil::Statistics _instancedStats; }; } #endif