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

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. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <math.h>       /* for cos(), sin(), and sqrt() */
  9. #include <GL/glut.h>
  10. extern unsigned char mjk_image[];
  11. extern int mjk_depth;
  12. extern int mjk_height;
  13. extern int mjk_width;
  14. float tick1 = 0;
  15. float tick2 = 0;
  16. float angle;
  17. float size;
  18. int set_timeout = 0;
  19. int visible = 0;
  20. int spinning = 1;
  21. int scaling = 1;
  22. int interval = 100;
  23. #define CUBE 1
  24. #define SQUARES 2
  25. #define DRUM 3
  26. int mode = SQUARES;
  27. void
  28. animate(int value)
  29. {
  30.   if (visible) {
  31.     if (spinning || scaling) {
  32.       if (value) {
  33.         if (spinning) {
  34.           tick1 += 4 * (interval / 100.0);
  35.           angle = ((int) tick1) % 360;
  36.         }
  37.         if (scaling) {
  38.           tick2 += 2 * (interval / 100.0);
  39.           size = .7 - .5 * sin(tick2 / 20.0);
  40.         }
  41.       }
  42.       glutPostRedisplay();
  43.       set_timeout = 1;
  44.     }
  45.   }
  46. }
  47. #define TIMEDELTA(dest, src1, src2) { 
  48.         if(((dest).tv_usec = (src1).tv_usec - (src2).tv_usec) < 0) {
  49.               (dest).tv_usec += 1000000;
  50.               (dest).tv_sec = (src1).tv_sec - (src2).tv_sec - 1;
  51.         } else  (dest).tv_sec = (src1).tv_sec - (src2).tv_sec;  }
  52. void
  53. redraw(void)
  54. {
  55.   int begin, end, elapsed;
  56.   int i, j;
  57.   float amplitude;
  58.   if (set_timeout) {
  59.     begin = glutGet(GLUT_ELAPSED_TIME);
  60.   }
  61.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  62.   glPushMatrix();
  63.   if (mode != DRUM) {
  64.     glScalef(size, size, size);
  65.   }
  66.   switch (mode) {
  67.   case SQUARES:
  68. #define COLS 6
  69. #define TILE_TEX_W (1.0/COLS)
  70. #define ROWS 6
  71. #define TILE_TEX_H (1.0/ROWS)
  72.     glTranslatef(-COLS / 2.0 + .5, -ROWS / 2.0 + .5, 0);
  73.     for (i = 0; i < COLS; i++) {
  74.       for (j = 0; j < ROWS; j++) {
  75.         glPushMatrix();
  76.         glTranslatef(i, j, 0);
  77.         glRotatef(angle, 0, 1, 1);
  78.         glBegin(GL_QUADS);
  79.         glTexCoord2f(i * TILE_TEX_W, j * TILE_TEX_H);
  80.         glVertex2f(-.5, -.5);
  81.         glTexCoord2f((i + 1) * TILE_TEX_W, j * TILE_TEX_H);
  82.         glVertex2f(.5, -.5);
  83.         glTexCoord2f((i + 1) * TILE_TEX_W, (j + 1) * TILE_TEX_H);
  84.         glVertex2f(.5, .5);
  85.         glTexCoord2f(i * TILE_TEX_W, (j + 1) * TILE_TEX_H);
  86.         glVertex2f(-.5, .5);
  87.         glEnd();
  88.         glPopMatrix();
  89.       }
  90.     }
  91.     break;
  92.   case DRUM:
  93. #undef COLS
  94. #undef TILE_TEX_W
  95. #undef ROWS
  96. #undef TILE_TEX_H
  97. #define COLS 12
  98. #define TILE_TEX_W (1.0/COLS)
  99. #define ROWS 12
  100. #define TILE_TEX_H (1.0/ROWS)
  101.     glRotatef(angle, 0, 0, 1);
  102.     glTranslatef(-COLS / 2.0 + .5, -ROWS / 2.0 + .5, 0);
  103.     amplitude = 0.4 * sin(tick2 / 6.0);
  104.     for (i = 0; i < COLS; i++) {
  105.       for (j = 0; j < ROWS; j++) {
  106. #define Z(x,y) (((COLS-(x))*(x) + (ROWS-(y))*(y)) * amplitude) - 28.0
  107.         glPushMatrix();
  108.         glTranslatef(i, j, 0);
  109.         glBegin(GL_QUADS);
  110.         glTexCoord2f(i * TILE_TEX_W, j * TILE_TEX_H);
  111.         glVertex3f(-.5, -.5, Z(i, j));
  112.         glTexCoord2f((i + 1) * TILE_TEX_W, j * TILE_TEX_H);
  113.         glVertex3f(.5, -.5, Z(i + 1, j));
  114.         glTexCoord2f((i + 1) * TILE_TEX_W, (j + 1) * TILE_TEX_H);
  115.         glVertex3f(.5, .5, Z(i + 1, j + 1));
  116.         glTexCoord2f(i * TILE_TEX_W, (j + 1) * TILE_TEX_H);
  117.         glVertex3f(-.5, .5, Z(i, j + 1));
  118.         glEnd();
  119.         glPopMatrix();
  120.       }
  121.     }
  122.     break;
  123.   case CUBE:
  124.     glRotatef(angle, 0, 1, 0);
  125.     glBegin(GL_QUADS);
  126.     /* front */
  127.     glTexCoord2f(0.0, 0.0);
  128.     glVertex3f(-1.0, -1.0, 1.0);
  129.     glTexCoord2f(1.0, 0.0);
  130.     glVertex3f(1.0, -1.0, 1.0);
  131.     glTexCoord2f(1.0, 1.0);
  132.     glVertex3f(1.0, 1.0, 1.0);
  133.     glTexCoord2f(0.0, 1.0);
  134.     glVertex3f(-1.0, 1.0, 1.0);
  135.     /* back */
  136.     glTexCoord2f(0.0, 1.0);
  137.     glVertex3f(-1.0, 1.0, -1.0);
  138.     glTexCoord2f(1.0, 1.0);
  139.     glVertex3f(1.0, 1.0, -1.0);
  140.     glTexCoord2f(1.0, 0.0);
  141.     glVertex3f(1.0, -1.0, -1.0);
  142.     glTexCoord2f(0.0, 0.0);
  143.     glVertex3f(-1.0, -1.0, -1.0);
  144.     /* left */
  145.     glTexCoord2f(0.0, 0.0);
  146.     glVertex3f(-1.0, -1.0, -1.0);
  147.     glTexCoord2f(1.0, 0.0);
  148.     glVertex3f(-1.0, -1.0, 1.0);
  149.     glTexCoord2f(1.0, 1.0);
  150.     glVertex3f(-1.0, 1.0, 1.0);
  151.     glTexCoord2f(0.0, 1.0);
  152.     glVertex3f(-1.0, 1.0, -1.0);
  153.     /* right */
  154.     glTexCoord2f(0.0, 1.0);
  155.     glVertex3f(1.0, 1.0, -1.0);
  156.     glTexCoord2f(1.0, 1.0);
  157.     glVertex3f(1.0, 1.0, 1.0);
  158.     glTexCoord2f(1.0, 0.0);
  159.     glVertex3f(1.0, -1.0, 1.0);
  160.     glTexCoord2f(0.0, 0.0);
  161.     glVertex3f(1.0, -1.0, -1.0);
  162.     glEnd();
  163.   }
  164.   glPopMatrix();
  165.   glutSwapBuffers();
  166.   if (set_timeout) {
  167.     set_timeout = 0;
  168.     end = glutGet(GLUT_ELAPSED_TIME);
  169.     elapsed = end - begin;
  170.     if (elapsed > interval) {
  171.       glutTimerFunc(0, animate, 1);
  172.     } else {
  173.       glutTimerFunc(interval - elapsed, animate, 1);
  174.     }
  175.   }
  176. }
  177. int width;
  178. int height;
  179. int depth;
  180. unsigned char *bits;
  181. void
  182. visibility(int state)
  183. {
  184.   if (state == GLUT_VISIBLE) {
  185.     visible = 1;
  186.     animate(0);
  187.   } else {
  188.     visible = 0;
  189.   }
  190. }
  191. void
  192. minify_select(int value)
  193. {
  194.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, value);
  195.   gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height,
  196.     GL_RGB, GL_UNSIGNED_BYTE, bits);
  197.   glutPostRedisplay();
  198. }
  199. void
  200. rate_select(int value)
  201. {
  202.   interval = value;
  203. }
  204. void
  205. menu_select(int value)
  206. {
  207.   switch (value) {
  208.   case 1:
  209.     spinning = !spinning;
  210.     if (spinning)
  211.       animate(0);
  212.     break;
  213.   case 2:
  214.     scaling = !scaling;
  215.     if (scaling)
  216.       animate(0);
  217.     break;
  218.   case 3:
  219.     mode++;
  220.     if (mode > DRUM)
  221.       mode = CUBE;
  222.     switch (mode) {
  223.     case CUBE:
  224.       glEnable(GL_CULL_FACE);
  225.       glDisable(GL_DEPTH_TEST);
  226.       break;
  227.     case SQUARES:
  228.       glDisable(GL_CULL_FACE);
  229.       glDisable(GL_DEPTH_TEST);
  230.       break;
  231.     case DRUM:
  232.       glEnable(GL_DEPTH_TEST);
  233.       glDisable(GL_CULL_FACE);
  234.       break;
  235.     }
  236.     glutPostRedisplay();
  237.     break;
  238.   case 666:
  239.     exit(0);
  240.   }
  241. }
  242. int
  243. main(int argc, char **argv)
  244. {
  245.   int minify_menu, rate_menu;
  246.   glutInit(&argc, argv);
  247.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  248.   glutCreateWindow("mjkwarp");
  249.   glutDisplayFunc(redraw);
  250.   glMatrixMode(GL_PROJECTION);
  251.   gluPerspective( /* field of view in degree */ 40.0,
  252.   /* aspect ratio */ 1.0,
  253.     /* Z near */ 1.0, /* Z far */ 70.0);
  254.   glMatrixMode(GL_MODELVIEW);
  255.   gluLookAt(0.0, 0.0, 5.0,  /* eye is at (0,0,30) */
  256.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  257.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  258.   depth = mjk_depth;
  259.   width = mjk_width;
  260.   height = mjk_height;
  261.   bits = mjk_image;
  262.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  263.   gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height,
  264.     GL_RGB, GL_UNSIGNED_BYTE, bits);
  265.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  266.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  267.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  268.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  269.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  270.   glEnable(GL_TEXTURE_2D);
  271.   glutVisibilityFunc(visibility);
  272.   minify_menu = glutCreateMenu(minify_select);
  273.   glutAddMenuEntry("Nearest", GL_NEAREST);
  274.   glutAddMenuEntry("Linear", GL_LINEAR);
  275.   glutAddMenuEntry("Nearest mipmap nearest", GL_NEAREST_MIPMAP_NEAREST);
  276.   glutAddMenuEntry("Linear mipmap nearest", GL_LINEAR_MIPMAP_NEAREST);
  277.   glutAddMenuEntry("Nearest mipmap linear", GL_NEAREST_MIPMAP_LINEAR);
  278.   glutAddMenuEntry("Linear mipmap linear", GL_LINEAR_MIPMAP_LINEAR);
  279.   rate_menu = glutCreateMenu(rate_select);
  280.   glutAddMenuEntry(" 2/sec", 500);
  281.   glutAddMenuEntry(" 6/sec", 166);
  282.   glutAddMenuEntry("10/sec", 100);
  283.   glutAddMenuEntry("20/sec", 50);
  284.   glutAddMenuEntry("30/sec", 33);
  285.   glutAddMenuEntry("60/sec", 16);
  286.   glutCreateMenu(menu_select);
  287.   glutAddMenuEntry("Toggle spinning", 1);
  288.   glutAddMenuEntry("Toggle scaling", 2);
  289.   glutAddMenuEntry("Switch mode", 3);
  290.   glutAddSubMenu("Minimum frame rate", rate_menu);
  291.   glutAddSubMenu("Minify modes", minify_menu);
  292.   glutAddMenuEntry("Quit", 666);
  293.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  294.   menu_select(3);
  295.   glutMainLoop();
  296.   return 0;             /* ANSI C requires main to return int. */
  297. }