RTRender.cc

Go to the documentation of this file.
00001 #include <gra/render/RTRender.h>
00002 #include <esg/explorer/RayIntExplorer.h>
00003 #include <gra/shader/RTShader.h>
00004 #include <esg/Statistics.h>
00005 #include <time.h>
00006 
00007 using namespace gra;
00008 
00009 void RTRender::_render_pixel_point(RayIntExplorer&   explorer,
00010                                    SceneGraphObject& scene,
00011                                    Shader&           shader,
00012                                    const Vector3&    point,
00013                                    Vector3           dir,
00014                                    Color3f&          pixelColor)
00015 {
00016     Color3f * pEnergy = NULL;
00017 
00018     /*
00019      * Cast primary ray
00020      */
00021     
00022     explorer.reinit(point, dir, _pIntersector);
00023     _pIntersector->init(ENV_WANT_INTERSECTION |
00024                         ENV_WANT_NORMAL |
00025                         ENV_WANT_ASOC_PRIMITIVE |
00026                         ENV_WANT_N_DOT_D);
00027     explorer.explore(scene);
00028 
00029     /*
00030      * Check whether the ray has intersected some object
00031      */
00032     
00033     PointEnv* pSurr = explorer.result();
00034     if (!pSurr) {
00035         pixelColor.set(_background);
00036         return;
00037     }
00038     if (!(pSurr->mask & (ENV_HAVE_INTERSECTION|
00039                          ENV_HAVE_NORMAL|
00040                          ENV_HAVE_ASOC_PRIMITIVE))) {
00041         delete pSurr;
00042         pixelColor.set(_background);
00043         return;
00044     }
00045 
00046     /*
00047      * Recursion - get color of the object
00048      */
00049 
00050     dir.negate();
00051 
00052     double nv = ((pSurr->mask & ENV_HAVE_N_DOT_D) ?
00053                  -(pSurr->nd) :
00054                  pSurr->normal.dot(dir));
00055 
00056     if (pSurr->normalOrientation == PointEnv::RANDOM_NORMAL &&
00057         pSurr->normal.dot(dir) < 0) pSurr->normal.negate();
00058 
00059     if (pSurr->mask & ENV_HAVE_TRANSFORMATION) {
00060         shader.setRenderedShape(pSurr->pVisitableObj, &(pSurr->trMat));
00061         pEnergy = shader.illuminatePoint(pSurr->intersection,
00062                                          pSurr->normal,
00063                                          dir, 0, &nv,
00064                                          &(pSurr->trMat));
00065     } else {
00066         shader.setRenderedShape(pSurr->pVisitableObj, NULL);
00067         pEnergy = shader.illuminatePoint(pSurr->intersection,
00068                                          pSurr->normal,
00069                                          dir, 0, &nv, NULL);
00070     }
00071     
00072     delete pSurr;
00073                     
00074     if (pEnergy) {
00075         pixelColor.set(*pEnergy);
00076         delete pEnergy;
00077     }
00078 }
00079 
00080 unsigned RTRender::_render_pixel_centroid(RayIntExplorer&   explorer,
00081                                           SceneGraphObject& scene,
00082                                           Shader&           shader,
00083                                           Camera&           camera,
00084                                           const Vector3&    centroid,
00085                                           unsigned          row,
00086                                           unsigned          col,
00087                                           unsigned          resX,
00088                                           unsigned          resY,
00089                                           Color3f&          pixelColor)
00090 {
00091     Color3f c;
00092     _render_pixel_point(explorer, scene, shader, centroid,
00093                         camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_CENTROID)), c);
00094     pixelColor.add(c);
00095     return 1;
00096 }
00097 
00098 unsigned RTRender::_render_pixel_corners(RayIntExplorer&   explorer,
00099                                          SceneGraphObject& scene,
00100                                          Shader&           shader,
00101                                          Camera&           camera,
00102                                          const Vector3d&   point,
00103                                          const Vector3d&   xDir,
00104                                          const Vector3d&   yDir,
00105                                          unsigned          row,
00106                                          unsigned          col,
00107                                          unsigned          resX,
00108                                          unsigned          resY,
00109                                          Color3f*          cRow,
00110                                          Color3f&          cCol,
00111                                          Color3f&          pixelColor)
00112 {
00113     Vector3d p(point);
00114     Color3f  c00(0,0,0);
00115     unsigned numRays = 0;
00116 
00117     if (row == 0 && col == 0) {
00118         _render_pixel_point(explorer, scene, shader, p,
00119                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_UPPER_LEFT_CORNER)),
00120                             c00);
00121         p.add(xDir);
00122         _render_pixel_point(explorer, scene, shader, p,
00123                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_UPPER_RIGHT_CORNER)),
00124                             cRow[col+1]);
00125         p.set(point);
00126         p.add(yDir);
00127         _render_pixel_point(explorer, scene, shader, p,
00128                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_LOWER_LEFT_CORNER)),
00129                             cRow[col]);
00130         p.add(xDir);
00131         _render_pixel_point(explorer, scene, shader, p,
00132                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_LOWER_RIGHT_CORNER)),
00133                             cCol);
00134         numRays = 4;
00135     }
00136 
00137     if (row == 0 && col > 0) {
00138         c00.set(cRow[col]);
00139         cRow[col].set(cCol);
00140         p.add(xDir);
00141         _render_pixel_point(explorer, scene, shader, p,
00142                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_UPPER_RIGHT_CORNER)),
00143                             cRow[col+1]);
00144         p.add(yDir);
00145         _render_pixel_point(explorer, scene, shader, p,
00146                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_LOWER_RIGHT_CORNER)),
00147                             cCol);
00148         numRays = 2;
00149     }
00150 
00151     if (row > 0 && col == 0) {
00152         c00.set(cRow[col]);
00153         p.add(yDir);
00154         _render_pixel_point(explorer, scene, shader, p,
00155                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_LOWER_LEFT_CORNER)),
00156                             cRow[col]);
00157         p.add(xDir);
00158         _render_pixel_point(explorer, scene, shader, p,
00159                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_LOWER_RIGHT_CORNER)),
00160                             cCol);
00161         numRays = 2;
00162     }
00163 
00164     if (row > 0 && col > 0) {
00165         c00.set(cRow[col]);
00166         cRow[col].set(cCol);
00167         p.add(yDir);
00168         p.add(xDir);
00169         _render_pixel_point(explorer, scene, shader, p,
00170                             camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_LOWER_RIGHT_CORNER)),
00171                             cCol);
00172         numRays = 1;
00173     }
00174 
00175     c00.add(cRow[col]);
00176     c00.add(cRow[col+1]);
00177     c00.add(cCol);
00178     c00.scale(.25);
00179     pixelColor.add(c00);
00180 
00181     return numRays;
00182 }
00183 
00184 unsigned RTRender::_render_pixel_randomly(RayIntExplorer&   explorer,
00185                                           SceneGraphObject& scene,
00186                                           Shader&           shader,
00187                                           Camera&           camera,
00188                                           const Vector3&    centroid,
00189                                           unsigned          row,
00190                                           unsigned          col,
00191                                           unsigned          resX,
00192                                           unsigned          resY,
00193                                           Color3f&          pixelColor)
00194 {
00195     Color3f c;
00196     _render_pixel_point(explorer, scene, shader, centroid,
00197                         camera.getProjectionDirection(camera.mapPixelToProjPlane(col, row, resX, resY, Camera::PS_RANDOM)), c);
00198     pixelColor.add(c);
00199     return 1;
00200 }
00201 
00202 unsigned RTRender::_render_pixel_stratified(RayIntExplorer&   explorer,
00203                                             SceneGraphObject& scene,
00204                                             Shader&           shader,
00205                                             Camera&           camera,
00206                                             const Vector3d&   point,
00207                                             const Vector3d&   xDir,
00208                                             const Vector3d&   yDir,
00209                                             double            xDirLength,
00210                                             double            yDirLength,
00211                                             Color3f&          pixelColor)
00212 {
00213     Color3f color(0,0,0);
00214     Color3f c(0,0,0);
00215 
00216     if (_raysPerPixel <= 0) return 0;
00217 
00218     unsigned m  = (unsigned) sqrt((float)_raysPerPixel);
00219     double   xd = xDirLength / (double) m;
00220     double   yd = yDirLength / (double) m;
00221     
00222     for (unsigned i = 0; i < m; i++) {
00223         for (unsigned j = 0; j < m; j++) {
00224             Vector3d u(xDir);
00225             u.scale(i * xd + ESG_DBL_RAND * xd);
00226             Vector3d p(yDir);
00227             p.scale(j * yd + ESG_DBL_RAND * yd);
00228             p.add(u);
00229             p.add(point);
00230             _render_pixel_point(explorer, scene, shader, p,
00231                                 camera.getProjectionDirection(camera.project(p)),
00232                                 c);
00233             color.add(c);
00234         }
00235     }
00236 
00237     // Store averadge pixel color:
00238     if (m > 1) color.scale(1. / (double) (m * m));
00239     pixelColor.add(color);
00240 
00241     return m * m;
00242 }
00243 
00244 void RTRender::_render(Shader&      shader,
00245                        FrameBuffer& fb,
00246                        Camera&      camera,
00247                        Scene&       scene)
00248 {
00249     unsigned   resX = fb.getWidth();
00250     unsigned   resY = fb.getHeight();
00251     Color3f*   pixelColors;
00252     unsigned   pcIndex = 0;
00253     unsigned   pcX = 0;
00254     unsigned   pcY = resY - 1;
00255     int        raycounter = 0;
00256     Vector3    top_left, bottom_right;
00257     Vector3    down_vec, right_vec, dir, centroid, point;
00258     Vector2    step(camera.getPixelSize(resX, resY));
00259     float      xPixelSize, yPixelSize;
00260     Color3f*   cRow = NULL;
00261     Color3f    cCol;
00262 
00263     RayIntExplorer explorer(Vector3(0,0,0), Vector3(0,0,0), _pIntersector);
00264 
00265     if (!_pIntersector) return;
00266 
00267     camera.getProjectionPlane(down_vec, top_left, right_vec, bottom_right);
00268 
00269     //fprintf(stderr,"%f %f %f\n",down_vec.x,down_vec.y,down_vec.z);
00270     //fprintf(stderr,"%f %f %f\n",top_left.x,top_left.y,top_left.z);
00271 
00272     down_vec.sub(top_left);
00273     right_vec.sub(top_left);
00274     down_vec.normalize();
00275     right_vec.normalize();
00276     down_vec.scale(step.y);
00277     right_vec.scale(step.x);
00278 
00279     xPixelSize = right_vec.length();
00280     yPixelSize = down_vec.length();
00281 
00282     // set to the center of pixels
00283     if (_pixelRendering == CENTROID) {
00284         top_left.add(right_vec * .5);
00285         top_left.sub(down_vec * .5);
00286     }
00287 
00288     switch (_fbWriteMode) {
00289     case PER_LINE:
00290         pixelColors = new Color3f[resX * _fbWriteElements];
00291         break;
00292     case PER_PIXEL:
00293     default:
00294         pixelColors = new Color3f[_fbWriteElements];
00295         break;
00296     }
00297 
00298 #ifdef ESG_STATISTICS
00299     ((Stopwatch*)Statistics::instance()->get(Statistics::OID_RENDERING_TIME)->receptor())->start();
00300     ((Stopwatch*)Statistics::instance()->get(Statistics::OID_CPU_RENDERING_TIME)->receptor())->start();
00301 #endif // ESG_STATISTICS
00302 
00303     for (int i = (int) resY - 1; i >= 0; i--) {
00304         centroid.set(top_left); // get first pixel of actual scanline
00305 
00306         for (int j = 0; j < (int) resX; j++) {
00307             if (_pStopFlag != NULL && *_pStopFlag) return;
00308 
00309             pixelColors[pcIndex].set(0,0,0); // init to black
00310 
00311             /* compute intersection with primary ray(s) */
00312             switch (_pixelRendering) {
00313             case CENTROID:
00314                 raycounter += _render_pixel_centroid(explorer,
00315                                                      *(scene.root()),
00316                                                      shader,
00317                                                      camera,
00318                                                      centroid,
00319                                                      i, j,
00320                                                      resX, resY,
00321                                                      pixelColors[pcIndex]);
00322                 break;
00323             case CORNERS:
00324                 if (cRow == NULL) cRow = new Color3f [resX + 1];
00325                 raycounter += _render_pixel_corners(explorer, *(scene.root()),
00326                                                     shader, camera, centroid,
00327                                                     right_vec, down_vec,
00328                                                     i, j,
00329                                                     resX, resY,
00330                                                     cRow, cCol,
00331                                                     pixelColors[pcIndex]);
00332                 if (j == (int)(resX - 1)) cRow[j+1].set(cCol);
00333                 break;
00334             case RANDOM:
00335                 raycounter += _render_pixel_centroid(explorer,
00336                                                      *(scene.root()),
00337                                                      shader,
00338                                                      camera,
00339                                                      centroid,
00340                                                      i, j,
00341                                                      resX, resY,
00342                                                      pixelColors[pcIndex]);
00343 #if 0
00344                 raycounter += _render_pixel_randomly(explorer, *(scene.root()),
00345                                                      shader, camera, centroid,
00346                                                      right_vec, down_vec, 
00347                                                      xPixelSize, yPixelSize,
00348                                                      pixelColors[pcIndex]);
00349 #endif
00350                 break;
00351             case STRATIFIED_SAMPLING:
00352                 raycounter += _render_pixel_stratified(explorer,
00353                                                        *(scene.root()), shader,
00354                                                        camera, centroid,
00355                                                        right_vec, down_vec,
00356                                                        xPixelSize, yPixelSize,
00357                                                        pixelColors[pcIndex]);
00358                 break;
00359             case CENTROID_AND_CORNERS:
00360                 // to do
00361                 break;
00362             }
00363 
00364             //exit(0);
00365             //return;
00366 
00367             if (_fbWriteMode == PER_PIXEL && _fbWriteElements <= (pcIndex+1)) {
00368                 fb.setColor(camera, pcX, pcY, pixelColors[pcIndex]);
00369                 //fb.showContent();
00370                 //fb.setColors(camera, pcX, pcY, pixelColors, pcIndex+1);
00371                 pcIndex = 0;
00372                 pcX = (j + 1) % resX;
00373                 pcY = (pcX) ? i : i - 1;
00374             } else {
00375                 pcIndex++;
00376             }
00377             
00378             centroid.add(right_vec); // next pixel of actual scanline
00379         } // for all columns
00380 
00381         if (_fbWriteMode == PER_LINE) {
00382             if (_fbWriteElements <= (pcY - i + 1)) {
00383                 fb.setColors(camera, pcX, pcY, pixelColors, resX * (pcY-i+1));
00384                 //fb.showContent();
00385                 pcIndex = 0;
00386                 pcX = 0;
00387                 pcY = i - 1;
00388             } else {
00389                 pcIndex++;
00390             }
00391         }
00392         
00393         top_left.add(down_vec); // next scanline
00394     } // for all lines
00395 
00396     
00397 #ifdef ESG_STATISTICS
00398     ((Stopwatch*)Statistics::instance()->get(Statistics::OID_RENDERING_TIME)->receptor())->stop();
00399     ((Stopwatch*)Statistics::instance()->get(Statistics::OID_CPU_RENDERING_TIME)->receptor())->stop();
00400     ((Counter*)Statistics::instance()->get(Statistics::OID_PRIMARY_RAYS)->receptor())->set(raycounter);
00401 #endif // ESG_STATISTICS
00402 
00403 
00404     if (cRow) delete [] cRow;
00405     delete [] pixelColors;
00406 }
00407 
00408 
00409 
00410 
00411 
00412 

Generated on Tue Nov 21 15:11:42 2006 for gra by  doxygen 1.4.6