5 * Revision 1.5 2008/07/27 16:10:37 ehofman
8 * - remove the SG_GLxxxx_H #defines, since OSG provides its own versions
9 * - this exposed a bizarre issue on Mac where dragging in <AGL/agl.h> in
10 * extensions.hxx was pulling in all of Carbon to the global namespace
11 * - very scary. As a result, I now need to explicitly include CoreFoundation
13 * - change SG_USING_STD(x) to using std::x
17 * - the logic for X11 and Win32 in RenderTexture and extensions is tortured,
18 * please see if you agree I got all the ifdefs correct.
20 * Revision 1.4 2006/10/29 19:27:11 frohlich
22 * configure.ac simgear/environment/visual_enviro.cxx
23 * simgear/ephemeris/ephemeris.cxx
24 * simgear/ephemeris/ephemeris.hxx simgear/ephemeris/stardata.cxx
25 * simgear/ephemeris/stardata.hxx simgear/math/SGMatrix.hxx
26 * simgear/math/SGQuat.hxx simgear/math/SGVec3.hxx
27 * simgear/math/SGVec4.hxx simgear/scene/Makefile.am
28 * simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx
29 * simgear/scene/material/matlib.cxx
30 * simgear/scene/material/matlib.hxx
31 * simgear/scene/material/matmodel.cxx
32 * simgear/scene/material/matmodel.hxx
33 * simgear/scene/model/Makefile.am
34 * simgear/scene/model/animation.cxx
35 * simgear/scene/model/animation.hxx
36 * simgear/scene/model/custtrans.hxx
37 * simgear/scene/model/model.cxx simgear/scene/model/model.hxx
38 * simgear/scene/model/modellib.cxx
39 * simgear/scene/model/modellib.hxx
40 * simgear/scene/model/personality.cxx
41 * simgear/scene/model/personality.hxx
42 * simgear/scene/model/placement.cxx
43 * simgear/scene/model/placement.hxx
44 * simgear/scene/model/placementtrans.cxx
45 * simgear/scene/model/placementtrans.hxx
46 * simgear/scene/model/shadanim.cxx
47 * simgear/scene/model/shadowvolume.hxx
48 * simgear/scene/sky/cloud.cxx simgear/scene/sky/cloud.hxx
49 * simgear/scene/sky/cloudfield.cxx simgear/scene/sky/dome.cxx
50 * simgear/scene/sky/dome.hxx simgear/scene/sky/moon.cxx
51 * simgear/scene/sky/moon.hxx simgear/scene/sky/newcloud.cxx
52 * simgear/scene/sky/oursun.cxx simgear/scene/sky/oursun.hxx
53 * simgear/scene/sky/sky.cxx simgear/scene/sky/sky.hxx
54 * simgear/scene/sky/sphere.cxx simgear/scene/sky/sphere.hxx
55 * simgear/scene/sky/stars.cxx simgear/scene/sky/stars.hxx
56 * simgear/scene/tgdb/apt_signs.cxx
57 * simgear/scene/tgdb/apt_signs.hxx simgear/scene/tgdb/leaf.cxx
58 * simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/obj.cxx
59 * simgear/scene/tgdb/obj.hxx simgear/scene/tgdb/pt_lights.cxx
60 * simgear/scene/tgdb/pt_lights.hxx
61 * simgear/scene/tgdb/userdata.cxx
62 * simgear/scene/tgdb/userdata.hxx simgear/scene/tgdb/vasi.hxx
63 * simgear/screen/jpgfactory.cxx simgear/screen/tr.cxx
64 * simgear/structure/Makefile.am simgear/threads/SGThread.hxx
66 * simgear/scene/util/Makefile.am
67 * simgear/scene/util/SGDebugDrawCallback.hxx
68 * simgear/scene/util/SGNodeMasks.hxx
69 * simgear/scene/util/SGStateAttributeVisitor.hxx
70 * simgear/scene/util/SGTextureStateAttributeVisitor.hxx
71 * simgear/scene/util/SGUpdateVisitor.hxx
73 * simgear/screen/ssgEntityArray.cxx
74 * simgear/screen/ssgEntityArray.hxx
75 * simgear/structure/ssgSharedPtr.hxx
76 * Big BLOB on the way to OSG.
78 * Revision 1.3 2006-02-21 10:47:21 ehofman
79 * Back out the previous patch.
81 * Revision 1.2 2004/11/18 19:10:34 curt
82 * Abstract out location of gl.h, glut.h, and glu.h includes so that we can
83 * make the Mac platform happy since they put these in a different place compared
84 * to the rest of the world.
86 * Revision 1.1.1.1 2002/09/07 02:58:19 curt
87 * Initial revsion of Simgear-0.3.0
89 * Revision 1.3 2001/07/30 20:34:21 curt
92 * Revision 1.2 2001/06/27 02:48:01 curt
93 * Fixed a type conversion bug that could trip up some of the pickier compilers
96 * Revision 1.1 2001/06/26 15:19:39 curt
97 * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
98 * rendering ultra high res "tiled" screen shots.
100 * Revision 1.9 1998/01/29 16:56:54 brianp
101 * allow trOrtho() and trFrustum() to be called at any time, minor clean-up
103 * Revision 1.8 1998/01/28 19:47:39 brianp
104 * minor clean-up for C++
106 * Revision 1.7 1997/07/21 17:34:38 brianp
109 * Revision 1.6 1997/07/21 15:47:35 brianp
110 * renamed all "near" and "far" variables
112 * Revision 1.5 1997/04/26 21:23:25 brianp
113 * added trRasterPos3f function
115 * Revision 1.4 1997/04/26 19:59:36 brianp
116 * set CurrentTile to -1 before first tile and after last tile
118 * Revision 1.3 1997/04/22 23:51:15 brianp
119 * added WIN32 header stuff, removed tabs
121 * Revision 1.2 1997/04/19 23:26:10 brianp
124 * Revision 1.1 1997/04/18 21:53:05 brianp
131 * Tiled Rendering library
133 * Copyright (C) Brian Paul
137 #include <simgear/compiler.h>
147 #include <simgear/math/project.hxx>
152 #define DEFAULT_TILE_WIDTH 256
153 #define DEFAULT_TILE_HEIGHT 256
154 #define DEFAULT_TILE_BORDER 0
158 /* Final image parameters */
159 GLint ImageWidth, ImageHeight;
160 GLenum ImageFormat, ImageType;
163 /* Tile parameters */
164 GLint TileWidth, TileHeight;
165 GLint TileWidthNB, TileHeightNB;
167 GLenum TileFormat, TileType;
170 /* Projection parameters */
171 GLboolean Perspective;
183 GLint CurrentTileWidth, CurrentTileHeight;
184 GLint CurrentRow, CurrentColumn;
186 GLint ViewportSave[4];
192 * Misc setup including computing number of tiles (rows and columns).
194 static void Setup(TRcontext *tr)
199 tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
200 tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
203 assert(tr->Columns >= 0);
204 assert(tr->Rows >= 0);
209 TRcontext *trNew(void)
211 TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
213 tr->TileWidth = DEFAULT_TILE_WIDTH;
214 tr->TileHeight = DEFAULT_TILE_HEIGHT;
215 tr->TileBorder = DEFAULT_TILE_BORDER;
216 tr->RowOrder = TR_BOTTOM_TO_TOP;
217 tr->CurrentTile = -1;
219 return (TRcontext *) tr;
223 void trDelete(TRcontext *tr)
231 void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
239 assert(width >= 2*border);
240 assert(height >= 2*border);
242 tr->TileBorder = border;
243 tr->TileWidth = width;
244 tr->TileHeight = height;
245 tr->TileWidthNB = width - 2 * border;
246 tr->TileHeightNB = height - 2 * border;
252 void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
257 tr->TileFormat = format;
259 tr->TileBuffer = image;
264 void trImageSize(TRcontext *tr, GLint width, GLint height)
269 tr->ImageWidth = width;
270 tr->ImageHeight = height;
275 void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
280 tr->ImageFormat = format;
281 tr->ImageType = type;
282 tr->ImageBuffer = image;
286 GLint trGet(TRcontext *tr, TRenum param)
292 return tr->TileWidth;
294 return tr->TileHeight;
296 return tr->TileBorder;
298 return tr->ImageWidth;
299 case TR_IMAGE_HEIGHT:
300 return tr->ImageHeight;
306 if (tr->CurrentTile<0)
309 return tr->CurrentRow;
310 case TR_CURRENT_COLUMN:
311 if (tr->CurrentTile<0)
314 return tr->CurrentColumn;
315 case TR_CURRENT_TILE_WIDTH:
316 return tr->CurrentTileWidth;
317 case TR_CURRENT_TILE_HEIGHT:
318 return tr->CurrentTileHeight;
320 return (GLint) tr->RowOrder;
326 GLdouble trGetD(TRcontext *tr, TRenum param)
348 void trRowOrder(TRcontext *tr, TRenum order)
353 if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
354 tr->RowOrder = order;
358 void trOrtho(TRcontext *tr,
359 GLdouble left, GLdouble right,
360 GLdouble bottom, GLdouble top,
361 GLdouble zNear, GLdouble zFar)
366 tr->Perspective = GL_FALSE;
376 void trFrustum(TRcontext *tr,
377 GLdouble left, GLdouble right,
378 GLdouble bottom, GLdouble top,
379 GLdouble zNear, GLdouble zFar)
384 tr->Perspective = GL_TRUE;
394 void trPerspective(TRcontext *tr,
395 GLdouble fovy, GLdouble aspect,
396 GLdouble zNear, GLdouble zFar )
398 GLdouble xmin, xmax, ymin, ymax;
399 ymax = zNear * tan(fovy * 3.14159265 / 360.0);
401 xmin = ymin * aspect;
402 xmax = ymax * aspect;
403 trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
407 void trBeginTile(TRcontext *tr)
410 GLint tileWidth, tileHeight, border;
411 GLdouble left, right, bottom, top;
416 if (tr->CurrentTile <= 0) {
418 /* Save user's viewport, will be restored after last tile rendered */
419 glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
422 /* which tile (by row and column) we're about to render */
423 if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
424 tr->CurrentRow = tr->CurrentTile / tr->Columns;
425 tr->CurrentColumn = tr->CurrentTile % tr->Columns;
427 else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
428 tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
429 tr->CurrentColumn = tr->CurrentTile % tr->Columns;
432 /* This should never happen */
435 assert(tr->CurrentRow < tr->Rows);
436 assert(tr->CurrentColumn < tr->Columns);
438 border = tr->TileBorder;
440 /* Compute actual size of this tile with border */
441 if (tr->CurrentRow < tr->Rows-1)
442 tileHeight = tr->TileHeight;
444 tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
446 if (tr->CurrentColumn < tr->Columns-1)
447 tileWidth = tr->TileWidth;
449 tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
451 /* Save tile size, with border */
452 tr->CurrentTileWidth = tileWidth;
453 tr->CurrentTileHeight = tileHeight;
455 glViewport(0, 0, tileWidth, tileHeight); /* tile size including border */
457 /* save current matrix mode */
458 glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
459 glMatrixMode(GL_PROJECTION);
462 /* compute projection parameters */
463 left = tr->Left + (tr->Right - tr->Left)
464 * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
465 right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
466 bottom = tr->Bottom + (tr->Top - tr->Bottom)
467 * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
468 top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
471 // ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
473 /* restore user's matrix mode */
474 glMatrixMode( (GLenum)matrixMode );
479 int trEndTile(TRcontext *tr)
481 GLint prevRowLength, prevSkipRows, prevSkipPixels /*, prevAlignment */;
486 assert(tr->CurrentTile>=0);
488 /* be sure OpenGL rendering is finished */
491 /* save current glPixelStore values */
492 glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
493 glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
494 glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
495 /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
497 if (tr->TileBuffer) {
498 GLint srcX = tr->TileBorder;
499 GLint srcY = tr->TileBorder;
500 GLint srcWidth = tr->TileWidthNB;
501 GLint srcHeight = tr->TileHeightNB;
502 glReadPixels(srcX, srcY, srcWidth, srcHeight,
503 tr->TileFormat, tr->TileType, tr->TileBuffer);
506 if (tr->ImageBuffer) {
507 GLint srcX = tr->TileBorder;
508 GLint srcY = tr->TileBorder;
509 GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
510 GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
511 GLint destX = tr->TileWidthNB * tr->CurrentColumn;
512 GLint destY = tr->TileHeightNB * tr->CurrentRow;
514 /* setup pixel store for glReadPixels */
515 glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
516 glPixelStorei(GL_PACK_SKIP_ROWS, destY);
517 glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
518 /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
520 /* read the tile into the final image */
521 glReadPixels(srcX, srcY, srcWidth, srcHeight,
522 tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
525 /* restore previous glPixelStore values */
526 glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
527 glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
528 glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
529 /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
531 /* increment tile counter, return 1 if more tiles left to render */
533 if (tr->CurrentTile >= tr->Rows * tr->Columns) {
534 /* restore user's viewport */
535 glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
536 tr->ViewportSave[2], tr->ViewportSave[3]);
537 tr->CurrentTile = -1; /* all done */
545 * Replacement for glRastePos3f() which avoids the problem with invalid
548 void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
550 if (tr->CurrentTile<0) {
551 /* not doing tile rendering right now. Let OpenGL do this. */
552 glRasterPos3f(x, y, z);
555 GLdouble modelview[16], proj[16];
557 GLdouble winX, winY, winZ;
559 /* Get modelview, projection and viewport */
560 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
561 glGetDoublev(GL_PROJECTION_MATRIX, proj);
564 viewport[2] = tr->CurrentTileWidth;
565 viewport[3] = tr->CurrentTileHeight;
567 /* Project object coord to window coordinate */
568 if (simgear::project(x, y, z, modelview, proj, viewport,
569 &winX, &winY, &winZ)){
571 /* set raster pos to window coord (0,0) */
572 glMatrixMode(GL_MODELVIEW);
575 glMatrixMode(GL_PROJECTION);
578 glOrtho(0.0, tr->CurrentTileWidth,
579 0.0, tr->CurrentTileHeight, 0.0, 1.0);
580 glRasterPos3f(0.0, 0.0, -winZ);
582 /* Now use empty bitmap to adjust raster position to (winX,winY) */
584 GLubyte bitmap[1] = {0};
585 glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap);
588 /* restore original matrices */
589 glPopMatrix(); /*proj*/
590 glMatrixMode(GL_MODELVIEW);
595 printf("GL error!\n");