From 25c8b05914f9c81b3dd9292bc8c04e16d52a3091 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 22 Oct 2001 22:02:47 +0000 Subject: [PATCH] Integrated Geoff Michel's updates to Stats code, whilest move all text rendering back in the viewer from the Statistics header. Added a osg::State::captureCurrentState(StateSet&) method and a copy constructor to osg::StateSet. --- include/osg/Drawable | 21 +- include/osg/GeoSet | 4 + include/osg/ImpostorSprite | 1 + include/osg/State | 3 + include/osg/StateSet | 3 +- include/osg/Statistics | 137 +++-------- include/osgGLUT/Viewer | 2 +- include/osgUtil/RenderBin | 2 +- include/osgUtil/RenderStage | 2 +- src/osg/GeoSet.cpp | 106 +++++++++ src/osg/ImpostorSprite.cpp | 15 ++ src/osg/State.cpp | 30 +++ src/osg/StateSet.cpp | 11 + src/osgGLUT/Viewer.cpp | 436 +++++++++++++++++++----------------- src/osgUtil/RenderBin.cpp | 19 +- src/osgUtil/RenderStage.cpp | 6 +- 16 files changed, 453 insertions(+), 345 deletions(-) diff --git a/include/osg/Drawable b/include/osg/Drawable index 1173267f1..60a78c126 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -29,6 +29,19 @@ class Vec4; for a Drawable are maintained in StateSet which the Drawable maintains a referenced counted pointer to. Both Drawable's and StateSet's can be shared for optimal memory usage and graphics performance. + + Subclasses should provide an instance of getStats(Statistics *st) if the subclass + contains drawing primitives. This member function should add the primitives it + draws into the Statistics class; for example add the number of quads, triangles etc + created. For an example see GeoSet.cpp: + getStats(osgUtil::Statistics *stat). + Failure to implement this routine will only result in the stats displayed for + your drawable being wrong. + Another example is in the InfinitePlane class- this draws a normal geoset AND + its own special set of quads, so this case of getPrims calls: + the normal geoset stats gs->getStats(..), and then adds the number of quads + rendered directly (it is rendered in a display list, but we do know how many + quads are in the display list). */ class SG_EXPORT Drawable : public Object { @@ -136,14 +149,6 @@ class SG_EXPORT Drawable : public Object COLORS = 0x4, TEXTURE_COORDS = 0x8, TEXTURE_COORDS_0 = TEXTURE_COORDS, - /* - * Robert, - * These would have kept you up late if you were - * trying to use these as bitmasks - TEXTURE_COORDS_1 = 0x16, - TEXTURE_COORDS_2 = 0x32, - TEXTURE_COORDS_3 = 0x64 - */ TEXTURE_COORDS_1 = 0x10, TEXTURE_COORDS_2 = 0x20, TEXTURE_COORDS_3 = 0x40 diff --git a/include/osg/GeoSet b/include/osg/GeoSet index a354abc14..43b3a457b 100644 --- a/include/osg/GeoSet +++ b/include/osg/GeoSet @@ -290,6 +290,10 @@ class SG_EXPORT GeoSet : public Drawable const bool check() const; + /** Statistics collection for each drawable- 26.09.01 + */ + bool getStats(Statistics &); + /** return the attributes supported by applyAttrbuteUpdate() as an AttributeBitMask.*/ virtual AttributeBitMask suppportsAttributeOperation() const; diff --git a/include/osg/ImpostorSprite b/include/osg/ImpostorSprite index 14dc093be..df205398a 100644 --- a/include/osg/ImpostorSprite +++ b/include/osg/ImpostorSprite @@ -111,6 +111,7 @@ class SG_EXPORT ImpostorSprite : public Drawable /** draw ImpostorSprite directly. */ virtual void drawImmediateMode(State& state); + bool getStats(Statistics &stat); protected: diff --git a/include/osg/State b/include/osg/State index 0753a961a..50aac72ef 100644 --- a/include/osg/State +++ b/include/osg/State @@ -46,6 +46,9 @@ class SG_EXPORT State : public Referenced /** pop drawstate off state stack.*/ void popStateSet(); + /** copy the modes and attributes which captures the current state.*/ + void captureCurrentState(StateSet& stateset) const; + /** reset the state object to an empty stack.*/ void reset(); diff --git a/include/osg/StateSet b/include/osg/StateSet index efb17f90b..3ab52fcd9 100644 --- a/include/osg/StateSet +++ b/include/osg/StateSet @@ -28,6 +28,8 @@ class SG_EXPORT StateSet : public Object StateSet(); + StateSet(const StateSet&); + virtual Object* clone() const { return new StateSet(); } virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* className() const { return "StateSet"; } @@ -154,7 +156,6 @@ class SG_EXPORT StateSet : public Object virtual ~StateSet(); - StateSet(const StateSet&):Object() {} StateSet& operator = (const StateSet&) { return *this; } diff --git a/include/osg/Statistics b/include/osg/Statistics index 858cb7596..0c560707b 100644 --- a/include/osg/Statistics +++ b/include/osg/Statistics @@ -2,135 +2,57 @@ //Distributed under the terms of the GNU Library General Public License (LGPL) //as published by the Free Software Foundation. -#ifndef OSG_STATISTICS -#define OSG_STATISTICS 1 +#ifndef OSGUTIL_STATISTICS +#define OSGUTIL_STATISTICS 1 -#include +#include namespace osg { /** * Statistics base class. Used to extract primitive information from - * the renderBin(s). + * the renderBin(s). Add a case of getStats(osgUtil::Statistics *stat) + * for any new drawable (or drawable derived class) that you generate + * (eg see GeoSet.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 /*SG_EXPORT*/ Statistics : public Object + +class SG_EXPORT Statistics : public osg::Object { public: Statistics() { numOpaque=0, nummat=0; - nprims=0, nlights=0; nbins=0; + nprims=0, nlights=0; nbins=0; nimpostor=0; reset(); }; - + ~Statistics() {}; // no dynamic allocations, so no need to free - - void reset() { - for (int i=0; i<20; i++) primverts[i]=numprimtypes[i]=primlens[i]=primtypes[i]=0; - } virtual osg::Object* clone() const { return new Statistics(); } virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=0L; } virtual const char* className() const { return "Statistics"; } - void addstat(osg::GeoSet *gs) { // analyse the drawable GeoSet - const int np=gs->getNumPrims(); // number of primitives in this geoset - nprims += np; - const int type=gs->getPrimType(); - switch (type) { - case osg::GeoSet::POINTS: - case osg::GeoSet::LINES: - case osg::GeoSet::LINE_STRIP: - case osg::GeoSet::FLAT_LINE_STRIP: - case osg::GeoSet::LINE_LOOP: - case osg::GeoSet::TRIANGLE_STRIP: - case osg::GeoSet::FLAT_TRIANGLE_STRIP: - case osg::GeoSet::TRIANGLE_FAN: - case osg::GeoSet::FLAT_TRIANGLE_FAN: - case osg::GeoSet::QUAD_STRIP: - case osg::GeoSet::POLYGON: - primtypes[type]++; - primtypes[0]++; - break; - case osg::GeoSet::TRIANGLES: // should not have any lengths for tris & quads - primtypes[type]++; - primtypes[0]++; - primlens[0]+=np; - primlens[type]+=np; - numprimtypes[type]+=np; - primverts[type]+=3*np; - primverts[0]+=3*np; - break; - case osg::GeoSet::QUADS: - primtypes[type]++; - primtypes[0]++; - primlens[0]+=np*2; - primlens[type]+=np*2; // quad is equiv to 2 triangles - numprimtypes[type]+=np; - primverts[type]+=4*np; - primverts[0]+=4*np; - break; - case osg::GeoSet::NO_TYPE: - default: - break; - } - // now count the lengths, ie efficiency of triangulation - const int *lens=gs->getPrimLengths(); // primitive lengths - for (int i=0; i #include +#include //#include @@ -682,3 +683,108 @@ Drawable::AttributeBitMask GeoSet::applyAttributeOperation(AttributeFunctor& auf return ramb; } +bool GeoSet::getStats(Statistics &stat) +{ // analyse the drawable GeoSet + const int np=getNumPrims(); // number of primitives in this geoset + stat.nprims += np; + const int type=getPrimType(); + switch (type) { + case osg::GeoSet::POINTS: + case osg::GeoSet::LINES: + case osg::GeoSet::LINE_STRIP: + case osg::GeoSet::FLAT_LINE_STRIP: + case osg::GeoSet::LINE_LOOP: + case osg::GeoSet::TRIANGLE_STRIP: + case osg::GeoSet::FLAT_TRIANGLE_STRIP: + case osg::GeoSet::TRIANGLE_FAN: + case osg::GeoSet::FLAT_TRIANGLE_FAN: + case osg::GeoSet::QUAD_STRIP: + case osg::GeoSet::POLYGON: + stat.primtypes[type]++; + stat.primtypes[0]++; + break; + case osg::GeoSet::TRIANGLES: // should not have any lengths for tris & quads + stat.primtypes[type]++; + stat.primtypes[0]++; + stat.primlens[0]+=np; + stat.primlens[type]+=np; + stat.numprimtypes[type]+=np; + stat.primverts[type]+=3*np; + stat.primverts[0]+=3*np; + break; + case osg::GeoSet::QUADS: + stat.primtypes[type]++; + stat.primtypes[0]++; + stat.primlens[0]+=np*2; + stat.primlens[type]+=np*2; // quad is equiv to 2 triangles + stat.numprimtypes[type]+=np; + stat.primverts[type]+=4*np; + stat.primverts[0]+=4*np; + break; + case osg::GeoSet::NO_TYPE: + default: + break; + } + // now count the lengths, ie efficiency of triangulation + const int *lens=getPrimLengths(); // primitive lengths + if (lens) { + for (int i=0; i #include +#include #include #include #include #include #include +#include using namespace osg; @@ -283,3 +285,16 @@ ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,i return is; } + + +bool ImpostorSprite::getStats(Statistics &stat) +{ // analyse the drawable Impostor Sprite + stat.primtypes[0]++; + stat.primtypes[GeoSet::QUADS]++; + stat.primlens[GeoSet::QUADS]+=2; // 1 quads quad is equiv to 2 triangles + stat.numprimtypes[GeoSet::QUADS]++; + stat.primverts[GeoSet::QUADS]+=4; + stat.primverts[0]+=38; + stat.nimpostor++; + return true; +} diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 8535e2cb8..1377dbac7 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -161,6 +161,36 @@ void State::popStateSet() _drawStateStack.pop_back(); } +void State::captureCurrentState(StateSet& stateset) const +{ + // empty the stateset first. + stateset.setAllToInherit(); + + for(ModeMap::const_iterator mitr=_modeMap.begin(); + mitr!=_modeMap.end(); + ++mitr) + { + // note GLMode = mitr->first + const ModeStack& ms = mitr->second; + if (!ms.valueVec.empty()) + { + stateset.setMode(mitr->first,ms.valueVec.back()); + } + } + + for(AttributeMap::const_iterator aitr=_attributeMap.begin(); + aitr!=_attributeMap.end(); + ++aitr) + { + const AttributeStack& as = aitr->second; + if (!as.attributeVec.empty()) + { + stateset.setAttribute(const_cast(as.attributeVec.back().first)); + } + } +} + + void State::apply(const StateSet* dstate) { // equivilant to: diff --git a/src/osg/StateSet.cpp b/src/osg/StateSet.cpp index c13d90b6f..231f21c2a 100644 --- a/src/osg/StateSet.cpp +++ b/src/osg/StateSet.cpp @@ -21,6 +21,17 @@ StateSet::StateSet() setRendingBinToInherit(); } +StateSet::StateSet(const StateSet& rhs):Object() +{ + _modeList = rhs._modeList; + _attributeList = rhs._attributeList; + + _renderingHint = rhs._renderingHint; + + _binMode = rhs._binMode; + _binNum = rhs._binNum; + _binName = rhs._binName; +} StateSet::~StateSet() { diff --git a/src/osgGLUT/Viewer.cpp b/src/osgGLUT/Viewer.cpp index a94a3a373..0974cb1b7 100644 --- a/src/osgGLUT/Viewer.cpp +++ b/src/osgGLUT/Viewer.cpp @@ -62,10 +62,17 @@ osg::Timer_t g_initTime; //static GLenum polymodes [] = { GL_FILL, GL_LINE, GL_POINT }; static osg::PolygonMode::Mode polymodes [] = { osg::PolygonMode::FILL, osg::PolygonMode::LINE, osg::PolygonMode::POINT }; +// forward declare functions to be used in stats. +GLuint makeRasterFont(void); +void displaytext(int x, int y, char *s); +void writePrims( const int ypos, osg::Statistics& stats); + using namespace osg; using namespace osgUtil; using namespace osgGLUT; + + Viewer* Viewer::s_theViewer = 0; Viewer::Viewer() @@ -435,148 +442,16 @@ void Viewer::keyboardCB(unsigned char key, int x, int y) } -GLuint makeRasterFont(void) -{ // GWM creates a set of display lists which may be used to render a character string on the screen -// data from GWM's reading of the Windows ASCII_FIXED_FONT. - GLubyte rasters[][12] = { // ascii symbols 32-127, small font -{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00}, -{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x00}, -{0x00, 0x00, 0x28, 0x28, 0x7e, 0x14, 0x14, 0x14, 0x3f, 0x0a, 0x0a, 0x00}, -{0x00, 0x00, 0x08, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c, 0x08, 0x00}, -{0x00, 0x00, 0x02, 0x45, 0x22, 0x10, 0x08, 0x04, 0x22, 0x51, 0x20, 0x00}, -{0x00, 0x00, 0x3b, 0x44, 0x4a, 0x49, 0x30, 0x10, 0x20, 0x20, 0x18, 0x00}, -{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00}, -{0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00}, -{0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x00}, -{0x00, 0x00, 0x00, 0x00, 0x36, 0x1c, 0x7f, 0x1c, 0x36, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00}, -{0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00}, -{0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00}, -{0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x08, 0x00}, -{0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x22, 0x1c, 0x00}, -{0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x22, 0x1c, 0x00}, -{0x00, 0x00, 0x0e, 0x04, 0x3e, 0x24, 0x14, 0x14, 0x0c, 0x0c, 0x04, 0x00}, -{0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x3c, 0x20, 0x20, 0x20, 0x3e, 0x00}, -{0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x10, 0x0c, 0x00}, -{0x00, 0x00, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x22, 0x3e, 0x00}, -{0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00}, -{0x00, 0x00, 0x18, 0x04, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1c, 0x00}, -{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x04, 0x02, 0x02, 0x22, 0x1c, 0x00}, -{0x00, 0x00, 0x1c, 0x20, 0x4e, 0x55, 0x55, 0x55, 0x4d, 0x21, 0x1e, 0x00}, -{0x00, 0x00, 0x77, 0x22, 0x3e, 0x22, 0x14, 0x14, 0x08, 0x08, 0x18, 0x00}, -{0x00, 0x00, 0x7e, 0x21, 0x21, 0x21, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00}, -{0x00, 0x00, 0x1e, 0x21, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, 0x1e, 0x00}, -{0x00, 0x00, 0x7c, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x7c, 0x00}, -{0x00, 0x00, 0x7f, 0x21, 0x20, 0x24, 0x3c, 0x24, 0x20, 0x21, 0x7f, 0x00}, -{0x00, 0x00, 0x78, 0x20, 0x20, 0x24, 0x3c, 0x24, 0x20, 0x21, 0x7f, 0x00}, -{0x00, 0x00, 0x1e, 0x21, 0x41, 0x47, 0x40, 0x40, 0x40, 0x21, 0x1e, 0x00}, -{0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x77, 0x00}, -{0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00}, -{0x00, 0x00, 0x38, 0x44, 0x44, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1e, 0x00}, -{0x00, 0x00, 0x73, 0x22, 0x24, 0x38, 0x28, 0x24, 0x24, 0x22, 0x73, 0x00}, -{0x00, 0x00, 0x7f, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00}, -{0x00, 0x00, 0x77, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x36, 0x22, 0x63, 0x00}, -{0x00, 0x00, 0x72, 0x22, 0x26, 0x26, 0x2a, 0x32, 0x32, 0x22, 0x67, 0x00}, -{0x00, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00}, -{0x00, 0x00, 0x78, 0x20, 0x20, 0x20, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00}, -{0x00, 0x1b, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00}, -{0x00, 0x00, 0x73, 0x22, 0x24, 0x24, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00}, -{0x00, 0x00, 0x3e, 0x41, 0x01, 0x01, 0x3e, 0x40, 0x40, 0x41, 0x3e, 0x00}, -{0x00, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x49, 0x7f, 0x00}, -{0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x77, 0x00}, -{0x00, 0x00, 0x08, 0x08, 0x14, 0x14, 0x14, 0x22, 0x22, 0x22, 0x77, 0x00}, -{0x00, 0x00, 0x14, 0x14, 0x2a, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x77, 0x00}, -{0x00, 0x00, 0x77, 0x22, 0x14, 0x14, 0x08, 0x14, 0x14, 0x22, 0x77, 0x00}, -{0x00, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00}, -{0x00, 0x00, 0x7f, 0x21, 0x10, 0x10, 0x08, 0x04, 0x04, 0x42, 0x7f, 0x00}, -{0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00}, -{0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00}, -{0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00}, -{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08}, -{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00}, -{0x00, 0x00, 0x3d, 0x42, 0x42, 0x3e, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x7e, 0x21, 0x21, 0x21, 0x21, 0x3e, 0x20, 0x20, 0x60, 0x00}, -{0x00, 0x00, 0x3e, 0x41, 0x40, 0x40, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x3f, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x06, 0x00}, -{0x00, 0x00, 0x3e, 0x41, 0x40, 0x7f, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x3c, 0x10, 0x10, 0x10, 0x10, 0x3c, 0x10, 0x10, 0x0c, 0x00}, -{0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3f, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x32, 0x2c, 0x20, 0x20, 0x60, 0x00}, -{0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x08, 0x00}, -{0x38, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x3c, 0x00, 0x00, 0x04, 0x00}, -{0x00, 0x00, 0x63, 0x24, 0x38, 0x28, 0x24, 0x26, 0x20, 0x20, 0x60, 0x00}, -{0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00}, -{0x00, 0x00, 0x6b, 0x2a, 0x2a, 0x2a, 0x2a, 0x74, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x32, 0x6c, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x3e, 0x41, 0x41, 0x41, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00}, -{0x70, 0x20, 0x3e, 0x21, 0x21, 0x21, 0x21, 0x7e, 0x00, 0x00, 0x00, 0x00}, -{0x07, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x3f, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x19, 0x76, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x3e, 0x41, 0x06, 0x38, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x0c, 0x12, 0x10, 0x10, 0x10, 0x3c, 0x10, 0x10, 0x00, 0x00}, -{0x00, 0x00, 0x1b, 0x26, 0x22, 0x22, 0x22, 0x66, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x14, 0x14, 0x2a, 0x2a, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x77, 0x22, 0x1c, 0x1c, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00}, -{0x30, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00}, -{0x00, 0x00, 0x7e, 0x22, 0x10, 0x08, 0x44, 0x7e, 0x00, 0x00, 0x00, 0x00}, -{0x06, 0x08, 0x08, 0x08, 0x08, 0x30, 0x08, 0x08, 0x08, 0x08, 0x06, 0x00}, -{0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, -{0x30, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00}, -{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x49, 0x31, 0x00, 0x00}, -{0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x00} -}; -// the remaining lines of this routine are similar to code developed and published in the - // OPENGL big red book. However I have modified the code slightly, and - // SGI are not responsible for any errors, omissions etc. - static GLuint fontOffset; // first display list - if (!fontOffset) { // then make the raster fonts - GLuint i; - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - fontOffset = glGenLists (128); - for (i = 32; i < 127; i++) { - glNewList(i+fontOffset, GL_COMPILE); - glBitmap(8, 12, 0.0, 2.0, 10.0, 0.0, rasters[i-32]); - glEndList(); - } - } - return fontOffset; -} -void displaytext(int x, int y, char *s) -{ // GWM July 2001 statistics text display at xy text S - GLuint fontOffset=makeRasterFont(); // first display list - glRasterPos2i(x,y); -// glPushAttrib (GL_LIST_BIT); - glListBase(fontOffset); - glCallLists(strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); - glListBase(0); -// glPopAttrib (); -} -// GWM July 2001 - add Statistics structure, and related RenderBin -#include -#include - -void Viewer::showStats() -{ +// GWM July 2001 - moved all draw stats to Statistics structure, and related RenderBin +// GWM Sept 2001 - all draw stats now calculated by calls to ->getStats(Statistic..) +void Viewer::showStats(const unsigned int viewport) +{ // collect stats for viewport static GLfloat tmax=100; glViewport(0,0,ww,wh); float vh = wh; - //glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_STENCIL_BUFFER_BIT); - glDisable( GL_DEPTH_TEST ); // to see the stats always glDisable( GL_ALPHA_TEST ); glDisable( GL_LIGHTING ); @@ -586,6 +461,7 @@ void Viewer::showStats() glPushMatrix(); glLoadIdentity(); // set tmax using hysteresis to prevent flip-flopping between two values of tmax + // tmax is the scale for the stage timing graph if (times[2].timeFrame>360.0f && tmax<1600) tmax=1600; else if (times[2].timeFrame<300.0f && tmax>800) tmax=800; else if (times[2].timeFrame>180.0f && tmax<800) tmax=800; @@ -595,6 +471,7 @@ void Viewer::showStats() else if (times[2].timeFrame>45.0f && tmax<200) tmax=200; else if (times[2].timeFrame<36.0f && tmax>100) tmax=100; glOrtho(-0.1f*tmax, tmax*1.1f,0,vh,0,500); + glDepthRange(0,1); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); @@ -618,7 +495,7 @@ void Viewer::showStats() displaytext(0,(int)(0.98f*vh),clin); } - if (_printStats>1) { // more stats - graphs this time + if (_printStats>=Statistics::STAT_GRAPHS && _printStats!=Statistics::STAT_PRIMSPERVIEW) { // more stats - graphs this time int sampleIndex = 2; float timeApp=times[sampleIndex].timeApp; @@ -634,15 +511,15 @@ void Viewer::showStats() char clin[72]; // buffer to print glColor4fv((GLfloat * )&app_color); - sprintf(clin,"App %.2f ms.", timeApp); + sprintf(clin,"App %.1f ms.", timeApp); displaytext((int)(.15f*tmax),(int)(0.98f*vh),clin); glColor4fv((GLfloat * )&cull_color); - sprintf(clin,"Cull %.2f ms.", timeCull); + sprintf(clin,"Cull %.1f ms.", timeCull); displaytext((int)(.35*tmax),(int)(0.98f*vh),clin); glColor4fv((GLfloat * )&draw_color); - sprintf(clin,"Draw %.2f ms.", timeDraw); + sprintf(clin,"Draw %.1f ms.", timeDraw); displaytext((int)(.55*tmax),(int)(0.98f*vh),clin); glColor4fv((GLfloat * )&frame_color); @@ -693,21 +570,13 @@ void Viewer::showStats() glEnd(); glLineWidth(1.0f); } - if (_printStats==3) { // yet more stats - add triangles, number of strips... + if (_printStats==Statistics::STAT_PRIMS) { // yet more stats - add triangles, number of strips... /* * Use the new renderStage. Required mods to RenderBin.cpp, and RenderStage.cpp (add getPrims) * also needed to define a new class called Statistic (see osgUtil/Statistic). * RO, July 2001. */ - char clin[100]; // buffer to print - char ctmp[12]; - int i; // a counter - static char *prtypes[]={"Total", - " Pt", " Ln", " Lstr", " LSTf", " Llop", // 1- 5 - " Tris", " TStr", " TSfl", " TFan", " TFnf", // 6-10 - " Quad", " QStr", " Pols", "", "", // 11-15 - "", "", "", "", ""}; ViewportList::iterator itr; Statistics primStats; for(itr=_viewportList.begin(); @@ -715,59 +584,16 @@ void Viewer::showStats() ++itr) { osgUtil::RenderStage *stage = itr->sceneView->getRenderStage(); - stage->getPrims(&primStats); + stage->getStats(primStats); } - glColor3f(.9f,.9f,0.0f); - - sprintf(clin,"%d Prims %d Matrices %d nGsets %d nlights %d bins", primStats.nprims, - primStats.nummat, primStats.numOpaque, primStats.nlights, primStats.nbins); - displaytext(0,(int)(0.86f*vh),clin); - strcpy(clin," "); - for (i=0; i<15; i++) { - if (i==0 || primStats.primtypes[i]) { - strcat(clin, prtypes[i]); - } - } - displaytext(0,(int)(0.82f*vh),clin); - strcpy(clin,"GSet type: "); - for (i=0; i<15; i++) { - if (primStats.primtypes[i]) { - sprintf(ctmp,"%5d", primStats.primtypes[i]); - strcat(clin, ctmp); - } - } - displaytext(0,(int)(0.80f*vh),clin); - strcpy(clin,"Prims: "); - for (i=0; i<15; i++) { - if (primStats.numprimtypes[i]) { - sprintf(ctmp,"%5d", primStats.numprimtypes[i]); - strcat(clin, ctmp); - } - } - displaytext(0,(int)(0.78f*vh),clin); - strcpy(clin,"Triangles: "); - for (i=0; i<15; i++) { - if (primStats.primlens[i]) { - sprintf(ctmp,"%5d", primStats.primlens[i]); - strcat(clin, ctmp); - } - } - displaytext(0,(int)(0.76f*vh),clin); - strcpy(clin,"Vertices: "); - for (i=0; i<15; i++) { - if (primStats.primlens[i]) { - sprintf(ctmp,"%5d", primStats.primverts[i]); - strcat(clin, ctmp); - } - } - displaytext(0,(int)(0.74f*vh),clin); + writePrims((int)(0.86f*vh),primStats); } - if (_printStats==4) { // yet more stats - read the depth complexity + if (_printStats==Statistics::STAT_DC) { // yet more stats - read the depth complexity int wid=ww, ht=wh; // temporary local screen size - must change during this section if (wid>0 && ht>0) { const int blsize=16; char *clin=new char[wid/blsize+2]; // buffer to print dc - char *ctext=new char[128]; // buffer to print details + char ctext[128]; // buffer to print details float mdc=0; GLubyte *buffer=new GLubyte[wid*ht]; if (buffer) { @@ -797,13 +623,12 @@ void Viewer::showStats() displaytext(0,(int)(0.84f*vh-(j*12)/blsize),clin); // display average DC over the blsize box } sprintf(ctext, "Pixels hit %.1f Mean DC %.2f: %4d by %4d pixels.", mdc, mdc/(wid*ht), wid, ht); - displaytext(0,(int)(0.86f*vh),clin); + displaytext(0,(int)(0.86f*vh),ctext); glEnable(GL_STENCIL_TEST); // re-enable stencil buffer counting delete [] buffer; } delete [] clin; - delete [] ctext; } } @@ -812,11 +637,9 @@ void Viewer::showStats() glMatrixMode( GL_PROJECTION ); glPopMatrix(); - - //glPopAttrib (); - } + void Viewer::display() { @@ -842,6 +665,11 @@ void Viewer::display() // draw traverasal. times[2].timeDraw+=draw(i); + if (_printStats==Statistics::STAT_PRIMSPERVIEW) + { // gwm - get and show stats in each window + showStats(i); + } + } @@ -851,14 +679,12 @@ void Viewer::display() times[2].timeFrame=frameSeconds()*1000; - if (_printStats) - { // gwm output selected stats at this point - convert to a graph. - showStats(); - times[0]=times[1]; + if (_printStats) { + showStats(0); // output selected stats at this point - timing graph. + times[0]=times[1]; // move the times buffers down times[1]=times[2]; } - glutSwapBuffers(); // moved after draw of stats & glFinish() to get accurate timing (excluding stat draw!) // cout << "Time elapsed "<<_timer.delta_s(_initialTick,_timer.tick())<4) _printStats=0; - if (_printStats==4) { // count depth complexity by incrementing the stencil buffer every + if (_printStats>=Statistics::STAT_RESTART) _printStats=0; + if (getNumViewports()<=1 && _printStats==Statistics::STAT_PRIMSPERVIEW) _printStats++; // no need for these stats as only one view + if (_printStats==Statistics::STAT_DC) { // count depth complexity by incrementing the stencil buffer every // time a pixel is hit - GLint nsten=0; // Number of stencil planes available + int nsten=0; // Number of stencil planes available glGetIntegerv(GL_STENCIL_BITS , &nsten); if (nsten>0) { glEnable(GL_STENCIL_TEST); @@ -1448,3 +1275,192 @@ void Viewer::init(osg::Node* rootnode) osg::notify(osg::WARN)<<" Automatically mapping init to addViewport."< -void RenderBin::getPrims(osg::Statistics *primStats) +void RenderBin::getStats(Statistics& primStats) { for(RenderBinList::iterator itr = _bins.begin(); itr!=_bins.end(); ++itr) { - primStats->nbins++; + primStats.nbins++; + itr->second->getStats(primStats); // gwm 19.08.01 - multi-pass rendering uses these bins too. } for(RenderGraphList::iterator oitr=_renderGraphList.begin(); @@ -182,16 +183,10 @@ void RenderBin::getPrims(osg::Statistics *primStats) { RenderLeaf* rl = dw_itr->get(); Drawable* dw= rl->_drawable; - primStats->numOpaque++; // number of geosets - if (rl->_matrix.get()) primStats->nummat++; // number of matrices + primStats.numOpaque++; // number of geosets + if (rl->_matrix.get()) primStats.nummat++; // number of matrices if (dw) { // then tot up the types 1-14 - GeoSet *gs=dynamic_cast(dw); - if (gs) - { - primStats->addstat(gs); - // rl->getPrims(state,previous);?? - // previous = rl; - } + dw->getStats(primStats); // use sub-class to find the stats for each drawable } } } diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index 8c60f78f9..dcaea5654 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -140,8 +140,8 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous) } // Statistics features -void RenderStage::getPrims(osg::Statistics *primStats) +void RenderStage::getStats(Statistics& primStats) { - if (_renderStageLighting.valid()) primStats->nlights+=_renderStageLighting->_lightList.size(); - RenderBin::getPrims(primStats); + if (_renderStageLighting.valid()) primStats.nlights+=_renderStageLighting->_lightList.size(); + RenderBin::getStats(primStats); }