Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGRenderNode.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *           Copyright (C) 2000-2002,2002 by the OpenSG Forum                *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 
00042 #include <vector>
00043 
00044 #include <OSGConfig.h>
00045 #include <OSGGL.h>
00046 #include <OSGGLU.h>
00047 #include <OSGBaseFunctions.h>
00048 #include <OSGTime.h>
00049 #include <OSGLog.h>
00050 #include <OSGMatrix.h>
00051 #include <OSGWindow.h>
00052 
00053 #include "OSGRenderNode.h"
00054 
00055 OSG_USING_NAMESPACE using namespace std;
00056 
00062 RenderNode *RenderNode::            _prefefined[] =
00063 {
00064     // some nvidia cards
00065     new
00066     RenderNode
00067         (
00068             1.0 /   83495245, // GF 4 
00069             1.0 /   16750624,
00070             1.0 / 1161538447, 
00071             1.0 /   42022724, 
00072             1.0 /   83570644,
00073             "NVIDIA Corporation", "GeForce4 Ti 4600/AGP/3DNOW!"
00074         ),
00075     new
00076     RenderNode
00077         (
00078             1.0 /   83495245, // GF 4 
00079             1.0 /   16750624,
00080             1.0 / 1161538447, 
00081             1.0 /   42022724, 
00082             1.0 /   83570644,
00083             "NVIDIA Corporation", "GeForce4 Ti 4600/AGP/SSE/3DNOW!"
00084         ),
00085     new
00086     RenderNode
00087         (
00088             1.0 /   83455190, // GF 4 
00089             1.0 /   16881114,
00090             1.0 / 1061266770, 
00091             1.0 /   42022724, 
00092             1.0 /   83570644,
00093             "NVIDIA Corporation", "GeForce4 Ti 4800 SE/AGP/SSE/3DNOW!"
00094         ),
00095     new
00096     RenderNode
00097         (
00098             1.0 /  105725796, // GF 4 
00099             1.0 /   20313509,
00100             1.0 / 1168604741, 
00101             1.0 /   45037981, 
00102             1.0 /  107106583,
00103             "NVIDIA Corporation", "GeForce4 Ti 4600/AGP/SSE2"
00104         ),
00105     /*
00106     new RenderNode(1.0/  7598000,          // GF 256
00107                    1.0/  7597000,
00108                    1.0/110599000,
00109                    1.0/ 18896143,
00110                    1.0/ 26220918,
00111                    "NVIDIA Corporation",
00112                    "GeForce 256/AGP"),
00113     */
00114     new
00115     RenderNode
00116         (
00117             1.0 /  94383759, // GF 3 
00118             1.0 /  17733654, 
00119             1.0 / 897012437, 
00120             1.0 /  24905933, 
00121             1.0 /  45649003,
00122             "NVIDIA Corporation", "GeForce3/AGP/3DNOW!"
00123         ),
00124     new
00125     RenderNode
00126         (
00127             1.0 /  94383759, // GF 3 
00128             1.0 /  17733654, 
00129             1.0 / 897012437,
00130             1.0 /  24905933, 
00131             1.0 /  45649003,
00132             "NVIDIA Corporation", "GeForce3/AGP/SSE2"
00133         ),
00134     new
00135     RenderNode
00136         (
00137             1.0 /  87097434, // GF 2 MX 
00138             1.0 /  18473570, 
00139             1.0 / 172343128,
00140             1.0 /  49542156,
00141             1.0 /  77120245,
00142             "NVIDIA Corporation", "GeForce2 MX/AGP/3DNOW!"
00143         ),
00144 
00145     // some sgi cards
00146     new
00147     RenderNode
00148         (
00149             1.0 /  1428577, // O2 
00150             1.0 /   581803, 
00151             1.0 / 66498959, 
00152             1.0 /  4047028,
00153             1.0 /  1101353, 
00154             "SGI", "CRIME"
00155         ),
00156     new
00157     RenderNode
00158         (
00159             1.0 /  10121349, // IR2 
00160             1.0 /   7749685, 
00161             1.0 / 466657941, 
00162             1.0 /  38311070, 
00163             1.0 /  73507039, 
00164             "SGI", "IRL/M/2/64/4"
00165         ),
00166     new
00167     RenderNode
00168         (
00169             1.0 /  12237547, // ATI 
00170             1.0 /  12422953, 
00171             1.0 / 190803343, 
00172             1.0 /  41767062, 
00173             1.0 / 157129952, 
00174             "ATI Technologies Inc.", "Radeon 9700 PRO Pentium 4 (SSE2)"
00175         ),
00176     NULL
00177 };
00178 
00179 /*-------------------------------------------------------------------------*/
00180 /*                            Constructors                                 */
00181 
00184 RenderNode::RenderNode(Real32 invisibleFaceCost, Real32 visibleFaceCost,
00185                        Real32 drawPixelCost, Real32 readPixelCost,
00186                        Real32 writePixelCost, const string &vendor,
00187                        const string &renderer) :
00188         _visibleFaceCost(visibleFaceCost),
00189         _invisibleFaceCost(invisibleFaceCost),
00190         _drawPixelCost(drawPixelCost),
00191         _readPixelCost(readPixelCost),
00192         _writePixelCost(writePixelCost),
00193         _vendor(vendor),
00194         _renderer(renderer)
00195 {
00196 }
00197 
00200 RenderNode::RenderNode(const RenderNode &source) :
00201     _visibleFaceCost(source._visibleFaceCost),
00202     _invisibleFaceCost(source._invisibleFaceCost),
00203     _drawPixelCost(source._drawPixelCost),
00204     _readPixelCost(source._readPixelCost),
00205     _writePixelCost(source._writePixelCost),
00206     _vendor(source._vendor),
00207     _renderer(source._renderer)
00208 {
00209 }
00210 
00211 /*-------------------------------------------------------------------------*/
00212 /*                             Destructor                                  */
00213 
00216 RenderNode::~RenderNode(void)
00217 {
00218 }
00219 
00220 /*-------------------------------------------------------------------------*/
00221 /*                             Assignment                                  */
00222 
00225 RenderNode &RenderNode::operator=(const RenderNode &source)
00226 {
00227     if(this == &source)
00228         return *this;
00229 
00230     _visibleFaceCost = source._visibleFaceCost;
00231     _invisibleFaceCost = source._invisibleFaceCost;
00232     _drawPixelCost = source._drawPixelCost;
00233     _readPixelCost = source._readPixelCost;
00234     _writePixelCost = source._writePixelCost;
00235     _vendor = source._vendor;
00236     _renderer = source._renderer;
00237     return *this;
00238 }
00239 
00240 /*-------------------------------------------------------------------------*/
00241 /*                             Performance analysis                        */
00242 
00251 void RenderNode::determinePerformance(WindowPtr &window)
00252 {
00253     int     c;
00254     double  t;
00255     UInt32  width, height;
00256 
00257     setVendor((const char *) glGetString(GL_VENDOR));
00258     setRenderer((const char *) glGetString(GL_RENDERER));
00259 
00260     // try to find precalculated values
00261     for(c = 0; _prefefined[c] != NULL; ++c)
00262     {
00263         if(_prefefined[c]->getVendor() == getVendor() &&
00264                    _prefefined[c]->getRenderer() == getRenderer())
00265         {
00266             SLOG << "Predefined performance values used." << endl;
00267             *this = *_prefefined[c];
00268             return;
00269         }
00270     }
00271 
00272     SLOG << "Start rendering benchmark" << endl;
00273     window->activate();
00274 
00275     // set viewport
00276     glViewport(0, 0, window->getWidth(), window->getHeight());
00277 
00278     glPushAttrib(GL_ALL_ATTRIB_BITS);
00279     glDisable(GL_SCISSOR_TEST);
00280     glEnable(GL_DEPTH_TEST);
00281     glDisable(GL_COLOR_MATERIAL);
00282     glEnable(GL_LIGHTING);
00283     glDepthFunc(GL_LEQUAL);
00284     for(int i = 0; i < 8; ++i)
00285         glDisable(GL_LIGHT0 + i);
00286     glEnable(GL_LIGHT0);
00287 
00288     double  a1, a2, b, r;
00289     a1 = runFaceBench(1, 1);
00290     a2 = runFaceBench(4, 1);
00291     b = (a2 - .25 * a1) / .75;
00292     r = runRasterBench();
00293 
00294     _visibleFaceCost = Real32(1.0 / a1);
00295     _invisibleFaceCost = Real32(1.0 / b);
00296     _drawPixelCost = Real32(1.0 / r);
00297 
00298     // test write performance
00299     glPixelStorei(GL_PACK_ALIGNMENT, 1);
00300     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00301 
00302     vector<UInt8>   pixels;
00303     width = window->getWidth();
00304     height = window->getHeight();
00305     pixels.resize(width * height * 4);
00306     glFinish();
00307     t = -getSystemTime();
00308     for(c = 0; c < 2; ++c)
00309     {
00310         glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);
00311     }
00312 
00313     glFinish();
00314     t += getSystemTime();
00315     _readPixelCost = Real32(t / (c * width * height));
00316 
00317     // test write performance
00318     glMatrixMode(GL_MODELVIEW);
00319     glPushMatrix();
00320     glLoadIdentity();
00321     glMatrixMode(GL_PROJECTION);
00322     glPushMatrix();
00323     glLoadIdentity();
00324     gluOrtho2D(0, width, 0, height);
00325     glRasterPos2i(0, 0);
00326     glDisable(GL_DEPTH_TEST);
00327     glFinish();
00328     t = -getSystemTime();
00329     for(c = 0; c < 2; ++c)
00330     {
00331         glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);
00332     }
00333     glFinish();
00334     t += getSystemTime();
00335     _writePixelCost = Real32(t / (c * width * height));
00336     glEnable(GL_DEPTH_TEST);
00337     glPopMatrix();
00338     glMatrixMode(GL_MODELVIEW);
00339     glPopMatrix();
00340     SLOG << "End rendering benchmark" << endl;
00341 
00342     glPopAttrib();
00343 }
00344 
00347 void RenderNode::copyToBin(BinaryDataHandler &handle)
00348 {
00349     handle.putValue(_invisibleFaceCost);
00350     handle.putValue(_visibleFaceCost);
00351     handle.putValue(_drawPixelCost);
00352     handle.putValue(_readPixelCost);
00353     handle.putValue(_writePixelCost);
00354 }
00355 
00358 void RenderNode::copyFromBin(BinaryDataHandler &handle)
00359 {
00360     handle.getValue(_invisibleFaceCost);
00361     handle.getValue(_visibleFaceCost);
00362     handle.getValue(_drawPixelCost);
00363     handle.getValue(_readPixelCost);
00364     handle.getValue(_writePixelCost);
00365 }
00366 
00377 void RenderNode::setGroup(const RenderNode *begin, const RenderNode *end)
00378 {
00379     const RenderNode    *i;
00380     Real32              invisibleFaces = 0;
00381     Real32              visibleFaces = 0;
00382     Real32              drawPixels = 0;
00383     Real32              readPixels = 0;
00384     Real32              writePixels = 0;
00385     UInt32              count = 0;
00386 
00387     for(count = 0, i = begin; i != end; ++i, count++)
00388     {
00389         invisibleFaces += 1.f / i->_invisibleFaceCost;
00390         visibleFaces += 1.f / i->_visibleFaceCost;
00391         drawPixels += 1.f / i->_drawPixelCost;
00392         readPixels += 1.f / i->_readPixelCost;
00393         writePixels += 1.f / i->_writePixelCost;
00394     }
00395 
00396     _invisibleFaceCost = (1.f / invisibleFaces);
00397     _visibleFaceCost = (1.f / visibleFaces);
00398     _drawPixelCost = (1.f / drawPixels);
00399     _readPixelCost = (1.f / readPixels);
00400     _writePixelCost = (1.f / writePixels);
00401 }
00402 
00405 void RenderNode::dump(void) const
00406 {
00407     FLOG(("Vendor           : %s\n", _vendor.c_str()));
00408     FLOG(("Rnderer          : %s\n", _renderer.c_str()));
00409     FLOG(("Culled Faces/s   : %20.5f\n", 1.0 / _invisibleFaceCost));
00410     FLOG(("Faces/s          : %20.5f\n", 1.0 / _visibleFaceCost));
00411     FLOG(("Pixel/s          : %20.5f\n", 1.0 / _drawPixelCost));
00412     FLOG(("Read pixel/s     : %20.5f\n", 1.0 / _readPixelCost));
00413     FLOG(("Write pixel/s    : %20.5f\n", 1.0 / _writePixelCost));
00414 }
00415 
00423 double RenderNode::runFaceBench(float w, int size)
00424 {
00425     int     c;
00426     int     faces = 0;
00427 
00428     // vp size
00429     GLint   view[4];
00430     glGetIntegerv(GL_VIEWPORT, view);
00431 
00432     int vw = view[2], vh = view[3];
00433 
00434     // set projection
00435     glMatrixMode(GL_MODELVIEW);
00436     glPushMatrix();
00437     glLoadIdentity();
00438     glMatrixMode(GL_PROJECTION);
00439     glPushMatrix();
00440     glLoadIdentity();
00441     gluOrtho2D(0, vw, 0, vh);
00442     glMatrixMode(GL_MODELVIEW);
00443 
00444     // create display list
00445     GLuint  dList = glGenLists(1);
00446     glNewList(dList, GL_COMPILE);
00447     glBegin(GL_TRIANGLE_STRIP);
00448     for(int x = 0; x <= (vw * w); x += size)
00449     {
00450         glNormal3f(0, 0, 1);
00451         glVertex3i(x, 0, 1);
00452         glNormal3f(0, 0, 1);
00453         glVertex3i(x, size, 1);
00454         if(((x & 3) == 3) && (x != (vw * w)))
00455         {
00456             glEnd();
00457             glBegin(GL_TRIANGLE_STRIP);
00458             glNormal3f(0, 0, 1);
00459             glVertex3i(x, 0, 1);
00460             glNormal3f(0, 0, 1);
00461             glVertex3i(x, size, 1);
00462         }
00463     }
00464 
00465     glEnd();
00466     glEndList();
00467     glFinish();
00468 
00469     // run test
00470     Time    t = 0;
00471     c = 0;
00472     glPushMatrix();
00473     do
00474     {
00475         glLoadIdentity();
00476         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00477         glFinish();
00478         t -= getSystemTime();
00479         for(int y = 0; y < vh; y += size)
00480         {
00481             glCallList(dList);
00482             glTranslatef(0, GLfloat(size), 0);
00483         }
00484 
00485         glFinish();
00486         t += getSystemTime();
00487         c++;
00488     } while(t < .5);
00489     glPopMatrix();
00490     faces = (int) (((vw * w * 2) / size) * (vh / size) * c);
00491 
00492     // reset projection
00493     glMatrixMode(GL_PROJECTION);
00494     glPopMatrix();
00495     glMatrixMode(GL_MODELVIEW);
00496     glPopMatrix();
00497     glMatrixMode(GL_PROJECTION);
00498 
00499     glDeleteLists(dList, 1);
00500     return faces / t;
00501 }
00502 
00506 double RenderNode::runRasterBench(void)
00507 {
00508     int     c;
00509 
00510     // vp size
00511     GLint   view[4];
00512     glGetIntegerv(GL_VIEWPORT, view);
00513 
00514     int vw = view[2], vh = view[3];
00515 
00516     // set projection
00517     glMatrixMode(GL_MODELVIEW);
00518     glPushMatrix();
00519     glLoadIdentity();
00520     glMatrixMode(GL_PROJECTION);
00521     glPushMatrix();
00522     glLoadIdentity();
00523     gluOrtho2D(0, vw, 0, vh);
00524 
00525     // create display list
00526     GLuint  dList = glGenLists(1);
00527     glNewList(dList, GL_COMPILE);
00528     glBegin(GL_QUADS);
00529     glVertex3i(0, 0, 1);
00530     glNormal3f(0, 0, 1);
00531     glVertex3i(0, vh - 1, 1);
00532     glNormal3f(0, 0, 1);
00533     glVertex3i(vw - 1, vh - 1, 1);
00534     glNormal3f(0, 0, 1);
00535     glVertex3i(vw - 1, 0, 1);
00536     glNormal3f(0, 0, 1);
00537     glEnd();
00538     glEndList();
00539     glFinish();
00540 
00541     // run test
00542     Time    t = 0;
00543     c = 0;
00544     do
00545     {
00546         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00547         glFinish();
00548         t -= getSystemTime();
00549         glCallList(dList);
00550         glFinish();
00551         t += getSystemTime();
00552         c++;
00553     } 
00554     while(t < .5);
00555 
00556     // reset projection
00557     glMatrixMode(GL_PROJECTION);
00558     glPopMatrix();
00559     glMatrixMode(GL_MODELVIEW);
00560     glPopMatrix();
00561     glMatrixMode(GL_PROJECTION);
00562 
00563     glDeleteLists(dList, 1);
00564     return (vw * vh * c) / t;
00565 }
00566 
00567 /*-------------------------------------------------------------------------*/
00568 /*                              cvs id's                                   */
00569 
00570 #ifdef __sgi
00571 #pragma set woff 1174
00572 #endif
00573 #ifdef OSG_LINUX_ICC
00574 #pragma warning(disable : 177)
00575 #endif
00576 
00577 namespace
00578 {
00579     static Char8    cvsid_cpp[] = "@(#)$Id:$";
00580     static Char8    cvsid_hpp[] = OSG_CLUSTERNODE_HEADER_CVSID;
00581     static Char8    cvsid_inl[] = OSG_CLUSTERNODE_INLINE_CVSID;
00582 }

Generated on Thu Aug 25 04:09:07 2005 for OpenSG by  doxygen 1.4.3