00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00065 new
00066 RenderNode
00067 (
00068 1.0 / 83495245,
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,
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,
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,
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
00107
00108
00109
00110
00111
00112
00113
00114 new
00115 RenderNode
00116 (
00117 1.0 / 94383759,
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,
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,
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
00146 new
00147 RenderNode
00148 (
00149 1.0 / 1428577,
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,
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,
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
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
00213
00216 RenderNode::~RenderNode(void)
00217 {
00218 }
00219
00220
00221
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
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
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
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
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
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
00429 GLint view[4];
00430 glGetIntegerv(GL_VIEWPORT, view);
00431
00432 int vw = view[2], vh = view[3];
00433
00434
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
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
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
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
00511 GLint view[4];
00512 glGetIntegerv(GL_VIEWPORT, view);
00513
00514 int vw = view[2], vh = view[3];
00515
00516
00517 glMatrixMode(GL_MODELVIEW);
00518 glPushMatrix();
00519 glLoadIdentity();
00520 glMatrixMode(GL_PROJECTION);
00521 glPushMatrix();
00522 glLoadIdentity();
00523 gluOrtho2D(0, vw, 0, vh);
00524
00525
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
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
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
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 }