5 * Revision 1.1 2001/06/26 15:19:39 curt
6 * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
7 * rendering ultra high res "tiled" screen shots.
9 * Revision 1.9 1998/01/29 16:56:54 brianp
10 * allow trOrtho() and trFrustum() to be called at any time, minor clean-up
12 * Revision 1.8 1998/01/28 19:47:39 brianp
13 * minor clean-up for C++
15 * Revision 1.7 1997/07/21 17:34:38 brianp
18 * Revision 1.6 1997/07/21 15:47:35 brianp
19 * renamed all "near" and "far" variables
21 * Revision 1.5 1997/04/26 21:23:25 brianp
22 * added trRasterPos3f function
24 * Revision 1.4 1997/04/26 19:59:36 brianp
25 * set CurrentTile to -1 before first tile and after last tile
27 * Revision 1.3 1997/04/22 23:51:15 brianp
28 * added WIN32 header stuff, removed tabs
30 * Revision 1.2 1997/04/19 23:26:10 brianp
33 * Revision 1.1 1997/04/18 21:53:05 brianp
40 * Tiled Rendering library
42 * Copyright (C) Brian Paul
59 #define DEFAULT_TILE_WIDTH 256
60 #define DEFAULT_TILE_HEIGHT 256
61 #define DEFAULT_TILE_BORDER 0
65 /* Final image parameters */
66 GLint ImageWidth, ImageHeight;
67 GLenum ImageFormat, ImageType;
71 GLint TileWidth, TileHeight;
72 GLint TileWidthNB, TileHeightNB;
74 GLenum TileFormat, TileType;
77 /* Projection parameters */
78 GLboolean Perspective;
90 GLint CurrentTileWidth, CurrentTileHeight;
91 GLint CurrentRow, CurrentColumn;
93 GLint ViewportSave[4];
99 * Misc setup including computing number of tiles (rows and columns).
101 static void Setup(TRcontext *tr)
106 tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
107 tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
110 assert(tr->Columns >= 0);
111 assert(tr->Rows >= 0);
116 TRcontext *trNew(void)
118 TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
120 tr->TileWidth = DEFAULT_TILE_WIDTH;
121 tr->TileHeight = DEFAULT_TILE_HEIGHT;
122 tr->TileBorder = DEFAULT_TILE_BORDER;
123 tr->RowOrder = TR_BOTTOM_TO_TOP;
124 tr->CurrentTile = -1;
126 return (TRcontext *) tr;
130 void trDelete(TRcontext *tr)
138 void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
146 assert(width >= 2*border);
147 assert(height >= 2*border);
149 tr->TileBorder = border;
150 tr->TileWidth = width;
151 tr->TileHeight = height;
152 tr->TileWidthNB = width - 2 * border;
153 tr->TileHeightNB = height - 2 * border;
159 void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
164 tr->TileFormat = format;
166 tr->TileBuffer = image;
171 void trImageSize(TRcontext *tr, GLint width, GLint height)
176 tr->ImageWidth = width;
177 tr->ImageHeight = height;
182 void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
187 tr->ImageFormat = format;
188 tr->ImageType = type;
189 tr->ImageBuffer = image;
193 GLint trGet(TRcontext *tr, TRenum param)
199 return tr->TileWidth;
201 return tr->TileHeight;
203 return tr->TileBorder;
205 return tr->ImageWidth;
206 case TR_IMAGE_HEIGHT:
207 return tr->ImageHeight;
213 if (tr->CurrentTile<0)
216 return tr->CurrentRow;
217 case TR_CURRENT_COLUMN:
218 if (tr->CurrentTile<0)
221 return tr->CurrentColumn;
222 case TR_CURRENT_TILE_WIDTH:
223 return tr->CurrentTileWidth;
224 case TR_CURRENT_TILE_HEIGHT:
225 return tr->CurrentTileHeight;
227 return (GLint) tr->RowOrder;
233 GLdouble trGetD(TRcontext *tr, TRenum param)
255 void trRowOrder(TRcontext *tr, TRenum order)
260 if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
261 tr->RowOrder = order;
265 void trOrtho(TRcontext *tr,
266 GLdouble left, GLdouble right,
267 GLdouble bottom, GLdouble top,
268 GLdouble zNear, GLdouble zFar)
273 tr->Perspective = GL_FALSE;
283 void trFrustum(TRcontext *tr,
284 GLdouble left, GLdouble right,
285 GLdouble bottom, GLdouble top,
286 GLdouble zNear, GLdouble zFar)
291 tr->Perspective = GL_TRUE;
301 void trPerspective(TRcontext *tr,
302 GLdouble fovy, GLdouble aspect,
303 GLdouble zNear, GLdouble zFar )
305 GLdouble xmin, xmax, ymin, ymax;
306 ymax = zNear * tan(fovy * 3.14159265 / 360.0);
308 xmin = ymin * aspect;
309 xmax = ymax * aspect;
310 trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
314 void trBeginTile(TRcontext *tr)
317 GLint tileWidth, tileHeight, border;
318 GLdouble left, right, bottom, top;
323 if (tr->CurrentTile <= 0) {
325 /* Save user's viewport, will be restored after last tile rendered */
326 glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
329 /* which tile (by row and column) we're about to render */
330 if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
331 tr->CurrentRow = tr->CurrentTile / tr->Columns;
332 tr->CurrentColumn = tr->CurrentTile % tr->Columns;
334 else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
335 tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
336 tr->CurrentColumn = tr->CurrentTile % tr->Columns;
339 /* This should never happen */
342 assert(tr->CurrentRow < tr->Rows);
343 assert(tr->CurrentColumn < tr->Columns);
345 border = tr->TileBorder;
347 /* Compute actual size of this tile with border */
348 if (tr->CurrentRow < tr->Rows-1)
349 tileHeight = tr->TileHeight;
351 tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
353 if (tr->CurrentColumn < tr->Columns-1)
354 tileWidth = tr->TileWidth;
356 tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
358 /* Save tile size, with border */
359 tr->CurrentTileWidth = tileWidth;
360 tr->CurrentTileHeight = tileHeight;
362 glViewport(0, 0, tileWidth, tileHeight); /* tile size including border */
364 /* save current matrix mode */
365 glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
366 glMatrixMode(GL_PROJECTION);
369 /* compute projection parameters */
370 left = tr->Left + (tr->Right - tr->Left)
371 * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
372 right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
373 bottom = tr->Bottom + (tr->Top - tr->Bottom)
374 * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
375 top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
377 ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
379 /* restore user's matrix mode */
380 glMatrixMode(matrixMode);
385 int trEndTile(TRcontext *tr)
387 GLint prevRowLength, prevSkipRows, prevSkipPixels /*, prevAlignment */;
392 assert(tr->CurrentTile>=0);
394 /* be sure OpenGL rendering is finished */
397 /* save current glPixelStore values */
398 glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
399 glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
400 glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
401 /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
403 if (tr->TileBuffer) {
404 GLint srcX = tr->TileBorder;
405 GLint srcY = tr->TileBorder;
406 GLint srcWidth = tr->TileWidthNB;
407 GLint srcHeight = tr->TileHeightNB;
408 glReadPixels(srcX, srcY, srcWidth, srcHeight,
409 tr->TileFormat, tr->TileType, tr->TileBuffer);
412 if (tr->ImageBuffer) {
413 GLint srcX = tr->TileBorder;
414 GLint srcY = tr->TileBorder;
415 GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
416 GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
417 GLint destX = tr->TileWidthNB * tr->CurrentColumn;
418 GLint destY = tr->TileHeightNB * tr->CurrentRow;
420 /* setup pixel store for glReadPixels */
421 glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
422 glPixelStorei(GL_PACK_SKIP_ROWS, destY);
423 glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
424 /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
426 /* read the tile into the final image */
427 glReadPixels(srcX, srcY, srcWidth, srcHeight,
428 tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
431 /* restore previous glPixelStore values */
432 glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
433 glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
434 glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
435 /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
437 /* increment tile counter, return 1 if more tiles left to render */
439 if (tr->CurrentTile >= tr->Rows * tr->Columns) {
440 /* restore user's viewport */
441 glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
442 tr->ViewportSave[2], tr->ViewportSave[3]);
443 tr->CurrentTile = -1; /* all done */
452 * Replacement for glRastePos3f() which avoids the problem with invalid
455 void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
457 if (tr->CurrentTile<0) {
458 /* not doing tile rendering right now. Let OpenGL do this. */
459 glRasterPos3f(x, y, z);
462 GLdouble modelview[16], proj[16];
464 GLdouble winX, winY, winZ;
466 /* Get modelview, projection and viewport */
467 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
468 glGetDoublev(GL_PROJECTION_MATRIX, proj);
471 viewport[2] = tr->CurrentTileWidth;
472 viewport[3] = tr->CurrentTileHeight;
474 /* Project object coord to window coordinate */
475 if (gluProject(x, y, z, modelview, proj, viewport, &winX, &winY, &winZ)){
477 /* set raster pos to window coord (0,0) */
478 glMatrixMode(GL_MODELVIEW);
481 glMatrixMode(GL_PROJECTION);
484 glOrtho(0.0, tr->CurrentTileWidth,
485 0.0, tr->CurrentTileHeight, 0.0, 1.0);
486 glRasterPos3f(0.0, 0.0, -winZ);
488 /* Now use empty bitmap to adjust raster position to (winX,winY) */
490 GLubyte bitmap[1] = {0};
491 glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap);
494 /* restore original matrices */
495 glPopMatrix(); /*proj*/
496 glMatrixMode(GL_MODELVIEW);
501 printf("GL error!\n");