]> git.mxchange.org Git - simgear.git/commitdiff
Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
authorcurt <curt>
Tue, 26 Jun 2001 15:19:39 +0000 (15:19 +0000)
committercurt <curt>
Tue, 26 Jun 2001 15:19:39 +0000 (15:19 +0000)
rendering ultra high res "tiled" screen shots.

simgear/screen/Makefile.am
simgear/screen/tr.cxx [new file with mode: 0644]
simgear/screen/tr.h [new file with mode: 0644]

index 60df6eb28d6782ba24eb6eb0c3137ca7e840c494..5c618a3a29a5d7f5d28127fe2c23730d35a14541 100644 (file)
@@ -2,11 +2,12 @@ includedir = @includedir@/screen
 
 lib_LIBRARIES = libsgscreen.a
 
-include_HEADERS = screen-dump.hxx
+include_HEADERS = screen-dump.hxx tr.h
 
 libsgscreen_a_SOURCES = \
        GLBitmaps.cxx GLBitmaps.h \
        screen-dump.cxx \
+        tr.cxx \
        win32-printer.h
 
 INCLUDES += -I$(top_srcdir)
diff --git a/simgear/screen/tr.cxx b/simgear/screen/tr.cxx
new file mode 100644 (file)
index 0000000..6a8169c
--- /dev/null
@@ -0,0 +1,505 @@
+/* $Id$ */
+
+/*
+ * $Log$
+ * Revision 1.1  2001/06/26 15:19:39  curt
+ * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
+ * rendering ultra high res "tiled" screen shots.
+ *
+ * Revision 1.9  1998/01/29  16:56:54  brianp
+ * allow trOrtho() and trFrustum() to be called at any time, minor clean-up
+ *
+ * Revision 1.8  1998/01/28  19:47:39  brianp
+ * minor clean-up for C++
+ *
+ * Revision 1.7  1997/07/21  17:34:38  brianp
+ * added tile borders
+ *
+ * Revision 1.6  1997/07/21  15:47:35  brianp
+ * renamed all "near" and "far" variables
+ *
+ * Revision 1.5  1997/04/26  21:23:25  brianp
+ * added trRasterPos3f function
+ *
+ * Revision 1.4  1997/04/26  19:59:36  brianp
+ * set CurrentTile to -1 before first tile and after last tile
+ *
+ * Revision 1.3  1997/04/22  23:51:15  brianp
+ * added WIN32 header stuff, removed tabs
+ *
+ * Revision 1.2  1997/04/19  23:26:10  brianp
+ * many API changes
+ *
+ * Revision 1.1  1997/04/18  21:53:05  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Tiled Rendering library
+ * Version 1.1
+ * Copyright (C) Brian Paul
+ */
+
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <plib/ssg.h>
+#include "tr.h"
+
+
+#define DEFAULT_TILE_WIDTH  256
+#define DEFAULT_TILE_HEIGHT 256
+#define DEFAULT_TILE_BORDER 0
+
+
+struct _TRctx {
+   /* Final image parameters */
+   GLint ImageWidth, ImageHeight;
+   GLenum ImageFormat, ImageType;
+   GLvoid *ImageBuffer;
+
+   /* Tile parameters */
+   GLint TileWidth, TileHeight;
+   GLint TileWidthNB, TileHeightNB;
+   GLint TileBorder;
+   GLenum TileFormat, TileType;
+   GLvoid *TileBuffer;
+
+   /* Projection parameters */
+   GLboolean Perspective;
+   GLdouble Left;
+   GLdouble Right;
+   GLdouble Bottom;
+   GLdouble Top;
+   GLdouble Near;
+   GLdouble Far;
+
+   /* Misc */
+   TRenum RowOrder;
+   GLint Rows, Columns;
+   GLint CurrentTile;
+   GLint CurrentTileWidth, CurrentTileHeight;
+   GLint CurrentRow, CurrentColumn;
+
+   GLint ViewportSave[4];
+};
+
+
+
+/*
+ * Misc setup including computing number of tiles (rows and columns).
+ */
+static void Setup(TRcontext *tr)
+{
+   if (!tr)
+      return;
+
+   tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
+   tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
+   tr->CurrentTile = 0;
+
+   assert(tr->Columns >= 0);
+   assert(tr->Rows >= 0);
+}
+
+
+
+TRcontext *trNew(void)
+{
+   TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
+   if (tr) {
+      tr->TileWidth = DEFAULT_TILE_WIDTH;
+      tr->TileHeight = DEFAULT_TILE_HEIGHT;
+      tr->TileBorder = DEFAULT_TILE_BORDER;
+      tr->RowOrder = TR_BOTTOM_TO_TOP;
+      tr->CurrentTile = -1;
+   }
+   return (TRcontext *) tr;
+}
+
+
+void trDelete(TRcontext *tr)
+{
+   if (tr)
+      free(tr);
+}
+
+
+
+void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
+{
+   if (!tr)
+      return;
+
+   assert(border >= 0);
+   assert(width >= 1);
+   assert(height >= 1);
+   assert(width >= 2*border);
+   assert(height >= 2*border);
+
+   tr->TileBorder = border;
+   tr->TileWidth = width;
+   tr->TileHeight = height;
+   tr->TileWidthNB = width - 2 * border;
+   tr->TileHeightNB = height - 2 * border;
+   Setup(tr);
+}
+
+
+
+void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
+{
+   if (!tr)
+      return;
+
+   tr->TileFormat = format;
+   tr->TileType = type;
+   tr->TileBuffer = image;
+}
+
+
+
+void trImageSize(TRcontext *tr, GLint width, GLint height)
+{
+   if (!tr)
+      return;
+
+   tr->ImageWidth = width;
+   tr->ImageHeight = height;
+   Setup(tr);
+}
+
+
+void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
+{
+   if (!tr)
+      return;
+
+   tr->ImageFormat = format;
+   tr->ImageType = type;
+   tr->ImageBuffer = image;
+}
+
+
+GLint trGet(TRcontext *tr, TRenum param)
+{
+   if (!tr)
+      return 0;
+   switch (param) {
+      case TR_TILE_WIDTH:
+         return tr->TileWidth;
+      case TR_TILE_HEIGHT:
+         return tr->TileHeight;
+      case TR_TILE_BORDER:
+         return tr->TileBorder;
+      case TR_IMAGE_WIDTH:
+         return tr->ImageWidth;
+      case TR_IMAGE_HEIGHT:
+         return tr->ImageHeight;
+      case TR_ROWS:
+         return tr->Rows;
+      case TR_COLUMNS:
+         return tr->Columns;
+      case TR_CURRENT_ROW:
+         if (tr->CurrentTile<0)
+            return -1;
+         else
+            return tr->CurrentRow;
+      case TR_CURRENT_COLUMN:
+         if (tr->CurrentTile<0)
+            return -1;
+         else
+            return tr->CurrentColumn;
+      case TR_CURRENT_TILE_WIDTH:
+         return tr->CurrentTileWidth;
+      case TR_CURRENT_TILE_HEIGHT:
+         return tr->CurrentTileHeight;
+      case TR_ROW_ORDER:
+         return (GLint) tr->RowOrder;
+      default:
+         return 0;
+   }
+}
+
+GLdouble trGetD(TRcontext *tr, TRenum param)
+{
+       if (!tr)
+               return 0.0;
+       switch (param) {
+       case TR_LEFT:
+               return tr->Left;
+       case TR_RIGHT:
+               return tr->Right;
+       case TR_BOTTOM:
+               return tr->Bottom;
+       case TR_TOP:
+               return tr->Top;
+       case TR_NEAR:
+               return tr->Near;
+       case TR_FAR:
+               return tr->Far;
+       default:
+               return 0.0;
+       }
+}
+
+void trRowOrder(TRcontext *tr, TRenum order)
+{
+   if (!tr)
+      return;
+
+   if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
+      tr->RowOrder = order;
+}
+
+
+void trOrtho(TRcontext *tr,
+             GLdouble left, GLdouble right,
+             GLdouble bottom, GLdouble top,
+             GLdouble zNear, GLdouble zFar)
+{
+   if (!tr)
+      return;
+
+   tr->Perspective = GL_FALSE;
+   tr->Left = left;
+   tr->Right = right;
+   tr->Bottom = bottom;
+   tr->Top = top;
+   tr->Near = zNear;
+   tr->Far = zFar;
+}
+
+
+void trFrustum(TRcontext *tr,
+               GLdouble left, GLdouble right,
+               GLdouble bottom, GLdouble top,
+               GLdouble zNear, GLdouble zFar)
+{
+   if (!tr)
+      return;
+
+   tr->Perspective = GL_TRUE;
+   tr->Left = left;
+   tr->Right = right;
+   tr->Bottom = bottom;
+   tr->Top = top;
+   tr->Near = zNear;
+   tr->Far = zFar;
+}
+
+
+void trPerspective(TRcontext *tr,
+                   GLdouble fovy, GLdouble aspect,
+                   GLdouble zNear, GLdouble zFar )
+{
+   GLdouble xmin, xmax, ymin, ymax;
+   ymax = zNear * tan(fovy * 3.14159265 / 360.0);
+   ymin = -ymax;
+   xmin = ymin * aspect;
+   xmax = ymax * aspect;
+   trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
+}
+
+
+void trBeginTile(TRcontext *tr)
+{
+   GLint matrixMode;
+   GLint tileWidth, tileHeight, border;
+   GLdouble left, right, bottom, top;
+
+   if (!tr)
+      return;
+
+   if (tr->CurrentTile <= 0) {
+      Setup(tr);
+      /* Save user's viewport, will be restored after last tile rendered */
+      glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
+   }
+
+   /* which tile (by row and column) we're about to render */
+   if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
+      tr->CurrentRow = tr->CurrentTile / tr->Columns;
+      tr->CurrentColumn = tr->CurrentTile % tr->Columns;
+   }
+   else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
+      tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
+      tr->CurrentColumn = tr->CurrentTile % tr->Columns;
+   }
+   else {
+      /* This should never happen */
+      abort();
+   }
+   assert(tr->CurrentRow < tr->Rows);
+   assert(tr->CurrentColumn < tr->Columns);
+
+   border = tr->TileBorder;
+
+   /* Compute actual size of this tile with border */
+   if (tr->CurrentRow < tr->Rows-1)
+      tileHeight = tr->TileHeight;
+   else
+      tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
+
+   if (tr->CurrentColumn < tr->Columns-1)
+      tileWidth = tr->TileWidth;
+   else
+      tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
+
+   /* Save tile size, with border */
+   tr->CurrentTileWidth = tileWidth;
+   tr->CurrentTileHeight = tileHeight;
+
+   glViewport(0, 0, tileWidth, tileHeight);  /* tile size including border */
+
+   /* save current matrix mode */
+   glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+
+   /* compute projection parameters */
+   left = tr->Left + (tr->Right - tr->Left)
+        * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
+   right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
+   bottom = tr->Bottom + (tr->Top - tr->Bottom)
+          * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
+   top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
+
+   ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
+
+   /* restore user's matrix mode */
+   glMatrixMode(matrixMode);
+}
+
+
+
+int trEndTile(TRcontext *tr)
+{
+   GLint prevRowLength, prevSkipRows, prevSkipPixels /*, prevAlignment */;
+
+   if (!tr)
+      return 0;
+
+   assert(tr->CurrentTile>=0);
+
+   /* be sure OpenGL rendering is finished */
+   glFlush();
+
+   /* save current glPixelStore values */
+   glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
+   glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
+   glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
+   /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
+
+   if (tr->TileBuffer) {
+      GLint srcX = tr->TileBorder;
+      GLint srcY = tr->TileBorder;
+      GLint srcWidth = tr->TileWidthNB;
+      GLint srcHeight = tr->TileHeightNB;
+      glReadPixels(srcX, srcY, srcWidth, srcHeight,
+                   tr->TileFormat, tr->TileType, tr->TileBuffer);
+   }
+
+   if (tr->ImageBuffer) {
+      GLint srcX = tr->TileBorder;
+      GLint srcY = tr->TileBorder;
+      GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
+      GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
+      GLint destX = tr->TileWidthNB * tr->CurrentColumn;
+      GLint destY = tr->TileHeightNB * tr->CurrentRow;
+
+      /* setup pixel store for glReadPixels */
+      glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
+      glPixelStorei(GL_PACK_SKIP_ROWS, destY);
+      glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
+      /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
+
+      /* read the tile into the final image */
+      glReadPixels(srcX, srcY, srcWidth, srcHeight,
+                   tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
+   }
+
+   /* restore previous glPixelStore values */
+   glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
+   glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
+   glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
+   /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
+
+   /* increment tile counter, return 1 if more tiles left to render */
+   tr->CurrentTile++;
+   if (tr->CurrentTile >= tr->Rows * tr->Columns) {
+      /* restore user's viewport */
+      glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
+                 tr->ViewportSave[2], tr->ViewportSave[3]);
+      tr->CurrentTile = -1;  /* all done */
+      return 0;
+   }
+   else
+      return 1;
+}
+
+
+/*
+ * Replacement for glRastePos3f() which avoids the problem with invalid
+ * raster pos.
+ */
+void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
+{
+   if (tr->CurrentTile<0) {
+      /* not doing tile rendering right now.  Let OpenGL do this. */
+      glRasterPos3f(x, y, z);
+   }
+   else {
+      GLdouble modelview[16], proj[16];
+      GLint viewport[4];
+      GLdouble winX, winY, winZ;
+
+      /* Get modelview, projection and viewport */
+      glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
+      glGetDoublev(GL_PROJECTION_MATRIX, proj);
+      viewport[0] = 0;
+      viewport[1] = 0;
+      viewport[2] = tr->CurrentTileWidth;
+      viewport[3] = tr->CurrentTileHeight;
+
+      /* Project object coord to window coordinate */
+      if (gluProject(x, y, z, modelview, proj, viewport, &winX, &winY, &winZ)){
+
+         /* set raster pos to window coord (0,0) */
+         glMatrixMode(GL_MODELVIEW);
+         glPushMatrix();
+         glLoadIdentity();
+         glMatrixMode(GL_PROJECTION);
+         glPushMatrix();
+         glLoadIdentity();
+         glOrtho(0.0, tr->CurrentTileWidth,
+                 0.0, tr->CurrentTileHeight, 0.0, 1.0);
+         glRasterPos3f(0.0, 0.0, -winZ);
+
+         /* Now use empty bitmap to adjust raster position to (winX,winY) */
+         {
+            GLubyte bitmap[1] = {0};
+            glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap);
+         }
+
+         /* restore original matrices */
+         glPopMatrix(); /*proj*/
+         glMatrixMode(GL_MODELVIEW);
+         glPopMatrix();
+      }
+#ifdef DEBUG
+      if (glGetError())
+         printf("GL error!\n");
+#endif
+   }
+}
+
diff --git a/simgear/screen/tr.h b/simgear/screen/tr.h
new file mode 100644 (file)
index 0000000..e57b008
--- /dev/null
@@ -0,0 +1,170 @@
+/* $Id$ */
+
+/*
+ * $Log$
+ * Revision 1.1  2001/06/26 15:19:39  curt
+ * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
+ * rendering ultra high res "tiled" screen shots.
+ *
+ * Revision 1.5  1997/07/21  17:34:07  brianp
+ * added tile borders, incremented version to 1.1
+ *
+ * Revision 1.4  1997/07/21  15:47:35  brianp
+ * renamed all "near" and "far" variables
+ *
+ * Revision 1.3  1997/04/26  21:23:25  brianp
+ * added trRasterPos3f function
+ *
+ * Revision 1.2  1997/04/19  23:26:10  brianp
+ * many API changes
+ *
+ * Revision 1.1  1997/04/18  21:53:05  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Tiled Rendering library
+ * Version 1.1
+ * Copyright (C) Brian Paul
+ *
+ *
+ * This library allows one to render arbitrarily large images with OpenGL.
+ * The basic idea is to break the image into tiles which are rendered one
+ * at a time.  The tiles are assembled together to form the final, large
+ * image.  Tiles and images can be of any size.
+ *
+ * Basic usage:
+ *
+ * 1. Allocate a tile rendering context:
+ *       TRcontext t = trNew();
+ *
+ * 2. Specify the final image buffer and tile size:
+ *       GLubyte image[W][H][4]
+ *       trImageSize(t, W, H);
+ *       trImageBuffer(t, GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte *) image);
+ *
+ * 3. Setup your projection:
+ *       trFrustum(t, left, right, bottom top, near, far);
+ *    or
+ *       trOrtho(t, left, right, bottom top, near, far);
+ *    or
+ *       trPerspective(t, fovy, aspect, near, far);
+ *
+ * 4. Render the tiles:
+ *       do {
+ *           trBeginTile(t);
+ *           DrawMyScene();
+ *       } while (trEndTile(t));
+ *
+ *    You provide the DrawMyScene() function which calls glClear() and
+ *    draws all your stuff.
+ *
+ * 5. The image array is now complete.  Display it, write it to a file, etc.
+ *
+ * 6. Delete the tile rendering context when finished:
+ *       trDelete(t);
+ *
+ */
+
+
+#ifndef TR_H
+#define TR_H
+
+
+#include <GL/gl.h>
+
+
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
+
+
+#define TR_VERSION "1.1"
+#define TR_MAJOR_VERSION 1
+#define TR_MINOR_VERSION 1
+
+
+typedef struct _TRctx TRcontext;
+
+
+typedef enum {
+       TR_TILE_WIDTH = 100,
+       TR_TILE_HEIGHT,
+       TR_TILE_BORDER,
+       TR_IMAGE_WIDTH,
+       TR_IMAGE_HEIGHT,
+       TR_ROWS,
+       TR_COLUMNS,
+       TR_CURRENT_ROW,
+       TR_CURRENT_COLUMN,
+       TR_CURRENT_TILE_WIDTH,
+       TR_CURRENT_TILE_HEIGHT,
+       TR_ROW_ORDER,
+       TR_TOP_TO_BOTTOM,
+       TR_BOTTOM_TO_TOP,
+       TR_LEFT,
+       TR_RIGHT,
+       TR_BOTTOM,
+       TR_TOP,
+       TR_NEAR,
+       TR_FAR
+} TRenum;
+
+
+
+extern TRcontext *trNew(void);
+
+extern void trDelete(TRcontext *tr);
+
+
+extern void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border);
+
+extern void trTileBuffer(TRcontext *tr, GLenum format, GLenum type,
+                                                GLvoid *image);
+
+
+extern void trImageSize(TRcontext *tr, GLint width, GLint height);
+
+extern void trImageBuffer(TRcontext *tr, GLenum format, GLenum type,
+                                                 GLvoid *image);
+
+
+extern void trRowOrder(TRcontext *tr, TRenum order);
+
+
+extern GLint trGet(TRcontext *tr, TRenum param);
+extern GLdouble trGetD(TRcontext *tr, TRenum param);
+
+
+extern void trOrtho(TRcontext *tr,
+                                       GLdouble left, GLdouble right,
+                                       GLdouble bottom, GLdouble top,
+                                       GLdouble zNear, GLdouble zFar);
+
+extern void trFrustum(TRcontext *tr,
+                                         GLdouble left, GLdouble right,
+                                         GLdouble bottom, GLdouble top,
+                                         GLdouble zNear, GLdouble zFar);
+
+extern void trPerspective(TRcontext *tr,
+                                                 GLdouble fovy, GLdouble aspect,
+                                                 GLdouble zNear, GLdouble zFar );
+
+
+extern void trBeginTile(TRcontext *tr);
+
+extern int trEndTile(TRcontext *tr);
+
+
+extern void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z);
+
+
+
+//#ifdef __cplusplus
+//}
+//#endif
+
+
+#endif