OpenSceneGraph/include/osgUtil/Statistics
2005-12-15 15:25:02 +00:00

192 lines
6.6 KiB
C++

/* -*-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 <osg/PrimitiveSet>
#include <osg/Drawable>
#include <map>
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<unsigned int,unsigned int> PrimitivePair;
typedef std::map<GLenum,PrimitivePair> PrimitiveValueMap;
typedef std::map<GLenum, unsigned int> 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 / 2 - 1;
default: return 0;
}
}
}
#endif