5 * Revision 1.2 2001/06/27 02:48:01 curt
6 * Fixed a type conversion bug that could trip up some of the pickier compilers
9 * Revision 1.1 2001/06/26 15:19:39 curt
10 * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
11 * rendering ultra high res "tiled" screen shots.
13 * Revision 1.9 1998/01/29 16:56:54 brianp
14 * allow trOrtho() and trFrustum() to be called at any time, minor clean-up
16 * Revision 1.8 1998/01/28 19:47:39 brianp
17 * minor clean-up for C++
19 * Revision 1.7 1997/07/21 17:34:38 brianp
22 * Revision 1.6 1997/07/21 15:47:35 brianp
23 * renamed all "near" and "far" variables
25 * Revision 1.5 1997/04/26 21:23:25 brianp
26 * added trRasterPos3f function
28 * Revision 1.4 1997/04/26 19:59:36 brianp
29 * set CurrentTile to -1 before first tile and after last tile
31 * Revision 1.3 1997/04/22 23:51:15 brianp
32 * added WIN32 header stuff, removed tabs
34 * Revision 1.2 1997/04/19 23:26:10 brianp
37 * Revision 1.1 1997/04/18 21:53:05 brianp
44 * Tiled Rendering library
46 * Copyright (C) Brian Paul
63 #define DEFAULT_TILE_WIDTH 256
64 #define DEFAULT_TILE_HEIGHT 256
65 #define DEFAULT_TILE_BORDER 0
69 /* Final image parameters */
70 GLint ImageWidth, ImageHeight;
71 GLenum ImageFormat, ImageType;
75 GLint TileWidth, TileHeight;
76 GLint TileWidthNB, TileHeightNB;
78 GLenum TileFormat, TileType;
81 /* Projection parameters */
82 GLboolean Perspective;
94 GLint CurrentTileWidth, CurrentTileHeight;
95 GLint CurrentRow, CurrentColumn;
97 GLint ViewportSave[4];
103 * Misc setup including computing number of tiles (rows and columns).
105 static void Setup(TRcontext *tr)
110 tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
111 tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
114 assert(tr->Columns >= 0);
115 assert(tr->Rows >= 0);
120 TRcontext *trNew(void)
122 TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
124 tr->TileWidth = DEFAULT_TILE_WIDTH;
125 tr->TileHeight = DEFAULT_TILE_HEIGHT;
126 tr->TileBorder = DEFAULT_TILE_BORDER;
127 tr->RowOrder = TR_BOTTOM_TO_TOP;
128 tr->CurrentTile = -1;
130 return (TRcontext *) tr;
134 void trDelete(TRcontext *tr)
142 void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
150 assert(width >= 2*border);
151 assert(height >= 2*border);
153 tr->TileBorder = border;
154 tr->TileWidth = width;
155 tr->TileHeight = height;
156 tr->TileWidthNB = width - 2 * border;
157 tr->TileHeightNB = height - 2 * border;
163 void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
168 tr->TileFormat = format;
170 tr->TileBuffer = image;
175 void trImageSize(TRcontext *tr, GLint width, GLint height)
180 tr->ImageWidth = width;
181 tr->ImageHeight = height;
186 void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
191 tr->ImageFormat = format;
192 tr->ImageType = type;
193 tr->ImageBuffer = image;
197 GLint trGet(TRcontext *tr, TRenum param)
203 return tr->TileWidth;
205 return tr->TileHeight;
207 return tr->TileBorder;
209 return tr->ImageWidth;
210 case TR_IMAGE_HEIGHT:
211 return tr->ImageHeight;
217 if (tr->CurrentTile<0)
220 return tr->CurrentRow;
221 case TR_CURRENT_COLUMN:
222 if (tr->CurrentTile<0)
225 return tr->CurrentColumn;
226 case TR_CURRENT_TILE_WIDTH:
227 return tr->CurrentTileWidth;
228 case TR_CURRENT_TILE_HEIGHT:
229 return tr->CurrentTileHeight;
231 return (GLint) tr->RowOrder;
237 GLdouble trGetD(TRcontext *tr, TRenum param)
259 void trRowOrder(TRcontext *tr, TRenum order)
264 if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
265 tr->RowOrder = order;
269 void trOrtho(TRcontext *tr,
270 GLdouble left, GLdouble right,
271 GLdouble bottom, GLdouble top,
272 GLdouble zNear, GLdouble zFar)
277 tr->Perspective = GL_FALSE;
287 void trFrustum(TRcontext *tr,
288 GLdouble left, GLdouble right,
289 GLdouble bottom, GLdouble top,
290 GLdouble zNear, GLdouble zFar)
295 tr->Perspective = GL_TRUE;
305 void trPerspective(TRcontext *tr,
306 GLdouble fovy, GLdouble aspect,
307 GLdouble zNear, GLdouble zFar )
309 GLdouble xmin, xmax, ymin, ymax;
310 ymax = zNear * tan(fovy * 3.14159265 / 360.0);
312 xmin = ymin * aspect;
313 xmax = ymax * aspect;
314 trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
318 void trBeginTile(TRcontext *tr)
321 GLint tileWidth, tileHeight, border;
322 GLdouble left, right, bottom, top;
327 if (tr->CurrentTile <= 0) {
329 /* Save user's viewport, will be restored after last tile rendered */
330 glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
333 /* which tile (by row and column) we're about to render */
334 if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
335 tr->CurrentRow = tr->CurrentTile / tr->Columns;
336 tr->CurrentColumn = tr->CurrentTile % tr->Columns;
338 else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
339 tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
340 tr->CurrentColumn = tr->CurrentTile % tr->Columns;
343 /* This should never happen */
346 assert(tr->CurrentRow < tr->Rows);
347 assert(tr->CurrentColumn < tr->Columns);
349 border = tr->TileBorder;
351 /* Compute actual size of this tile with border */
352 if (tr->CurrentRow < tr->Rows-1)
353 tileHeight = tr->TileHeight;
355 tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
357 if (tr->CurrentColumn < tr->Columns-1)
358 tileWidth = tr->TileWidth;
360 tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
362 /* Save tile size, with border */
363 tr->CurrentTileWidth = tileWidth;
364 tr->CurrentTileHeight = tileHeight;
366 glViewport(0, 0, tileWidth, tileHeight); /* tile size including border */
368 /* save current matrix mode */
369 glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
370 glMatrixMode(GL_PROJECTION);
373 /* compute projection parameters */
374 left = tr->Left + (tr->Right - tr->Left)
375 * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
376 right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
377 bottom = tr->Bottom + (tr->Top - tr->Bottom)
378 * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
379 top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
381 ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
383 /* restore user's matrix mode */
384 glMatrixMode( (GLenum)matrixMode );
389 int trEndTile(TRcontext *tr)
391 GLint prevRowLength, prevSkipRows, prevSkipPixels /*, prevAlignment */;
396 assert(tr->CurrentTile>=0);
398 /* be sure OpenGL rendering is finished */
401 /* save current glPixelStore values */
402 glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
403 glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
404 glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
405 /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
407 if (tr->TileBuffer) {
408 GLint srcX = tr->TileBorder;
409 GLint srcY = tr->TileBorder;
410 GLint srcWidth = tr->TileWidthNB;
411 GLint srcHeight = tr->TileHeightNB;
412 glReadPixels(srcX, srcY, srcWidth, srcHeight,
413 tr->TileFormat, tr->TileType, tr->TileBuffer);
416 if (tr->ImageBuffer) {
417 GLint srcX = tr->TileBorder;
418 GLint srcY = tr->TileBorder;
419 GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
420 GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
421 GLint destX = tr->TileWidthNB * tr->CurrentColumn;
422 GLint destY = tr->TileHeightNB * tr->CurrentRow;
424 /* setup pixel store for glReadPixels */
425 glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
426 glPixelStorei(GL_PACK_SKIP_ROWS, destY);
427 glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
428 /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
430 /* read the tile into the final image */
431 glReadPixels(srcX, srcY, srcWidth, srcHeight,
432 tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
435 /* restore previous glPixelStore values */
436 glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
437 glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
438 glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
439 /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
441 /* increment tile counter, return 1 if more tiles left to render */
443 if (tr->CurrentTile >= tr->Rows * tr->Columns) {
444 /* restore user's viewport */
445 glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
446 tr->ViewportSave[2], tr->ViewportSave[3]);
447 tr->CurrentTile = -1; /* all done */
456 * Replacement for glRastePos3f() which avoids the problem with invalid
459 void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
461 if (tr->CurrentTile<0) {
462 /* not doing tile rendering right now. Let OpenGL do this. */
463 glRasterPos3f(x, y, z);
466 GLdouble modelview[16], proj[16];
468 GLdouble winX, winY, winZ;
470 /* Get modelview, projection and viewport */
471 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
472 glGetDoublev(GL_PROJECTION_MATRIX, proj);
475 viewport[2] = tr->CurrentTileWidth;
476 viewport[3] = tr->CurrentTileHeight;
478 /* Project object coord to window coordinate */
479 if (gluProject(x, y, z, modelview, proj, viewport, &winX, &winY, &winZ)){
481 /* set raster pos to window coord (0,0) */
482 glMatrixMode(GL_MODELVIEW);
485 glMatrixMode(GL_PROJECTION);
488 glOrtho(0.0, tr->CurrentTileWidth,
489 0.0, tr->CurrentTileHeight, 0.0, 1.0);
490 glRasterPos3f(0.0, 0.0, -winZ);
492 /* Now use empty bitmap to adjust raster position to (winX,winY) */
494 GLubyte bitmap[1] = {0};
495 glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap);
498 /* restore original matrices */
499 glPopMatrix(); /*proj*/
500 glMatrixMode(GL_MODELVIEW);
505 printf("GL error!\n");