/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 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 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() { reset(); }; 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() { numDrawables=0, nummat=0; depth=0; stattype=STAT_NONE; nlights=0; nbins=0; nimpostor=0; _vertexCount=0; _primitiveCount.clear(); _currentPrimitiveFunctorMode=0; } 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) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); } virtual void drawElements(GLenum mode,GLsizei count,const GLubyte*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); } virtual void drawElements(GLenum mode,GLsizei count,const GLushort*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); } virtual void drawElements(GLenum mode,GLsizei count,const GLuint*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); } virtual void begin(GLenum mode) { _currentPrimitiveFunctorMode=mode; PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; _number_of_vertexes = 0; } 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() { _primitives_count[_currentPrimitiveFunctorMode] += _calculate_primitives_number_by_mode(_currentPrimitiveFunctorMode, _number_of_vertexes); } 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;} 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 - 3; default: return 0; } } } #endif