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

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1994.  */
  2. /* This program is freely distributable without licensing fees 
  3.    and is provided without guarantee or warrantee expressed or 
  4.    implied. This program is -not- in the public domain. */
  5. /* This program uses 3D texture coordinates to introduce
  6.    "sifting" effects to warp a static mesh of textured
  7.    geometry.  The third texture coordinate encodes a shifting
  8.    quantity through the mesh.  By updating the texture matrix,
  9.    the texture coordinates can be shifted based on this
  10.    third texture coordinate.  You'll notice the face seems
  11.    to have local vortexes scattered over the image that
  12.    warp the image.  While the texture coordinates look dynamic,
  13.    they are indeed quite static (frozen in a display list) and
  14.    it is just the texture matrix that is changing to shift
  15.    the final 2D texture coordinates. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <math.h>       /* for cos(), sin(), and sqrt() */
  20. #include <GL/glut.h>
  21. extern unsigned char mjk_image[];
  22. extern int mjk_depth;
  23. extern int mjk_height;
  24. extern int mjk_width;
  25. float tick1 = 0;
  26. float tick2 = 0;
  27. float angle;
  28. float size = 0.4;
  29. int set_timeout = 0;
  30. int visible = 0;
  31. int sifting = 1;
  32. int scaling = 0;
  33. int interval = 100;
  34. void
  35. animate(int value)
  36. {
  37.   if (visible) {
  38.     if (sifting || scaling) {
  39.       if (value) {
  40.         if (sifting) {
  41.           tick1 += 4 * (interval / 100.0);
  42.           angle = ((int) tick1) % 360;
  43.         }
  44.         if (scaling) {
  45.           tick2 += 2 * (interval / 100.0);
  46.           size = .7 - .5 * sin(tick2 / 20.0);
  47.         }
  48.       }
  49.       glutPostRedisplay();
  50.       set_timeout = 1;
  51.     }
  52.   }
  53. }
  54. /* Setup display list with "frozen" 3D texture coordinates. */
  55. void
  56. generateTexturedSurface(void)
  57. {
  58.   static GLfloat data[8] =
  59.   {0, 1, 0, -1};
  60.   int i, j;
  61. #define COLS 12
  62. #define ROWS 12
  63. #define TILE_TEX_W (1.0/COLS)
  64. #define TILE_TEX_H (1.0/ROWS)
  65.   glNewList(1, GL_COMPILE);
  66.   glTranslatef(-COLS / 2.0 + .5, -ROWS / 2.0 + .5, 0);
  67.   for (j = 0; j < ROWS; j++) {
  68.     glBegin(GL_QUAD_STRIP);
  69.     for (i = 0; i < COLS; i++) {
  70.       glTexCoord3f(i * TILE_TEX_W, j * TILE_TEX_H, data[(i + j) % 4]);
  71.       glVertex2f(i - .5, j - .5);
  72.       glTexCoord3f(i * TILE_TEX_W, (j + 1) * TILE_TEX_H, data[(i + j + 1) % 4]);
  73.       glVertex2f(i - .5, j + .5);
  74.     }
  75.     glTexCoord3f((i + 1) * TILE_TEX_W, j * TILE_TEX_H, data[(i + j) % 4]);
  76.     glVertex2f(i + .5, j - .5);
  77.     glTexCoord3f((i + 1) * TILE_TEX_W, (j + 1) * TILE_TEX_H, data[(i + j + 1) % 4]);
  78.     glVertex2f(i + .5, j + .5);
  79.     glEnd();
  80.   }
  81.   glEndList();
  82. }
  83. /* Construct an identity matrix except that the third coordinate
  84.    can be used to "sift" the X and Y coordinates. */
  85. void
  86. makeSift(GLfloat m[16], float xsift, float ysift)
  87. {
  88.   m[0 + 4 * 0] = 1;
  89.   m[0 + 4 * 1] = 0;
  90.   m[0 + 4 * 2] = xsift;
  91.   m[0 + 4 * 3] = 0;
  92.   m[1 + 4 * 0] = 0;
  93.   m[1 + 4 * 1] = 1;
  94.   m[1 + 4 * 2] = ysift;
  95.   m[1 + 4 * 3] = 0;
  96.   m[2 + 4 * 0] = 0;
  97.   m[2 + 4 * 1] = 0;
  98.   m[2 + 4 * 2] = 1;
  99.   m[2 + 4 * 3] = 0;
  100.   m[3 + 4 * 0] = 0;
  101.   m[3 + 4 * 1] = 0;
  102.   m[3 + 4 * 2] = 0;
  103.   m[3 + 4 * 3] = 1;
  104. }
  105. void
  106. redraw(void)
  107. {
  108.   int begin, end, elapsed;
  109.   GLfloat matrix[16];
  110.   if (set_timeout) {
  111.     begin = glutGet(GLUT_ELAPSED_TIME);
  112.   }
  113.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  114.   glPushMatrix();
  115.   glScalef(size, size, size);
  116.   glMatrixMode(GL_TEXTURE);
  117.   makeSift(matrix, 0.02 * cos(tick1 / 40.0), 0.02 * sin(tick1 / 15.0));
  118.   glLoadMatrixf(matrix);
  119.   glMatrixMode(GL_MODELVIEW);
  120.   glCallList(1);
  121.   glPopMatrix();
  122.   glutSwapBuffers();
  123.   if (set_timeout) {
  124.     set_timeout = 0;
  125.     end = glutGet(GLUT_ELAPSED_TIME);
  126.     elapsed = end - begin;
  127.     if (elapsed > interval) {
  128.       glutTimerFunc(0, animate, 1);
  129.     } else {
  130.       glutTimerFunc(interval - elapsed, animate, 1);
  131.     }
  132.   }
  133. }
  134. int width;
  135. int height;
  136. int depth;
  137. unsigned char *bits;
  138. void
  139. visibility(int state)
  140. {
  141.   if (state == GLUT_VISIBLE) {
  142.     visible = 1;
  143.     animate(0);
  144.   } else {
  145.     visible = 0;
  146.   }
  147. }
  148. void
  149. minify_select(int value)
  150. {
  151.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, value);
  152.   gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height,
  153.     GL_RGB, GL_UNSIGNED_BYTE, bits);
  154.   glutPostRedisplay();
  155. }
  156. void
  157. rate_select(int value)
  158. {
  159.   interval = value;
  160. }
  161. void
  162. menu_select(int value)
  163. {
  164.   switch (value) {
  165.   case 1:
  166.     sifting = !sifting;
  167.     if (sifting)
  168.       animate(0);
  169.     break;
  170.   case 2:
  171.     scaling = !scaling;
  172.     if (scaling)
  173.       animate(0);
  174.     break;
  175.   case 666:
  176.     exit(0);
  177.   }
  178. }
  179. int
  180. main(int argc, char **argv)
  181. {
  182.   int minify_menu, rate_menu;
  183.   glutInit(&argc, argv);
  184.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  185.   glutCreateWindow("mjksift");
  186.   glutDisplayFunc(redraw);
  187.   glMatrixMode(GL_PROJECTION);
  188.   gluPerspective( /* field of view in degree */ 40.0,
  189.   /* aspect ratio */ 1.0,
  190.     /* Z near */ 1.0, /* Z far */ 70.0);
  191.   glMatrixMode(GL_MODELVIEW);
  192.   gluLookAt(0.0, 0.0, 5.0,  /* eye is at (0,0,30) */
  193.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  194.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  195.   depth = mjk_depth;
  196.   width = mjk_width;
  197.   height = mjk_height;
  198.   bits = mjk_image;
  199.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  200.   gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height,
  201.     GL_RGB, GL_UNSIGNED_BYTE, bits);
  202.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  203.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  204.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  205.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  206.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  207.   glEnable(GL_TEXTURE_2D);
  208.   glutVisibilityFunc(visibility);
  209.   minify_menu = glutCreateMenu(minify_select);
  210.   glutAddMenuEntry("Nearest", GL_NEAREST);
  211.   glutAddMenuEntry("Linear", GL_LINEAR);
  212.   glutAddMenuEntry("Nearest mipmap nearest", GL_NEAREST_MIPMAP_NEAREST);
  213.   glutAddMenuEntry("Linear mipmap nearest", GL_LINEAR_MIPMAP_NEAREST);
  214.   glutAddMenuEntry("Nearest mipmap linear", GL_NEAREST_MIPMAP_LINEAR);
  215.   glutAddMenuEntry("Linear mipmap linear", GL_LINEAR_MIPMAP_LINEAR);
  216.   rate_menu = glutCreateMenu(rate_select);
  217.   glutAddMenuEntry(" 2/sec", 500);
  218.   glutAddMenuEntry(" 6/sec", 166);
  219.   glutAddMenuEntry("10/sec", 100);
  220.   glutAddMenuEntry("20/sec", 50);
  221.   glutAddMenuEntry("30/sec", 33);
  222.   glutAddMenuEntry("60/sec", 16);
  223.   glutCreateMenu(menu_select);
  224.   glutAddMenuEntry("Toggle sifting", 1);
  225.   glutAddMenuEntry("Toggle scaling", 2);
  226.   glutAddSubMenu("Minimum frame rate", rate_menu);
  227.   glutAddSubMenu("Minify modes", minify_menu);
  228.   glutAddMenuEntry("Quit", 666);
  229.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  230.   menu_select(3);
  231.   generateTexturedSurface();
  232.   glutMainLoop();
  233.   return 0;             /* ANSI C requires main to return int. */
  234. }