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,
00185                              Real32       visibleFaceCost,
00186                              Real32       drawPixelCost, 
00187                              Real32       readPixelCost,
00188                              Real32       writePixelCost, 
00189                        const std::string &vendor,
00190                        const std::string &renderer) :
00191     _visibleFaceCost  (visibleFaceCost  ),
00192     _invisibleFaceCost(invisibleFaceCost),
00193     _drawPixelCost    (drawPixelCost    ),
00194     _readPixelCost    (readPixelCost    ),
00195     _writePixelCost   (writePixelCost   ),
00196     _vendor           (vendor           ),
00197     _renderer         (renderer         )
00198 {
00199 }
00200 
00203 RenderNode::RenderNode(const RenderNode &source) :
00204     _visibleFaceCost  (source._visibleFaceCost  ),
00205     _invisibleFaceCost(source._invisibleFaceCost),
00206     _drawPixelCost    (source._drawPixelCost    ),
00207     _readPixelCost    (source._readPixelCost    ),
00208     _writePixelCost   (source._writePixelCost   ),
00209     _vendor           (source._vendor           ),
00210     _renderer         (source._renderer         )
00211 {
00212 }
00213 
00214 /*-------------------------------------------------------------------------*/
00215 /*                             Destructor                                  */
00216 
00219 RenderNode::~RenderNode(void)
00220 {
00221 }
00222 
00223 /*-------------------------------------------------------------------------*/
00224 /*                             Assignment                                  */
00225 
00228 RenderNode &RenderNode::operator=(const RenderNode &source)
00229 {
00230     if(this == &source)
00231         return *this;
00232 
00233     _visibleFaceCost   = source._visibleFaceCost;
00234     _invisibleFaceCost = source._invisibleFaceCost;
00235     _drawPixelCost     = source._drawPixelCost;
00236     _readPixelCost     = source._readPixelCost;
00237     _writePixelCost    = source._writePixelCost;
00238     _vendor            = source._vendor;
00239     _renderer          = source._renderer;
00240 
00241     return *this;
00242 }
00243 
00244 /*-------------------------------------------------------------------------*/
00245 /*                             Performance analysis                        */
00246 
00255 void RenderNode::determinePerformance(WindowPtr &window)
00256 {
00257     int     c;
00258     double  t;
00259     UInt32  width, height;
00260 
00261     setVendor  ((const char *) glGetString(GL_VENDOR));
00262     setRenderer((const char *) glGetString(GL_RENDERER));
00263 
00264     // try to find precalculated values
00265     for(c = 0; _prefefined[c] != NULL; ++c)
00266     {
00267         if(_prefefined[c]->getVendor() == getVendor() &&
00268                    _prefefined[c]->getRenderer() == getRenderer())
00269         {
00270             SLOG << "Predefined performance values used." << endl;
00271             *this = *_prefefined[c];
00272             return;
00273         }
00274     }
00275 
00276     SLOG << "Start rendering benchmark" << endl;
00277     window->activate();
00278 
00279     // set viewport
00280     glViewport(0, 0, window->getWidth(), window->getHeight());
00281 
00282     glPushAttrib(GL_ALL_ATTRIB_BITS);
00283     glDisable(GL_SCISSOR_TEST);
00284     glEnable(GL_DEPTH_TEST);
00285     glDisable(GL_COLOR_MATERIAL);
00286     glEnable(GL_LIGHTING);
00287     glDepthFunc(GL_LEQUAL);
00288     for(int i = 0; i < 8; ++i)
00289         glDisable(GL_LIGHT0 + i);
00290     glEnable(GL_LIGHT0);
00291 
00292     double  a1, a2, b, r;
00293     a1 = runFaceBench(1, 1);
00294     a2 = runFaceBench(4, 1);
00295     b = (a2 - .25 * a1) / .75;
00296     r = runRasterBench();
00297 
00298     _visibleFaceCost = Real32(1.0 / a1);
00299     _invisibleFaceCost = Real32(1.0 / b);
00300     _drawPixelCost = Real32(1.0 / r);
00301 
00302     // test write performance
00303     glPixelStorei(GL_PACK_ALIGNMENT, 1);
00304     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00305 
00306     vector<UInt8>   pixels;
00307     width = window->getWidth();
00308     height = window->getHeight();
00309     pixels.resize(width * height * 4);
00310     glFinish();
00311     t = -getSystemTime();
00312     for(c = 0; c < 2; ++c)
00313     {
00314         glReadPixels(0, 
00315                      0, 
00316                      width, 
00317                      height, 
00318                      GL_RGB, 
00319                      GL_UNSIGNED_BYTE, 
00320                      &pixels[0]);
00321     }
00322 
00323     glFinish();
00324     t += getSystemTime();
00325     _readPixelCost = Real32(t / (c * width * height));
00326 
00327     // test write performance
00328     glMatrixMode(GL_MODELVIEW);
00329     glPushMatrix();
00330     glLoadIdentity();
00331     glMatrixMode(GL_PROJECTION);
00332     glPushMatrix();
00333     glLoadIdentity();
00334     gluOrtho2D(0, width, 0, height);
00335     glRasterPos2i(0, 0);
00336     glDisable(GL_DEPTH_TEST);
00337     glFinish();
00338     t = -getSystemTime();
00339     for(c = 0; c < 2; ++c)
00340     {
00341         glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);
00342     }
00343     glFinish();
00344     t += getSystemTime();
00345     _writePixelCost = Real32(t / (c * width * height));
00346     glEnable(GL_DEPTH_TEST);
00347     glPopMatrix();
00348     glMatrixMode(GL_MODELVIEW);
00349     glPopMatrix();
00350     SLOG << "End rendering benchmark" << endl;
00351 
00352     glPopAttrib();
00353 }
00354 
00357 void RenderNode::copyToBin(BinaryDataHandler &handle)
00358 {
00359     handle.putValue(_invisibleFaceCost);
00360     handle.putValue(_visibleFaceCost);
00361     handle.putValue(_drawPixelCost);
00362     handle.putValue(_readPixelCost);
00363     handle.putValue(_writePixelCost);
00364 }
00365 
00368 void RenderNode::copyFromBin(BinaryDataHandler &handle)
00369 {
00370     handle.getValue(_invisibleFaceCost);
00371     handle.getValue(_visibleFaceCost);
00372     handle.getValue(_drawPixelCost);
00373     handle.getValue(_readPixelCost);
00374     handle.getValue(_writePixelCost);
00375 }
00376 
00387 void RenderNode::setGroup(const RenderNode *begin, const RenderNode *end)
00388 {
00389     const RenderNode    *i;
00390     Real32              invisibleFaces = 0;
00391     Real32              visibleFaces = 0;
00392     Real32              drawPixels = 0;
00393     Real32              readPixels = 0;
00394     Real32              writePixels = 0;
00395     UInt32              count = 0;
00396 
00397     for(count = 0, i = begin; i != end; ++i, count++)
00398     {
00399         invisibleFaces += 1.f / i->_invisibleFaceCost;
00400         visibleFaces += 1.f / i->_visibleFaceCost;
00401         drawPixels += 1.f / i->_drawPixelCost;
00402         readPixels += 1.f / i->_readPixelCost;
00403         writePixels += 1.f / i->_writePixelCost;
00404     }
00405 
00406     _invisibleFaceCost = (1.f / invisibleFaces);
00407     _visibleFaceCost = (1.f / visibleFaces);
00408     _drawPixelCost = (1.f / drawPixels);
00409     _readPixelCost = (1.f / readPixels);
00410     _writePixelCost = (1.f / writePixels);
00411 }
00412 
00415 void RenderNode::dump(void) const
00416 {
00417     FLOG(("Vendor           : %s\n", _vendor.c_str()));
00418     FLOG(("Rnderer          : %s\n", _renderer.c_str()));
00419     FLOG(("Culled Faces/s   : %20.5f\n", 1.0 / _invisibleFaceCost));
00420     FLOG(("Faces/s          : %20.5f\n", 1.0 / _visibleFaceCost));
00421     FLOG(("Pixel/s          : %20.5f\n", 1.0 / _drawPixelCost));
00422     FLOG(("Read pixel/s     : %20.5f\n", 1.0 / _readPixelCost));
00423     FLOG(("Write pixel/s    : %20.5f\n", 1.0 / _writePixelCost));
00424 }
00425 
00433 double RenderNode::runFaceBench(float w, int size)
00434 {
00435     int     c;
00436     int     faces = 0;
00437 
00438     // vp size
00439     GLint   view[4];
00440     glGetIntegerv(GL_VIEWPORT, view);
00441 
00442     int vw = view[2], vh = view[3];
00443 
00444     // set projection
00445     glMatrixMode(GL_MODELVIEW);
00446     glPushMatrix();
00447     glLoadIdentity();
00448     glMatrixMode(GL_PROJECTION);
00449     glPushMatrix();
00450     glLoadIdentity();
00451     gluOrtho2D(0, vw, 0, vh);
00452     glMatrixMode(GL_MODELVIEW);
00453 
00454     // create display list
00455     GLuint  dList = glGenLists(1);
00456     glNewList(dList, GL_COMPILE);
00457     glBegin(GL_TRIANGLE_STRIP);
00458     for(int x = 0; x <= (vw * w); x += size)
00459     {
00460         glNormal3f(0, 0, 1);
00461         glVertex3i(x, 0, 1);
00462         glNormal3f(0, 0, 1);
00463         glVertex3i(x, size, 1);
00464         if(((x & 3) == 3) && (x != (vw * w)))
00465         {
00466             glEnd();
00467             glBegin(GL_TRIANGLE_STRIP);
00468             glNormal3f(0, 0, 1);
00469             glVertex3i(x, 0, 1);
00470             glNormal3f(0, 0, 1);
00471             glVertex3i(x, size, 1);
00472         }
00473     }
00474 
00475     glEnd();
00476     glEndList();
00477     glFinish();
00478 
00479     // run test
00480     Time    t = 0;
00481     c = 0;
00482     glPushMatrix();
00483     do
00484     {
00485         glLoadIdentity();
00486         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00487         glFinish();
00488         t -= getSystemTime();
00489         for(int y = 0; y < vh; y += size)
00490         {
00491             glCallList(dList);
00492             glTranslatef(0, GLfloat(size), 0);
00493         }
00494 
00495         glFinish();
00496         t += getSystemTime();
00497         c++;
00498     } while(t < .5);
00499     glPopMatrix();
00500     faces = (int) (((vw * w * 2) / size) * (vh / size) * c);
00501 
00502     // reset projection
00503     glMatrixMode(GL_PROJECTION);
00504     glPopMatrix();
00505     glMatrixMode(GL_MODELVIEW);
00506     glPopMatrix();
00507     glMatrixMode(GL_PROJECTION);
00508 
00509     glDeleteLists(dList, 1);
00510     return faces / t;
00511 }
00512 
00516 double RenderNode::runRasterBench(void)
00517 {
00518     int     c;
00519 
00520     // vp size
00521     GLint   view[4];
00522     glGetIntegerv(GL_VIEWPORT, view);
00523 
00524     int vw = view[2], vh = view[3];
00525 
00526     // set projection
00527     glMatrixMode(GL_MODELVIEW);
00528     glPushMatrix();
00529     glLoadIdentity();
00530     glMatrixMode(GL_PROJECTION);
00531     glPushMatrix();
00532     glLoadIdentity();
00533     gluOrtho2D(0, vw, 0, vh);
00534 
00535     // create display list
00536     GLuint  dList = glGenLists(1);
00537     glNewList(dList, GL_COMPILE);
00538     glBegin(GL_QUADS);
00539     glVertex3i(0, 0, 1);
00540     glNormal3f(0, 0, 1);
00541     glVertex3i(0, vh - 1, 1);
00542     glNormal3f(0, 0, 1);
00543     glVertex3i(vw - 1, vh - 1, 1);
00544     glNormal3f(0, 0, 1);
00545     glVertex3i(vw - 1, 0, 1);
00546     glNormal3f(0, 0, 1);
00547     glEnd();
00548     glEndList();
00549     glFinish();
00550 
00551     // run test
00552     Time    t = 0;
00553     c = 0;
00554     do
00555     {
00556         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00557         glFinish();
00558         t -= getSystemTime();
00559         glCallList(dList);
00560         glFinish();
00561         t += getSystemTime();
00562         c++;
00563     } 
00564     while(t < .5);
00565 
00566     // reset projection
00567     glMatrixMode(GL_PROJECTION);
00568     glPopMatrix();
00569     glMatrixMode(GL_MODELVIEW);
00570     glPopMatrix();
00571     glMatrixMode(GL_PROJECTION);
00572 
00573     glDeleteLists(dList, 1);
00574     return (vw * vh * c) / t;
00575 }