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

GIS编程

开发平台:

Visual C++

  1. /*
  2.  * rasonly.c -
  3.  *      Demonstrates the use of OpenGL for rasterization-only, with
  4.  *      perspective-correct texture mapping.
  5.  *
  6.  * Michael I. Gold <gold@sgi.com>
  7.  * Silicon Graphics Computer Systems, May 1997
  8.  *
  9.  * Since current low-end 3D accelerators support only rasterization in
  10.  * hardware, a number of developers have expressed interested in using
  11.  * OpenGL as an interface to rasterization hardware while retaining
  12.  * control of transformations and lighting in the application code.
  13.  * Many OpenGL implementations detect and optimize for identity xforms,
  14.  * so this approach is entirely reasonable.
  15.  *
  16.  * Setting up rasterization-only is fairly straightforward.  The projection
  17.  * matrix is set up as a one-to-one mapping between eye and clip coordinates,
  18.  * and the modelview matrix is set up as identity, e.g. object coordinates
  19.  * map directly to eye coordinates.  This can be achieved as follows:
  20.  *
  21.  *      glMatrixMode(GL_PROJECTION);
  22.  *      glLoadIdentity();
  23.  *      glOrtho(0.0f, (GLfloat) width, 0.0f, (GLfloat) height, -1.0f, 1.0f);
  24.  *      glMatrixMode(GL_MODELVIEW);
  25.  *      glLoadIdentity();
  26.  *      glViewport(0, 0, width, height);
  27.  *
  28.  * where (width, height) represent the window dimensions.
  29.  *
  30.  * Now transformed geometry may be specified directly through the standard
  31.  * interfaces (e.g. glVertex*()).  The only tricky part that remains is
  32.  * specifying texture coordinates such that perspective correction may
  33.  * occur.  The answer is to use glTexCoord4*(), and perform the perspective
  34.  * divide on the texture coordinates directly.
  35.  */
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <GL/glut.h>
  39. GLboolean motion = GL_TRUE;
  40. /* Matrices */
  41. GLfloat rot = 0.0f;
  42. GLfloat ModelView[16];
  43. GLfloat Projection[16];
  44. GLfloat Viewport[4];
  45. /* Sample geometry */
  46. GLfloat quadV[][4] = {
  47.     { -1.0f, 0.0f, -1.0f, 1.0f },
  48.     {  1.0f, 0.0f, -1.0f, 1.0f },
  49.     {  1.0f, 0.5f, -0.2f, 1.0f },
  50.     { -1.0f, 0.5f, -0.2f, 1.0f },
  51. };
  52. GLfloat quadC[][3] = {
  53.     { 1.0f, 0.0f, 0.0f },
  54.     { 0.0f, 1.0f, 0.0f },
  55.     { 0.0f, 0.0f, 1.0f },
  56.     { 1.0f, 1.0f, 1.0f },
  57. };
  58. GLfloat quadT[][2] = {
  59.     { 0.0f, 0.0f },
  60.     { 0.0f, 1.0f },
  61.     { 1.0f, 1.0f },
  62.     { 1.0f, 0.0f },
  63. };
  64. /*********************************************************************
  65.  * Utility functions
  66.  */
  67. int texWidth = 128;
  68. int texHeight = 128;
  69. /* Create and download the application texture map */
  70. static void
  71. setCheckedTexture(void)
  72. {
  73.     int texSize;
  74.     void *textureBuf;
  75.     GLubyte *p;
  76.     int i,j;
  77.     /* malloc for rgba as worst case */
  78.     texSize = texWidth*texHeight*4;
  79.     textureBuf = malloc(texSize);
  80.     if (NULL == textureBuf) return;
  81.     p = (GLubyte *)textureBuf;
  82.     for (i=0; i < texWidth; i++) {
  83.         for (j=0; j < texHeight; j++) {
  84.             if ((i ^ j) & 8) {
  85.                 p[0] = 0xff; p[1] = 0xff; p[2] = 0xff; p[3] = 0xff;
  86.             } else {
  87.                 p[0] = 0x08; p[1] = 0x08; p[2] = 0x08; p[3] = 0xff;
  88.             }
  89.             p += 4;
  90.         }
  91.     }
  92.     gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, 
  93.                  GL_RGBA, GL_UNSIGNED_BYTE, textureBuf);
  94.     free(textureBuf);
  95. }
  96. /* Perform one transform operation */
  97. static void
  98. Transform(GLfloat *matrix, GLfloat *in, GLfloat *out)
  99. {
  100.     int ii;
  101.     for (ii=0; ii<4; ii++) {
  102.         out[ii] = 
  103.             in[0] * matrix[0*4+ii] +
  104.             in[1] * matrix[1*4+ii] +
  105.             in[2] * matrix[2*4+ii] +
  106.             in[3] * matrix[3*4+ii];
  107.     }
  108. }
  109. /* Transform a vertex from object coordinates to window coordinates.
  110.  * Lighting is left as an exercise for the reader.
  111.  */
  112. static void
  113. DoTransform(GLfloat *in, GLfloat *out)
  114. {
  115.     GLfloat tmp[4];
  116.     GLfloat invW;       /* 1/w */
  117.     /* Modelview xform */
  118.     Transform(ModelView, in, tmp);
  119.     /* Lighting calculation goes here! */
  120.     /* Projection xform */
  121.     Transform(Projection, tmp, out);
  122.     if (out[3] == 0.0f) /* do what? */
  123.         return;
  124.     invW = 1.0f / out[3];
  125.     /* Perspective divide */
  126.     out[0] *= invW;
  127.     out[1] *= invW;
  128.     out[2] *= invW;
  129.     /* Map to 0..1 range */
  130.     out[0] = out[0] * 0.5f + 0.5f;
  131.     out[1] = out[1] * 0.5f + 0.5f;
  132.     out[2] = out[2] * 0.5f + 0.5f;
  133.     /* Map to viewport */
  134.     out[0] = out[0] * Viewport[2] + Viewport[0];
  135.     out[1] = out[1] * Viewport[3] + Viewport[1];
  136.     /* Store inverted w for performance */
  137.     out[3] = invW;
  138. }
  139. /*********************************************************************
  140.  * Application code begins here
  141.  */
  142. /* For the sake of brevity, I'm use OpenGL to compute my matrices. */
  143. void UpdateModelView(void)
  144. {
  145.     glPushMatrix();
  146.     glLoadIdentity();
  147.     gluLookAt(0.0f, 1.0f, -4.0f,
  148.               0.0f, 0.0f, 0.0f,
  149.               0.0f, 1.0f, 0.0f);
  150.     glRotatef(rot, 0.0f, 1.0f, 0.0f);
  151.     /* Retrieve the matrix */
  152.     glGetFloatv(GL_MODELVIEW_MATRIX, ModelView);
  153.     glPopMatrix();
  154. }
  155. void InitMatrices(void)
  156. {
  157.     /* Calculate projection matrix */
  158.     glMatrixMode(GL_PROJECTION);
  159.     glPushMatrix();
  160.     glLoadIdentity();
  161.     gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
  162.     /* Retrieve the matrix */
  163.     glGetFloatv(GL_PROJECTION_MATRIX, Projection);
  164.     glPopMatrix();
  165.     glMatrixMode(GL_MODELVIEW);
  166.     UpdateModelView();
  167. }
  168. void Init(void)
  169. {
  170.     glClearColor(0.2f, 0.2f, 0.6f, 1.0f);
  171.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  172.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  173.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  174.     glEnable(GL_TEXTURE_2D);
  175.     glEnable(GL_DEPTH_TEST);
  176.     setCheckedTexture();
  177.     InitMatrices();
  178. }
  179. void Redraw(void)
  180. {
  181.     GLfloat tmp[4];
  182.     int ii;
  183.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  184.     glBegin(GL_QUADS);
  185.     for (ii = 0; ii < 4; ii++) {
  186.         /* Transform a vertex from object to window coordinates.
  187.          * 1/w is returned as tmp[3] for perspective-correcting
  188.          * the texture coordinates.
  189.          */
  190.         DoTransform(quadV[ii], tmp);
  191.         /* Ideally the colors will be computed by the lighting equation,
  192.          * but I've hard-coded values for this example.
  193.          */
  194.         glColor3fv(quadC[ii]);
  195.         /* Scale by 1/w (stored in tmp[3]) */
  196.         glTexCoord4f(quadT[ii][0] * tmp[3],
  197.                      quadT[ii][1] * tmp[3], 0.0f, tmp[3]);
  198.         /* Note I am using Vertex3, not Vertex4, since we have already
  199.          * performed the perspective divide.
  200.          */
  201.         glVertex3fv(tmp);
  202.     }
  203.     glEnd();
  204.     glutSwapBuffers();
  205. }
  206. void Motion(void)
  207. {
  208.     rot += 3.0f;
  209.     if (rot >= 360.0f) rot -= 360.0f;
  210.     UpdateModelView();
  211.     Redraw();
  212. }
  213. /* ARGSUSED1 */
  214. void Key(unsigned char key, int x, int y)
  215. {
  216.     switch (key) {
  217.     case 27:
  218.         exit(0);
  219.     case 'm':
  220.         motion = !motion;
  221.         glutIdleFunc(motion ? Motion : NULL);
  222.         break;
  223.     }
  224. }
  225. /* ARGSUSED1 */
  226. void Button(int button, int state, int x, int y)
  227. {
  228.     switch (button) {
  229.     case GLUT_LEFT_BUTTON:
  230.         if (state == GLUT_DOWN) {
  231.             rot -= 15.0f;
  232.             UpdateModelView();
  233.             Redraw();
  234.         }
  235.         break;
  236.     case GLUT_RIGHT_BUTTON:
  237.         if (state == GLUT_DOWN) {
  238.             rot += 15.0f;
  239.             UpdateModelView();
  240.             Redraw();
  241.         }
  242.         break;
  243.     }
  244. }
  245. void Reshape(int width, int height)
  246. {
  247.     glMatrixMode(GL_PROJECTION);
  248.     glLoadIdentity();
  249.     glOrtho(0.0f, (GLfloat) width, 0.0f, (GLfloat) height, -1.0f, 1.0f);
  250.     glMatrixMode(GL_MODELVIEW);
  251.     glLoadIdentity();
  252.     glViewport(0, 0, width, height);
  253.     Viewport[0] = Viewport[1] = 0.0f;
  254.     Viewport[2] = (GLfloat) width;
  255.     Viewport[3] = (GLfloat) height;
  256. }
  257. int
  258. main(int argc, char *argv[])
  259. {
  260.     char *t;
  261.     glutInit(&argc, argv);
  262.     glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
  263.     glutInitWindowSize(400, 400);
  264.     glutCreateWindow((t=strrchr(argv[0], '\')) != NULL ? t+1 : argv[0]);
  265.     Init();
  266.     glutDisplayFunc(Redraw);
  267.     glutReshapeFunc(Reshape);
  268.     glutKeyboardFunc(Key);
  269.     glutMouseFunc(Button);
  270.     glutIdleFunc(Motion);
  271.     glutMainLoop();
  272.     return 0;
  273. }