00001 /* $Id: tr_8cxx_source.html,v 1.3 2010/02/23 22:10:17 curt Exp $ */ 00002 00003 /* 00004 * $Log: tr_8cxx_source.html,v $ 00004 * Revision 1.3 2010/02/23 22:10:17 curt 00004 * Another v2.0.0 commit. 00004 * 00005 * Revision 1.5 2008/07/27 16:10:37 ehofman 00006 * 00007 * 00008 * - remove the SG_GLxxxx_H #defines, since OSG provides its own versions 00009 * - this exposed a bizarre issue on Mac where dragging in <AGL/agl.h> in 00010 * extensions.hxx was pulling in all of Carbon to the global namespace 00011 * - very scary. As a result, I now need to explicitly include CoreFoundation 00012 * in fg_init.cxx. 00013 * - change SG_USING_STD(x) to using std::x 00014 * 00015 * Issues: 00016 * 00017 * - the logic for X11 and Win32 in RenderTexture and extensions is tortured, 00018 * please see if you agree I got all the ifdefs correct. 00019 * 00020 * Revision 1.4 2006/10/29 19:27:11 frohlich 00021 * Modified Files: 00022 * configure.ac simgear/environment/visual_enviro.cxx 00023 * simgear/ephemeris/ephemeris.cxx 00024 * simgear/ephemeris/ephemeris.hxx simgear/ephemeris/stardata.cxx 00025 * simgear/ephemeris/stardata.hxx simgear/math/SGMatrix.hxx 00026 * simgear/math/SGQuat.hxx simgear/math/SGVec3.hxx 00027 * simgear/math/SGVec4.hxx simgear/scene/Makefile.am 00028 * simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx 00029 * simgear/scene/material/matlib.cxx 00030 * simgear/scene/material/matlib.hxx 00031 * simgear/scene/material/matmodel.cxx 00032 * simgear/scene/material/matmodel.hxx 00033 * simgear/scene/model/Makefile.am 00034 * simgear/scene/model/animation.cxx 00035 * simgear/scene/model/animation.hxx 00036 * simgear/scene/model/custtrans.hxx 00037 * simgear/scene/model/model.cxx simgear/scene/model/model.hxx 00038 * simgear/scene/model/modellib.cxx 00039 * simgear/scene/model/modellib.hxx 00040 * simgear/scene/model/personality.cxx 00041 * simgear/scene/model/personality.hxx 00042 * simgear/scene/model/placement.cxx 00043 * simgear/scene/model/placement.hxx 00044 * simgear/scene/model/placementtrans.cxx 00045 * simgear/scene/model/placementtrans.hxx 00046 * simgear/scene/model/shadanim.cxx 00047 * simgear/scene/model/shadowvolume.hxx 00048 * simgear/scene/sky/cloud.cxx simgear/scene/sky/cloud.hxx 00049 * simgear/scene/sky/cloudfield.cxx simgear/scene/sky/dome.cxx 00050 * simgear/scene/sky/dome.hxx simgear/scene/sky/moon.cxx 00051 * simgear/scene/sky/moon.hxx simgear/scene/sky/newcloud.cxx 00052 * simgear/scene/sky/oursun.cxx simgear/scene/sky/oursun.hxx 00053 * simgear/scene/sky/sky.cxx simgear/scene/sky/sky.hxx 00054 * simgear/scene/sky/sphere.cxx simgear/scene/sky/sphere.hxx 00055 * simgear/scene/sky/stars.cxx simgear/scene/sky/stars.hxx 00056 * simgear/scene/tgdb/apt_signs.cxx 00057 * simgear/scene/tgdb/apt_signs.hxx simgear/scene/tgdb/leaf.cxx 00058 * simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/obj.cxx 00059 * simgear/scene/tgdb/obj.hxx simgear/scene/tgdb/pt_lights.cxx 00060 * simgear/scene/tgdb/pt_lights.hxx 00061 * simgear/scene/tgdb/userdata.cxx 00062 * simgear/scene/tgdb/userdata.hxx simgear/scene/tgdb/vasi.hxx 00063 * simgear/screen/jpgfactory.cxx simgear/screen/tr.cxx 00064 * simgear/structure/Makefile.am simgear/threads/SGThread.hxx 00065 * Added Files: 00066 * simgear/scene/util/Makefile.am 00067 * simgear/scene/util/SGDebugDrawCallback.hxx 00068 * simgear/scene/util/SGNodeMasks.hxx 00069 * simgear/scene/util/SGStateAttributeVisitor.hxx 00070 * simgear/scene/util/SGTextureStateAttributeVisitor.hxx 00071 * simgear/scene/util/SGUpdateVisitor.hxx 00072 * Removed Files: 00073 * simgear/screen/ssgEntityArray.cxx 00074 * simgear/screen/ssgEntityArray.hxx 00075 * simgear/structure/ssgSharedPtr.hxx 00076 * Big BLOB on the way to OSG. 00077 * 00078 * Revision 1.3 2006-02-21 10:47:21 ehofman 00079 * Back out the previous patch. 00080 * 00081 * Revision 1.2 2004/11/18 19:10:34 curt 00082 * Abstract out location of gl.h, glut.h, and glu.h includes so that we can 00083 * make the Mac platform happy since they put these in a different place compared 00084 * to the rest of the world. 00085 * 00086 * Revision 1.1.1.1 2002/09/07 02:58:19 curt 00087 * Initial revsion of Simgear-0.3.0 00088 * 00089 * Revision 1.3 2001/07/30 20:34:21 curt 00090 * Various MSVC fixes. 00091 * 00092 * Revision 1.2 2001/06/27 02:48:01 curt 00093 * Fixed a type conversion bug that could trip up some of the pickier compilers 00094 * out there. 00095 * 00096 * Revision 1.1 2001/06/26 15:19:39 curt 00097 * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for 00098 * rendering ultra high res "tiled" screen shots. 00099 * 00100 * Revision 1.9 1998/01/29 16:56:54 brianp 00101 * allow trOrtho() and trFrustum() to be called at any time, minor clean-up 00102 * 00103 * Revision 1.8 1998/01/28 19:47:39 brianp 00104 * minor clean-up for C++ 00105 * 00106 * Revision 1.7 1997/07/21 17:34:38 brianp 00107 * added tile borders 00108 * 00109 * Revision 1.6 1997/07/21 15:47:35 brianp 00110 * renamed all "near" and "far" variables 00111 * 00112 * Revision 1.5 1997/04/26 21:23:25 brianp 00113 * added trRasterPos3f function 00114 * 00115 * Revision 1.4 1997/04/26 19:59:36 brianp 00116 * set CurrentTile to -1 before first tile and after last tile 00117 * 00118 * Revision 1.3 1997/04/22 23:51:15 brianp 00119 * added WIN32 header stuff, removed tabs 00120 * 00121 * Revision 1.2 1997/04/19 23:26:10 brianp 00122 * many API changes 00123 * 00124 * Revision 1.1 1997/04/18 21:53:05 brianp 00125 * Initial revision 00126 * 00127 */ 00128 00129 00130 /* 00131 * Tiled Rendering library 00132 * Version 1.1 00133 * Copyright (C) Brian Paul 00134 */ 00135 00136 00137 #include <simgear/compiler.h> 00138 00139 #include <assert.h> 00140 #include <math.h> 00141 #include <stdlib.h> 00142 #include <stdio.h> 00143 #ifdef WIN32 00144 #include <windows.h> 00145 #endif 00146 00147 #include <osg/GLU> 00148 00149 #include "tr.h" 00150 00151 00152 #define DEFAULT_TILE_WIDTH 256 00153 #define DEFAULT_TILE_HEIGHT 256 00154 #define DEFAULT_TILE_BORDER 0 00155 00156 00157 struct _TRctx { 00158 /* Final image parameters */ 00159 GLint ImageWidth, ImageHeight; 00160 GLenum ImageFormat, ImageType; 00161 GLvoid *ImageBuffer; 00162 00163 /* Tile parameters */ 00164 GLint TileWidth, TileHeight; 00165 GLint TileWidthNB, TileHeightNB; 00166 GLint TileBorder; 00167 GLenum TileFormat, TileType; 00168 GLvoid *TileBuffer; 00169 00170 /* Projection parameters */ 00171 GLboolean Perspective; 00172 GLdouble Left; 00173 GLdouble Right; 00174 GLdouble Bottom; 00175 GLdouble Top; 00176 GLdouble Near; 00177 GLdouble Far; 00178 00179 /* Misc */ 00180 TRenum RowOrder; 00181 GLint Rows, Columns; 00182 GLint CurrentTile; 00183 GLint CurrentTileWidth, CurrentTileHeight; 00184 GLint CurrentRow, CurrentColumn; 00185 00186 GLint ViewportSave[4]; 00187 }; 00188 00189 00190 00191 /* 00192 * Misc setup including computing number of tiles (rows and columns). 00193 */ 00194 static void Setup(TRcontext *tr) 00195 { 00196 if (!tr) 00197 return; 00198 00199 tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB; 00200 tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB; 00201 tr->CurrentTile = 0; 00202 00203 assert(tr->Columns >= 0); 00204 assert(tr->Rows >= 0); 00205 } 00206 00207 00208 00209 TRcontext *trNew(void) 00210 { 00211 TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext)); 00212 if (tr) { 00213 tr->TileWidth = DEFAULT_TILE_WIDTH; 00214 tr->TileHeight = DEFAULT_TILE_HEIGHT; 00215 tr->TileBorder = DEFAULT_TILE_BORDER; 00216 tr->RowOrder = TR_BOTTOM_TO_TOP; 00217 tr->CurrentTile = -1; 00218 } 00219 return (TRcontext *) tr; 00220 } 00221 00222 00223 void trDelete(TRcontext *tr) 00224 { 00225 if (tr) 00226 free(tr); 00227 } 00228 00229 00230 00231 void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border) 00232 { 00233 if (!tr) 00234 return; 00235 00236 assert(border >= 0); 00237 assert(width >= 1); 00238 assert(height >= 1); 00239 assert(width >= 2*border); 00240 assert(height >= 2*border); 00241 00242 tr->TileBorder = border; 00243 tr->TileWidth = width; 00244 tr->TileHeight = height; 00245 tr->TileWidthNB = width - 2 * border; 00246 tr->TileHeightNB = height - 2 * border; 00247 Setup(tr); 00248 } 00249 00250 00251 00252 void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image) 00253 { 00254 if (!tr) 00255 return; 00256 00257 tr->TileFormat = format; 00258 tr->TileType = type; 00259 tr->TileBuffer = image; 00260 } 00261 00262 00263 00264 void trImageSize(TRcontext *tr, GLint width, GLint height) 00265 { 00266 if (!tr) 00267 return; 00268 00269 tr->ImageWidth = width; 00270 tr->ImageHeight = height; 00271 Setup(tr); 00272 } 00273 00274 00275 void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image) 00276 { 00277 if (!tr) 00278 return; 00279 00280 tr->ImageFormat = format; 00281 tr->ImageType = type; 00282 tr->ImageBuffer = image; 00283 } 00284 00285 00286 GLint trGet(TRcontext *tr, TRenum param) 00287 { 00288 if (!tr) 00289 return 0; 00290 switch (param) { 00291 case TR_TILE_WIDTH: 00292 return tr->TileWidth; 00293 case TR_TILE_HEIGHT: 00294 return tr->TileHeight; 00295 case TR_TILE_BORDER: 00296 return tr->TileBorder; 00297 case TR_IMAGE_WIDTH: 00298 return tr->ImageWidth; 00299 case TR_IMAGE_HEIGHT: 00300 return tr->ImageHeight; 00301 case TR_ROWS: 00302 return tr->Rows; 00303 case TR_COLUMNS: 00304 return tr->Columns; 00305 case TR_CURRENT_ROW: 00306 if (tr->CurrentTile<0) 00307 return -1; 00308 else 00309 return tr->CurrentRow; 00310 case TR_CURRENT_COLUMN: 00311 if (tr->CurrentTile<0) 00312 return -1; 00313 else 00314 return tr->CurrentColumn; 00315 case TR_CURRENT_TILE_WIDTH: 00316 return tr->CurrentTileWidth; 00317 case TR_CURRENT_TILE_HEIGHT: 00318 return tr->CurrentTileHeight; 00319 case TR_ROW_ORDER: 00320 return (GLint) tr->RowOrder; 00321 default: 00322 return 0; 00323 } 00324 } 00325 00326 GLdouble trGetD(TRcontext *tr, TRenum param) 00327 { 00328 if (!tr) 00329 return 0.0; 00330 switch (param) { 00331 case TR_LEFT: 00332 return tr->Left; 00333 case TR_RIGHT: 00334 return tr->Right; 00335 case TR_BOTTOM: 00336 return tr->Bottom; 00337 case TR_TOP: 00338 return tr->Top; 00339 case TR_NEAR: 00340 return tr->Near; 00341 case TR_FAR: 00342 return tr->Far; 00343 default: 00344 return 0.0; 00345 } 00346 } 00347 00348 void trRowOrder(TRcontext *tr, TRenum order) 00349 { 00350 if (!tr) 00351 return; 00352 00353 if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP) 00354 tr->RowOrder = order; 00355 } 00356 00357 00358 void trOrtho(TRcontext *tr, 00359 GLdouble left, GLdouble right, 00360 GLdouble bottom, GLdouble top, 00361 GLdouble zNear, GLdouble zFar) 00362 { 00363 if (!tr) 00364 return; 00365 00366 tr->Perspective = GL_FALSE; 00367 tr->Left = left; 00368 tr->Right = right; 00369 tr->Bottom = bottom; 00370 tr->Top = top; 00371 tr->Near = zNear; 00372 tr->Far = zFar; 00373 } 00374 00375 00376 void trFrustum(TRcontext *tr, 00377 GLdouble left, GLdouble right, 00378 GLdouble bottom, GLdouble top, 00379 GLdouble zNear, GLdouble zFar) 00380 { 00381 if (!tr) 00382 return; 00383 00384 tr->Perspective = GL_TRUE; 00385 tr->Left = left; 00386 tr->Right = right; 00387 tr->Bottom = bottom; 00388 tr->Top = top; 00389 tr->Near = zNear; 00390 tr->Far = zFar; 00391 } 00392 00393 00394 void trPerspective(TRcontext *tr, 00395 GLdouble fovy, GLdouble aspect, 00396 GLdouble zNear, GLdouble zFar ) 00397 { 00398 GLdouble xmin, xmax, ymin, ymax; 00399 ymax = zNear * tan(fovy * 3.14159265 / 360.0); 00400 ymin = -ymax; 00401 xmin = ymin * aspect; 00402 xmax = ymax * aspect; 00403 trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar); 00404 } 00405 00406 00407 void trBeginTile(TRcontext *tr) 00408 { 00409 GLint matrixMode; 00410 GLint tileWidth, tileHeight, border; 00411 GLdouble left, right, bottom, top; 00412 00413 if (!tr) 00414 return; 00415 00416 if (tr->CurrentTile <= 0) { 00417 Setup(tr); 00418 /* Save user's viewport, will be restored after last tile rendered */ 00419 glGetIntegerv(GL_VIEWPORT, tr->ViewportSave); 00420 } 00421 00422 /* which tile (by row and column) we're about to render */ 00423 if (tr->RowOrder==TR_BOTTOM_TO_TOP) { 00424 tr->CurrentRow = tr->CurrentTile / tr->Columns; 00425 tr->CurrentColumn = tr->CurrentTile % tr->Columns; 00426 } 00427 else if (tr->RowOrder==TR_TOP_TO_BOTTOM) { 00428 tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1; 00429 tr->CurrentColumn = tr->CurrentTile % tr->Columns; 00430 } 00431 else { 00432 /* This should never happen */ 00433 abort(); 00434 } 00435 assert(tr->CurrentRow < tr->Rows); 00436 assert(tr->CurrentColumn < tr->Columns); 00437 00438 border = tr->TileBorder; 00439 00440 /* Compute actual size of this tile with border */ 00441 if (tr->CurrentRow < tr->Rows-1) 00442 tileHeight = tr->TileHeight; 00443 else 00444 tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border; 00445 00446 if (tr->CurrentColumn < tr->Columns-1) 00447 tileWidth = tr->TileWidth; 00448 else 00449 tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border; 00450 00451 /* Save tile size, with border */ 00452 tr->CurrentTileWidth = tileWidth; 00453 tr->CurrentTileHeight = tileHeight; 00454 00455 glViewport(0, 0, tileWidth, tileHeight); /* tile size including border */ 00456 00457 /* save current matrix mode */ 00458 glGetIntegerv(GL_MATRIX_MODE, &matrixMode); 00459 glMatrixMode(GL_PROJECTION); 00460 glLoadIdentity(); 00461 00462 /* compute projection parameters */ 00463 left = tr->Left + (tr->Right - tr->Left) 00464 * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth; 00465 right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth; 00466 bottom = tr->Bottom + (tr->Top - tr->Bottom) 00467 * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight; 00468 top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight; 00469 00470 // OSGFIXME 00471 // ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far ); 00472 00473 /* restore user's matrix mode */ 00474 glMatrixMode( (GLenum)matrixMode ); 00475 } 00476 00477 00478 00479 int trEndTile(TRcontext *tr) 00480 { 00481 GLint prevRowLength, prevSkipRows, prevSkipPixels /*, prevAlignment */; 00482 00483 if (!tr) 00484 return 0; 00485 00486 assert(tr->CurrentTile>=0); 00487 00488 /* be sure OpenGL rendering is finished */ 00489 glFlush(); 00490 00491 /* save current glPixelStore values */ 00492 glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength); 00493 glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows); 00494 glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels); 00495 /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/ 00496 00497 if (tr->TileBuffer) { 00498 GLint srcX = tr->TileBorder; 00499 GLint srcY = tr->TileBorder; 00500 GLint srcWidth = tr->TileWidthNB; 00501 GLint srcHeight = tr->TileHeightNB; 00502 glReadPixels(srcX, srcY, srcWidth, srcHeight, 00503 tr->TileFormat, tr->TileType, tr->TileBuffer); 00504 } 00505 00506 if (tr->ImageBuffer) { 00507 GLint srcX = tr->TileBorder; 00508 GLint srcY = tr->TileBorder; 00509 GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder; 00510 GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder; 00511 GLint destX = tr->TileWidthNB * tr->CurrentColumn; 00512 GLint destY = tr->TileHeightNB * tr->CurrentRow; 00513 00514 /* setup pixel store for glReadPixels */ 00515 glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth); 00516 glPixelStorei(GL_PACK_SKIP_ROWS, destY); 00517 glPixelStorei(GL_PACK_SKIP_PIXELS, destX); 00518 /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/ 00519 00520 /* read the tile into the final image */ 00521 glReadPixels(srcX, srcY, srcWidth, srcHeight, 00522 tr->ImageFormat, tr->ImageType, tr->ImageBuffer); 00523 } 00524 00525 /* restore previous glPixelStore values */ 00526 glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength); 00527 glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows); 00528 glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels); 00529 /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/ 00530 00531 /* increment tile counter, return 1 if more tiles left to render */ 00532 tr->CurrentTile++; 00533 if (tr->CurrentTile >= tr->Rows * tr->Columns) { 00534 /* restore user's viewport */ 00535 glViewport(tr->ViewportSave[0], tr->ViewportSave[1], 00536 tr->ViewportSave[2], tr->ViewportSave[3]); 00537 tr->CurrentTile = -1; /* all done */ 00538 return 0; 00539 } 00540 else 00541 return 1; 00542 } 00543 00544 00545 /* 00546 * Replacement for glRastePos3f() which avoids the problem with invalid 00547 * raster pos. 00548 */ 00549 void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z) 00550 { 00551 if (tr->CurrentTile<0) { 00552 /* not doing tile rendering right now. Let OpenGL do this. */ 00553 glRasterPos3f(x, y, z); 00554 } 00555 else { 00556 GLdouble modelview[16], proj[16]; 00557 GLint viewport[4]; 00558 GLdouble winX, winY, winZ; 00559 00560 /* Get modelview, projection and viewport */ 00561 glGetDoublev(GL_MODELVIEW_MATRIX, modelview); 00562 glGetDoublev(GL_PROJECTION_MATRIX, proj); 00563 viewport[0] = 0; 00564 viewport[1] = 0; 00565 viewport[2] = tr->CurrentTileWidth; 00566 viewport[3] = tr->CurrentTileHeight; 00567 00568 /* Project object coord to window coordinate */ 00569 if (gluProject(x, y, z, modelview, proj, viewport, &winX, &winY, &winZ)){ 00570 00571 /* set raster pos to window coord (0,0) */ 00572 glMatrixMode(GL_MODELVIEW); 00573 glPushMatrix(); 00574 glLoadIdentity(); 00575 glMatrixMode(GL_PROJECTION); 00576 glPushMatrix(); 00577 glLoadIdentity(); 00578 glOrtho(0.0, tr->CurrentTileWidth, 00579 0.0, tr->CurrentTileHeight, 0.0, 1.0); 00580 glRasterPos3f(0.0, 0.0, -winZ); 00581 00582 /* Now use empty bitmap to adjust raster position to (winX,winY) */ 00583 { 00584 GLubyte bitmap[1] = {0}; 00585 glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap); 00586 } 00587 00588 /* restore original matrices */ 00589 glPopMatrix(); /*proj*/ 00590 glMatrixMode(GL_MODELVIEW); 00591 glPopMatrix(); 00592 } 00593 #ifdef DEBUG 00594 if (glGetError()) 00595 printf("GL error!\n"); 00596 #endif 00597 } 00598 } 00599