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,
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
00216
00219 RenderNode::~RenderNode(void)
00220 {
00221 }
00222
00223
00224
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
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
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
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
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
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
00439 GLint view[4];
00440 glGetIntegerv(GL_VIEWPORT, view);
00441
00442 int vw = view[2], vh = view[3];
00443
00444
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
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
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
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
00521 GLint view[4];
00522 glGetIntegerv(GL_VIEWPORT, view);
00523
00524 int vw = view[2], vh = view[3];
00525
00526
00527 glMatrixMode(GL_MODELVIEW);
00528 glPushMatrix();
00529 glLoadIdentity();
00530 glMatrixMode(GL_PROJECTION);
00531 glPushMatrix();
00532 glLoadIdentity();
00533 gluOrtho2D(0, vw, 0, vh);
00534
00535
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
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
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 }