5 * Revision 1.3 2006/02/21 10:47:21 ehofman
6 * Back out the previous patch.
8 * Revision 1.2 2004/11/18 19:10:34 curt
9 * Abstract out location of gl.h, glut.h, and glu.h includes so that we can
10 * make the Mac platform happy since they put these in a different place compared
11 * to the rest of the world.
13 * Revision 1.1.1.1 2002/09/07 02:58:19 curt
14 * Initial revsion of Simgear-0.3.0
16 * Revision 1.3 2001/07/30 20:34:21 curt
19 * Revision 1.2 2001/06/27 02:48:01 curt
20 * Fixed a type conversion bug that could trip up some of the pickier compilers
23 * Revision 1.1 2001/06/26 15:19:39 curt
24 * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
25 * rendering ultra high res "tiled" screen shots.
27 * Revision 1.9 1998/01/29 16:56:54 brianp
28 * allow trOrtho() and trFrustum() to be called at any time, minor clean-up
30 * Revision 1.8 1998/01/28 19:47:39 brianp
31 * minor clean-up for C++
33 * Revision 1.7 1997/07/21 17:34:38 brianp
36 * Revision 1.6 1997/07/21 15:47:35 brianp
37 * renamed all "near" and "far" variables
39 * Revision 1.5 1997/04/26 21:23:25 brianp
40 * added trRasterPos3f function
42 * Revision 1.4 1997/04/26 19:59:36 brianp
43 * set CurrentTile to -1 before first tile and after last tile
45 * Revision 1.3 1997/04/22 23:51:15 brianp
46 * added WIN32 header stuff, removed tabs
48 * Revision 1.2 1997/04/19 23:26:10 brianp
51 * Revision 1.1 1997/04/18 21:53:05 brianp
58 * Tiled Rendering library
60 * Copyright (C) Brian Paul
64 #include <simgear/compiler.h>
80 #define DEFAULT_TILE_WIDTH 256
81 #define DEFAULT_TILE_HEIGHT 256
82 #define DEFAULT_TILE_BORDER 0
86 /* Final image parameters */
87 GLint ImageWidth, ImageHeight;
88 GLenum ImageFormat, ImageType;
92 GLint TileWidth, TileHeight;
93 GLint TileWidthNB, TileHeightNB;
95 GLenum TileFormat, TileType;
98 /* Projection parameters */
99 GLboolean Perspective;
111 GLint CurrentTileWidth, CurrentTileHeight;
112 GLint CurrentRow, CurrentColumn;
114 GLint ViewportSave[4];
120 * Misc setup including computing number of tiles (rows and columns).
122 static void Setup(TRcontext *tr)
127 tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
128 tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
131 assert(tr->Columns >= 0);
132 assert(tr->Rows >= 0);
137 TRcontext *trNew(void)
139 TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
141 tr->TileWidth = DEFAULT_TILE_WIDTH;
142 tr->TileHeight = DEFAULT_TILE_HEIGHT;
143 tr->TileBorder = DEFAULT_TILE_BORDER;
144 tr->RowOrder = TR_BOTTOM_TO_TOP;
145 tr->CurrentTile = -1;
147 return (TRcontext *) tr;
151 void trDelete(TRcontext *tr)
159 void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
167 assert(width >= 2*border);
168 assert(height >= 2*border);
170 tr->TileBorder = border;
171 tr->TileWidth = width;
172 tr->TileHeight = height;
173 tr->TileWidthNB = width - 2 * border;
174 tr->TileHeightNB = height - 2 * border;
180 void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
185 tr->TileFormat = format;
187 tr->TileBuffer = image;
192 void trImageSize(TRcontext *tr, GLint width, GLint height)
197 tr->ImageWidth = width;
198 tr->ImageHeight = height;
203 void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
208 tr->ImageFormat = format;
209 tr->ImageType = type;
210 tr->ImageBuffer = image;
214 GLint trGet(TRcontext *tr, TRenum param)
220 return tr->TileWidth;
222 return tr->TileHeight;
224 return tr->TileBorder;
226 return tr->ImageWidth;
227 case TR_IMAGE_HEIGHT:
228 return tr->ImageHeight;
234 if (tr->CurrentTile<0)
237 return tr->CurrentRow;
238 case TR_CURRENT_COLUMN:
239 if (tr->CurrentTile<0)
242 return tr->CurrentColumn;
243 case TR_CURRENT_TILE_WIDTH:
244 return tr->CurrentTileWidth;
245 case TR_CURRENT_TILE_HEIGHT:
246 return tr->CurrentTileHeight;
248 return (GLint) tr->RowOrder;
254 GLdouble trGetD(TRcontext *tr, TRenum param)
276 void trRowOrder(TRcontext *tr, TRenum order)
281 if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
282 tr->RowOrder = order;
286 void trOrtho(TRcontext *tr,
287 GLdouble left, GLdouble right,
288 GLdouble bottom, GLdouble top,
289 GLdouble zNear, GLdouble zFar)
294 tr->Perspective = GL_FALSE;
304 void trFrustum(TRcontext *tr,
305 GLdouble left, GLdouble right,
306 GLdouble bottom, GLdouble top,
307 GLdouble zNear, GLdouble zFar)
312 tr->Perspective = GL_TRUE;
322 void trPerspective(TRcontext *tr,
323 GLdouble fovy, GLdouble aspect,
324 GLdouble zNear, GLdouble zFar )
326 GLdouble xmin, xmax, ymin, ymax;
327 ymax = zNear * tan(fovy * 3.14159265 / 360.0);
329 xmin = ymin * aspect;
330 xmax = ymax * aspect;
331 trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
335 void trBeginTile(TRcontext *tr)
338 GLint tileWidth, tileHeight, border;
339 GLdouble left, right, bottom, top;
344 if (tr->CurrentTile <= 0) {
346 /* Save user's viewport, will be restored after last tile rendered */
347 glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
350 /* which tile (by row and column) we're about to render */
351 if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
352 tr->CurrentRow = tr->CurrentTile / tr->Columns;
353 tr->CurrentColumn = tr->CurrentTile % tr->Columns;
355 else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
356 tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
357 tr->CurrentColumn = tr->CurrentTile % tr->Columns;
360 /* This should never happen */
363 assert(tr->CurrentRow < tr->Rows);
364 assert(tr->CurrentColumn < tr->Columns);
366 border = tr->TileBorder;
368 /* Compute actual size of this tile with border */
369 if (tr->CurrentRow < tr->Rows-1)
370 tileHeight = tr->TileHeight;
372 tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
374 if (tr->CurrentColumn < tr->Columns-1)
375 tileWidth = tr->TileWidth;
377 tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
379 /* Save tile size, with border */
380 tr->CurrentTileWidth = tileWidth;
381 tr->CurrentTileHeight = tileHeight;
383 glViewport(0, 0, tileWidth, tileHeight); /* tile size including border */
385 /* save current matrix mode */
386 glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
387 glMatrixMode(GL_PROJECTION);
390 /* compute projection parameters */
391 left = tr->Left + (tr->Right - tr->Left)
392 * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
393 right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
394 bottom = tr->Bottom + (tr->Top - tr->Bottom)
395 * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
396 top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
398 ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
400 /* restore user's matrix mode */
401 glMatrixMode( (GLenum)matrixMode );
406 int trEndTile(TRcontext *tr)
408 GLint prevRowLength, prevSkipRows, prevSkipPixels /*, prevAlignment */;
413 assert(tr->CurrentTile>=0);
415 /* be sure OpenGL rendering is finished */
418 /* save current glPixelStore values */
419 glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
420 glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
421 glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
422 /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
424 if (tr->TileBuffer) {
425 GLint srcX = tr->TileBorder;
426 GLint srcY = tr->TileBorder;
427 GLint srcWidth = tr->TileWidthNB;
428 GLint srcHeight = tr->TileHeightNB;
429 glReadPixels(srcX, srcY, srcWidth, srcHeight,
430 tr->TileFormat, tr->TileType, tr->TileBuffer);
433 if (tr->ImageBuffer) {
434 GLint srcX = tr->TileBorder;
435 GLint srcY = tr->TileBorder;
436 GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
437 GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
438 GLint destX = tr->TileWidthNB * tr->CurrentColumn;
439 GLint destY = tr->TileHeightNB * tr->CurrentRow;
441 /* setup pixel store for glReadPixels */
442 glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
443 glPixelStorei(GL_PACK_SKIP_ROWS, destY);
444 glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
445 /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
447 /* read the tile into the final image */
448 glReadPixels(srcX, srcY, srcWidth, srcHeight,
449 tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
452 /* restore previous glPixelStore values */
453 glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
454 glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
455 glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
456 /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
458 /* increment tile counter, return 1 if more tiles left to render */
460 if (tr->CurrentTile >= tr->Rows * tr->Columns) {
461 /* restore user's viewport */
462 glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
463 tr->ViewportSave[2], tr->ViewportSave[3]);
464 tr->CurrentTile = -1; /* all done */
473 * Replacement for glRastePos3f() which avoids the problem with invalid
476 void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
478 if (tr->CurrentTile<0) {
479 /* not doing tile rendering right now. Let OpenGL do this. */
480 glRasterPos3f(x, y, z);
483 GLdouble modelview[16], proj[16];
485 GLdouble winX, winY, winZ;
487 /* Get modelview, projection and viewport */
488 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
489 glGetDoublev(GL_PROJECTION_MATRIX, proj);
492 viewport[2] = tr->CurrentTileWidth;
493 viewport[3] = tr->CurrentTileHeight;
495 /* Project object coord to window coordinate */
496 if (gluProject(x, y, z, modelview, proj, viewport, &winX, &winY, &winZ)){
498 /* set raster pos to window coord (0,0) */
499 glMatrixMode(GL_MODELVIEW);
502 glMatrixMode(GL_PROJECTION);
505 glOrtho(0.0, tr->CurrentTileWidth,
506 0.0, tr->CurrentTileHeight, 0.0, 1.0);
507 glRasterPos3f(0.0, 0.0, -winZ);
509 /* Now use empty bitmap to adjust raster position to (winX,winY) */
511 GLubyte bitmap[1] = {0};
512 glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap);
515 /* restore original matrices */
516 glPopMatrix(); /*proj*/
517 glMatrixMode(GL_MODELVIEW);
522 printf("GL error!\n");