tr.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:5k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* tr.c */
  2. /*
  3.  * Tiled Rendering library
  4.  *
  5.  * Brian Paul
  6.  * April 1997
  7.  */
  8. #include <assert.h>
  9. #include <math.h>
  10. #include <stdlib.h>
  11. #include "tr.h"
  12. struct _TRctx {
  13.    GLint ImageWidth, ImageHeight;
  14.    GLubyte *Image;
  15.    GLint TileWidth, TileHeight;
  16.    GLboolean Perspective;
  17.    GLdouble Left;
  18.    GLdouble Right;
  19.    GLdouble Bottom;
  20.    GLdouble Top;
  21.    GLdouble Near;
  22.    GLdouble Far;
  23.    GLint Rows, Columns;
  24.    GLint CurrentTile;
  25.    GLint CurrentTileWidth, CurrentTileHeight;
  26.    GLint CurrentRow, CurrentColumn;
  27.    GLint ViewportSave[4];
  28. };
  29. TRcontext *trNew(void)
  30. {
  31.    return (TRcontext *) calloc(1, sizeof(TRcontext));
  32. }
  33. void trDelete(TRcontext *tr)
  34. {
  35.    if (tr)
  36.       free(tr);
  37. }
  38. void trSetup(TRcontext *tr,
  39.      GLint imageWidth, GLint imageHeight, GLubyte *image,
  40.      GLint tileWidth, GLint tileHeight)
  41. {
  42.    if (!tr || !image)
  43.       return;
  44.    tr->ImageWidth = imageWidth;
  45.    tr->ImageHeight = imageHeight;
  46.    tr->Image = image;
  47.    tr->TileWidth = tileWidth;
  48.    tr->TileHeight = tileHeight;
  49.    tr->Columns = (tr->ImageWidth + tr->TileWidth - 1) / tr->TileWidth;
  50.    tr->Rows = (tr->ImageHeight + tr->TileHeight - 1) / tr->TileHeight;
  51.    tr->CurrentTile = 0;
  52.    assert(tr->Columns >= 1);
  53.    assert(tr->Rows >= 1);
  54. }
  55. void trOrtho(TRcontext *tr,
  56.      GLdouble left, GLdouble right,
  57.      GLdouble bottom, GLdouble top,
  58.      GLdouble nnear, GLdouble ffar)
  59. {
  60.    if (!tr)
  61.       return;
  62.    tr->Perspective = GL_FALSE;
  63.    tr->Left = left;
  64.    tr->Right = right;
  65.    tr->Bottom = bottom;
  66.    tr->Top = top;
  67.    tr->Near = nnear;
  68.    tr->Far = ffar;
  69.    tr->CurrentTile = 0;
  70. }
  71. void trFrustum(TRcontext *tr,
  72.        GLdouble left, GLdouble right,
  73.        GLdouble bottom, GLdouble top,
  74.        GLdouble zNear, GLdouble zFar)
  75. {
  76.    if (!tr)
  77.       return;
  78.    tr->Perspective = GL_TRUE;
  79.    tr->Left = left;
  80.    tr->Right = right;
  81.    tr->Bottom = bottom;
  82.    tr->Top = top;
  83.    tr->Near = zNear;
  84.    tr->Far = zFar;
  85.    tr->CurrentTile = 0;
  86. }
  87. void trPerspective(TRcontext *tr,
  88.    GLdouble fovy, GLdouble aspect,
  89.    GLdouble zNear, GLdouble zFar )
  90. {
  91.    GLdouble xmin, xmax, ymin, ymax;
  92.    ymax = zNear * tan(fovy * 3.14159265 / 360.0);
  93.    ymin = -ymax;
  94.    xmin = ymin * aspect;
  95.    xmax = ymax * aspect;
  96.    trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
  97. }
  98. void trBeginTile(TRcontext *tr)
  99. {
  100.    GLint matrixMode;
  101.    int tileWidth, tileHeight;
  102.    GLdouble left, right, bottom, top;
  103.    if (!tr)
  104.       return;
  105.    if (tr->CurrentTile==0) {
  106.       /* Save user's viewport, will be restored after last tile rendered */
  107.       glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
  108.    }
  109.    /* which tile (by row and column) we're about to render */
  110.    tr->CurrentRow = tr->CurrentTile / tr->Columns;
  111.    tr->CurrentColumn = tr->CurrentTile % tr->Columns;
  112.    /* actual size of this tile */
  113.    if (tr->CurrentRow < tr->Rows-1)
  114.       tileHeight = tr->TileHeight;
  115.    else
  116.       tileHeight = tr->ImageHeight - (tr->Rows-1) * tr->TileHeight;
  117.    if (tr->CurrentColumn < tr->Columns-1)
  118.       tileWidth = tr->TileWidth;
  119.    else
  120.       tileWidth = tr->ImageWidth - (tr->Columns-1) * tr->TileWidth;
  121.    tr->CurrentTileWidth = tileWidth;
  122.    tr->CurrentTileHeight = tileHeight;
  123.    glViewport(0, 0, tileWidth, tileHeight);
  124.    /* save current matrix mode */
  125.    glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
  126.    glMatrixMode(GL_PROJECTION);
  127.    glLoadIdentity();
  128.    /* compute projection parameters */
  129.    left = tr->Left + (tr->Right - tr->Left)
  130.         * (tr->CurrentColumn * tr->TileWidth) / tr->ImageWidth;
  131.    right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
  132.    bottom = tr->Bottom + (tr->Top - tr->Bottom)
  133.           * (tr->CurrentRow * tr->TileHeight) / tr->ImageHeight;
  134.    top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
  135.    if (tr->Perspective)
  136.       glFrustum(left, right, bottom, top, tr->Near, tr->Far);
  137.    else
  138.       glOrtho(left, right, bottom, top, tr->Near, tr->Far);
  139.    /* restore user's matrix mode */
  140.    glMatrixMode(matrixMode);
  141. }
  142. int trEndTile(TRcontext *tr)
  143. {
  144.    GLint prevRowLength, prevSkipRows, prevSkipPixels, prevAlignment;
  145.    GLint x, y;
  146.    if (!tr)
  147.       return 0;
  148.    /* be sure OpenGL rendering is finished */
  149.    glFlush();
  150.    /* save current glPixelStore values */
  151.    glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
  152.    glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
  153.    glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
  154.    glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);
  155.    x = tr->TileWidth * tr->CurrentColumn;
  156.    y = tr->TileHeight * tr->CurrentRow;
  157.    /* setup pixel store for glReadPixels */
  158.    glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
  159.    glPixelStorei(GL_PACK_SKIP_ROWS, y);
  160.    glPixelStorei(GL_PACK_SKIP_PIXELS, x);
  161.    glPixelStorei(GL_PACK_ALIGNMENT, 1);
  162.    /* read the tile into the final image */
  163.    glReadPixels(0, 0, tr->CurrentTileWidth, tr->CurrentTileHeight,
  164. GL_RGBA, GL_UNSIGNED_BYTE, tr->Image);
  165.    /* restore previous glPixelStore values */
  166.    glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
  167.    glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
  168.    glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
  169.    glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);
  170.    /* increment tile counter, return 1 if more tiles left to render */
  171.    tr->CurrentTile++;
  172.    if (tr->CurrentTile >= tr->Rows * tr->Columns) {
  173.       /* restore user's viewport */
  174.       glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
  175.  tr->ViewportSave[2], tr->ViewportSave[3]);
  176.       return 0;
  177.    }
  178.    else
  179.       return 1;
  180. }