1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12*/ 13 14#ifndef OSGUTIL_STATISTICS 15#define OSGUTIL_STATISTICS 1 16 17#include <osgUtil/Export> 18 19#include <osg/PrimitiveSet> 20#include <osg/Drawable> 21#include <osg/NodeVisitor> 22#include <osg/Geode> 23#include <osg/LOD> 24#include <osg/Switch> 25#include <osg/Geometry> 26#include <osg/Transform> 27 28#include <map> 29#include <set> 30#include <ostream> 31 32namespace osgUtil { 33 34/** 35 * Statistics base class. Used to extract primitive information from 36 * the renderBin(s). Add a case of getStats(osgUtil::Statistics *stat) 37 * for any new drawable (or drawable derived class) that you generate 38 * (eg see Geometry.cpp). There are 20 types of drawable counted - actually only 39 * 14 cases can occur in reality. these represent sets of GL_POINTS, GL_LINES 40 * GL_LINESTRIPS, LOOPS, TRIANGLES, TRI-fans, tristrips, quads, quadstrips etc 41 * The number of triangles rendered is inferred: 42 * each triangle = 1 triangle (number of vertices/3) 43 * each quad = 2 triangles (nverts/2) 44 * each trifan or tristrip = (length-2) triangles and so on. 45*/ 46 47class OSGUTIL_EXPORT Statistics : public osg::PrimitiveFunctor 48{ 49 public: 50 51 typedef std::pair<unsigned int,unsigned int> PrimitivePair; 52 typedef std::map<GLenum,PrimitivePair> PrimitiveValueMap; 53 typedef std::map<GLenum, unsigned int> PrimitiveCountMap; 54 55 56 Statistics(); 57 58 enum StatsType 59 { 60 STAT_NONE, // default 61 STAT_FRAMERATE, 62 STAT_GRAPHS, 63 STAT_PRIMS, 64 STAT_PRIMSPERVIEW, 65 STAT_PRIMSPERBIN, 66 STAT_DC, 67 STAT_RESTART // hint to restart the stats 68 }; 69 70 void reset(); 71 72 void setType(StatsType t) { stattype=t; } 73 74 virtual void setVertexArray(unsigned int count,const osg::Vec3*) { _vertexCount += count; } 75 virtual void setVertexArray(unsigned int count,const osg::Vec2*) { _vertexCount += count; } 76 virtual void setVertexArray(unsigned int count,const osg::Vec4*) { _vertexCount += count; } 77 virtual void setVertexArray(unsigned int count,const osg::Vec3d*) { _vertexCount += count; } 78 virtual void setVertexArray(unsigned int count,const osg::Vec2d*) { _vertexCount += count; } 79 virtual void setVertexArray(unsigned int count,const osg::Vec4d*) { _vertexCount += count; } 80 81 virtual void drawArrays(GLenum mode,GLint,GLsizei count); 82 virtual void drawElements(GLenum mode,GLsizei count,const GLubyte*); 83 virtual void drawElements(GLenum mode,GLsizei count,const GLushort*); 84 virtual void drawElements(GLenum mode,GLsizei count,const GLuint*); 85 86 virtual void begin(GLenum mode); 87 88 inline void vertex() 89 { 90 PrimitivePair& prim = _primitiveCount[_currentPrimitiveFunctorMode]; 91 ++prim.second; 92 _number_of_vertexes++; 93 } 94 95 virtual void vertex(float,float,float) { vertex(); } 96 virtual void vertex(const osg::Vec3&) { vertex(); } 97 virtual void vertex(const osg::Vec2&) { vertex(); } 98 virtual void vertex(const osg::Vec4&) { vertex(); } 99 virtual void vertex(float,float) { vertex(); } 100 virtual void vertex(float,float,float,float) { vertex(); } 101 102 virtual void end(); 103 104 void addDrawable() { numDrawables++;} 105 void addFastDrawable() { numFastDrawables++;} 106 void addMatrix() { nummat++;} 107 void addLight(int np) { nlights+=np;} 108 void addImpostor(int np) { nimpostor+= np; } 109 inline int getBins() { return nbins;} 110 void setDepth(int d) { depth=d; } 111 void addBins(int np) { nbins+= np; } 112 113 void setBinNo(int n) { _binNo=n;} 114 void addStateGraphs(int n) { numStateGraphs += n; } 115 void addOrderedLeaves(int n) { numOrderedLeaves += n; } 116 117 void add(const Statistics& stats); 118 119 public: 120 121 PrimitiveCountMap& getPrimitiveCountMap() { return _primitives_count; } 122 const PrimitiveCountMap& getPrimitiveCountMap() const { return _primitives_count; } 123 124 PrimitiveValueMap& getPrimitiveValueMap() { return _primitiveCount; } 125 const PrimitiveValueMap& getPrimitiveValueMap() const { return _primitiveCount; } 126 127 128 /// deprecated 129 PrimitiveCountMap::iterator GetPrimitivesBegin() { return _primitives_count.begin(); } 130 /// deprecated 131 PrimitiveCountMap::iterator GetPrimitivesEnd() { return _primitives_count.end(); } 132 133 int numDrawables, nummat, nbins, numStateGraphs; 134 int numFastDrawables; 135 int nlights; 136 int depth; // depth into bins - eg 1.1,1.2,1.3 etc 137 int _binNo; 138 StatsType stattype; 139 int nimpostor; // number of impostors rendered 140 int numOrderedLeaves; // leaves from RenderBin fine grain ordering 141 142 unsigned int _vertexCount; 143 PrimitiveValueMap _primitiveCount; 144 GLenum _currentPrimitiveFunctorMode; 145 146 private: 147 PrimitiveCountMap _primitives_count; 148 149 unsigned int _total_primitives_count; 150 unsigned int _number_of_vertexes; 151 152 inline unsigned int _calculate_primitives_number_by_mode(GLenum, GLsizei); 153}; 154 155inline unsigned int Statistics::_calculate_primitives_number_by_mode(GLenum mode, GLsizei count) 156{ 157 switch (mode) 158 { 159 case GL_POINTS: 160 case GL_LINE_LOOP: 161 case GL_POLYGON: return count; 162 case GL_LINES: return count / 2; 163 case GL_LINE_STRIP: return count - 1; 164 case GL_TRIANGLES: return count / 3; 165 case GL_TRIANGLE_STRIP: 166 case GL_TRIANGLE_FAN: return count - 2; 167 case GL_QUADS: return count / 4; 168 case GL_QUAD_STRIP: return count / 2 - 1; 169 default: return 0; 170 } 171} 172 173/** StatsVisitor for collecting statistics about scene graph.*/ 174class OSGUTIL_EXPORT StatsVisitor : public osg::NodeVisitor 175{ 176public: 177 178 typedef std::set<osg::Node*> NodeSet; 179 typedef std::set<osg::Drawable*> DrawableSet; 180 typedef std::set<osg::StateSet*> StateSetSet; 181 182 StatsVisitor(); 183 184 META_NodeVisitor(osgUtil, StatsVisitor) 185 186 virtual void reset(); 187 188 virtual void apply(osg::Node& node); 189 virtual void apply(osg::Group& node); 190 virtual void apply(osg::Transform& node); 191 virtual void apply(osg::LOD& node); 192 virtual void apply(osg::Switch& node); 193 virtual void apply(osg::Geode& node); 194 virtual void apply(osg::Drawable& drawable); 195 virtual void apply(osg::StateSet& ss); 196 197 virtual void totalUpStats(); 198 199 virtual void print(std::ostream& out); 200 201 unsigned int _numInstancedGroup; 202 unsigned int _numInstancedSwitch; 203 unsigned int _numInstancedLOD; 204 unsigned int _numInstancedTransform; 205 unsigned int _numInstancedGeode; 206 unsigned int _numInstancedDrawable; 207 unsigned int _numInstancedGeometry; 208 unsigned int _numInstancedFastGeometry; 209 unsigned int _numInstancedStateSet; 210 211 NodeSet _groupSet; 212 NodeSet _transformSet; 213 NodeSet _lodSet; 214 NodeSet _switchSet; 215 NodeSet _geodeSet; 216 DrawableSet _drawableSet; 217 DrawableSet _geometrySet; 218 DrawableSet _fastGeometrySet; 219 StateSetSet _statesetSet; 220 221 osgUtil::Statistics _uniqueStats; 222 osgUtil::Statistics _instancedStats; 223}; 224 225} 226 227#endif 228