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

GIS编程

开发平台:

Visual C++

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6. /* Some <math.h> files do not define M_PI... */
  7. #ifndef M_PI
  8. #define M_PI 3.14159265358979323846
  9. #endif
  10. #ifndef __sgi
  11. /* Most math.h's do not define float versions of the math functions. */
  12. #define expf(x) ((float)exp((x)))
  13. #define sinf(x) ((float)sin((x)))
  14. #endif
  15. static int rgb;
  16. static int mesh = 1;
  17. static float ttrans[2];
  18. static float transx, transy, rotx, roty;
  19. static float amplitude = 0.03;
  20. static float freq = 5.0f;
  21. static float phase = .00003;
  22. static int ox = -1, oy = -1;
  23. static int show_t = 1;
  24. static int mot;
  25. #define PAN 1
  26. #define ROT 2
  27. void
  28. pan(int x, int y) {
  29.     transx +=  (x-ox)/500.;
  30.     transy -= (y-oy)/500.;
  31.     ox = x; oy = y;
  32.     glutPostRedisplay();
  33. }
  34. void
  35. rotate(int x, int y) {
  36.     rotx += x-ox;
  37.     if (rotx > 360.) rotx -= 360.;
  38.     else if (rotx < -360.) rotx += 360.;
  39.     roty += y-oy;
  40.     if (roty > 360.) roty -= 360.;
  41.     else if (roty < -360.) roty += 360.;
  42.     ox = x; oy = y;
  43.     glutPostRedisplay();
  44. }
  45. void
  46. motion(int x, int y) {
  47.     if (mot == PAN) pan(x, y);
  48.     else if (mot == ROT) rotate(x,y);
  49. }
  50. void
  51. mouse(int button, int state, int x, int y) {
  52.     if(state == GLUT_DOWN) {
  53. switch(button) {
  54. case GLUT_LEFT_BUTTON:
  55.     mot = PAN;
  56.     motion(ox = x, oy = y);
  57.     break;
  58. case GLUT_MIDDLE_BUTTON:
  59.     mot = ROT;
  60.     motion(ox = x, oy = y);
  61.     break;
  62. case GLUT_RIGHT_BUTTON:
  63.     break;
  64. }
  65.     } else if (state == GLUT_UP) {
  66. mot = 0;
  67.     }
  68. }
  69. void toggle_t(void) {
  70.     show_t ^= 1;
  71. }
  72. void ffunc(void) { freq *= 2.f; }
  73. void Ffunc(void) { freq /= 2.f; }
  74. void mfunc(void) { mesh ^= 1; }
  75. void wire(void) {
  76.     static int w;
  77.     if (w ^= 1) {
  78. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  79. glEnable(GL_BLEND);
  80.     } else {
  81. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  82. glDisable(GL_BLEND);
  83.     }
  84. }
  85. void light(void) {
  86.     static int l;
  87.     if (l ^= 1)
  88. glEnable(GL_LIGHTING);
  89.     else
  90. glDisable(GL_LIGHTING);
  91. }
  92. void up(void) { amplitude += .01; }
  93. void down(void) { amplitude -= .01; }
  94. void left(void) { phase -= .00001; }
  95. void right(void) { phase += .00001; }
  96. void
  97. animate(void) {
  98.     ttrans[0] += .005f;
  99.     if (ttrans[0] == 1.0f) ttrans[0] = 0.0f;
  100.     ttrans[1] -= .0025f;
  101.     if (ttrans[1] <= 0.0f) ttrans[1] = 1.0f;
  102.     glutPostRedisplay();
  103. }
  104. void xfunc(void) {
  105.     static state = 1;
  106.     glutIdleFunc((state ^= 1) ? animate : NULL);
  107. }
  108. void help(void) {
  109.     printf("Usage: water [image]n");
  110.     printf("'h'            - helpn");
  111.     printf("'l'            - toggle lightingn");
  112.     printf("'f'            - increase frequencyn");
  113.     printf("'F'            - decrease frequencyn");
  114.     printf("'m'            - toggle meshn");
  115.     printf("'t'            - toggle wireframen");
  116.     printf("'x'            - toggle water motionn");
  117.     printf("'UP'           - increase amplituden");
  118.     printf("'DOWN'         - decrease amplituden");
  119.     printf("'RIGHT'        - increase phase changen");
  120.     printf("'LEFT'         - decreae phase changen");
  121.     printf("left mouse     - pann");
  122.     printf("middle mouse   - rotaten");
  123. }
  124. void init(char *filename) {
  125.     GLfloat cloud_color[4] = { 1., 1., 1., 0., };
  126.     GLfloat fog_color[4], fog_density = 0.05, density, far_cull;
  127.     unsigned *image;
  128.     int width, height, components;
  129.     if (filename) {
  130. image = read_texture(filename, &width, &height, &components);
  131. if (image == NULL) {
  132.     fprintf(stderr, "Error: Can't load image file "%s".n",
  133.     filename);
  134.     exit(EXIT_FAILURE);
  135. } else {
  136.     printf("%d x %d image loadedn", width, height);
  137. }
  138. if (components < 3) rgb = 0;
  139.     } else {
  140. int i, j;
  141. unsigned char *img;
  142. components = 4; width = height = 512;
  143. image = (unsigned *) malloc(width*height*sizeof(unsigned));
  144. img = (unsigned char *)image;
  145. for (j = 0; j < height; j++)
  146.     for (i = 0; i < width; i++) {
  147. int w2 = width/2, h2 = height/2;
  148. if (i & 32)
  149.     img[4*(i+j*width)+0] = 0xff;
  150. else
  151.     img[4*(i+j*width)+1] = 0xff;
  152. if (j&32)
  153.     img[4*(i+j*width)+2] = 0xff;
  154. if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 &&
  155.     (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff;
  156.     }
  157.     }
  158.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  159.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  160.     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cloud_color);
  161.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  162.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  163.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  164.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  165.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  166.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  167.                  image);
  168.     glEnable(GL_TEXTURE_2D);
  169.     glMatrixMode(GL_PROJECTION);
  170.     glLoadIdentity();
  171.     gluPerspective(50.,1.,.1,far_cull = 10.);
  172.     glMatrixMode(GL_MODELVIEW);
  173.     glLoadIdentity();
  174.     glTranslatef(0.,0.,-5.5);
  175.     density = 1.- expf(-5.5 * fog_density * fog_density *
  176.       far_cull * far_cull);
  177. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  178. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  179.     density = MAX(MIN(density, 1.), 0.);
  180.     fog_color[0] = .23 + density *.57;
  181.     fog_color[1] = .35 + density *.45;
  182.     fog_color[2] = .78 + density *.22;
  183.     glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.f);
  184.     glFogi(GL_FOG_MODE, GL_EXP2);
  185.     glFogf(GL_FOG_DENSITY, fog_density);
  186.     glFogfv(GL_FOG_COLOR, fog_color);
  187.     if (fog_density > 0)
  188. glEnable(GL_FOG);
  189.     glLineWidth(2.0f);
  190.     glEnable(GL_LINE_SMOOTH);
  191.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  192. }
  193. void draw_mesh(void) {
  194.     if (mesh) {
  195. glBegin(GL_QUADS);
  196. glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f);
  197. glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f,  1.f);
  198. glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f,  1.f);
  199. glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f);
  200. glEnd();
  201.     } else {
  202. #define MESH 32
  203. int i, j;
  204. static float off;
  205. float d = 1.f/MESH;
  206. for(i = 0; i < MESH; i++) {
  207.     glBegin(GL_TRIANGLE_STRIP);
  208.     for(j = 0; j < MESH; j++) {
  209. float s = (float)j*d;
  210. float t = (float)i*d;
  211. float x = -1.0 + 2.f*s;
  212. float z = -1.0 + 2.f*t;
  213. float y = amplitude*sinf(freq*2.f*M_PI*t+off);
  214. glTexCoord2f(s, t); glVertex3f(x, y, z);
  215. s += d; t += d;
  216. x = -1.0 + 2.f*s;
  217. z = -1.0 + 2.f*t;
  218. y = amplitude*sinf(freq*2.f*M_PI*t+off);
  219. glTexCoord2f(s, t); glVertex3f(x, y, z);
  220. off += phase;
  221.     }
  222.     glEnd();
  223. }
  224.     }
  225. }
  226. void display(void) {
  227.     glClear(GL_COLOR_BUFFER_BIT);
  228.     glPushMatrix();
  229.     glTranslatef(transx, transy, 0.f);
  230.     glRotatef(rotx, 0., 1., 0.);
  231.     glRotatef(roty, 1., 0., 0.);
  232.     glScalef(10,1,10);
  233.     if (!rgb)
  234. glColor3f(.31, .41, .97);
  235.     else
  236. glColor3f(1.f,1.f,1.f);
  237.     glTranslatef(0.f,-1.f,0.f);
  238.     glMatrixMode(GL_TEXTURE);
  239.     glPushMatrix();
  240.     glTranslatef(ttrans[0], ttrans[1], 0.);
  241.     glScalef(10.f, 10.f,1.f);
  242.     draw_mesh();
  243.     glPopMatrix();
  244.     glMatrixMode(GL_MODELVIEW);
  245.     glPopMatrix();
  246.     glutSwapBuffers();
  247. }
  248. void reshape(int w, int h) {
  249.     glViewport(0, 0, w, h);
  250. }
  251. /*ARGSUSED1*/
  252. void
  253. key(unsigned char key, int x, int y) {
  254.     switch(key) {
  255.     case 'l': light(); break;
  256.     case 'f': ffunc(); break;
  257.     case 'F': Ffunc(); break;
  258.     case 't': toggle_t(); break;
  259.     case 'm': mfunc(); break;
  260.     case 'w': wire(); break;
  261.     case 'x': xfunc(); break;
  262.     case 'h': help(); break;
  263.     case '33': exit(EXIT_SUCCESS); break;
  264.     default: break;
  265.     }
  266.     glutPostRedisplay();
  267. }
  268. /*ARGSUSED1*/
  269. void
  270. special(int key, int x, int y) {
  271.     switch(key) {
  272.     case GLUT_KEY_UP: up(); break;
  273.     case GLUT_KEY_DOWN: down(); break;
  274.     case GLUT_KEY_LEFT: left(); break;
  275.     case GLUT_KEY_RIGHT:right(); break;
  276.     }
  277. }
  278. int main(int argc, char** argv) {
  279.     glutInitWindowSize(256, 256);
  280.     glutInit(&argc, argv);
  281.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
  282.     (void)glutCreateWindow(argv[0]);
  283.     init(argc == 1 ? "../data/water.bw" : argv[1]);
  284.     glutDisplayFunc(display);
  285.     glutKeyboardFunc(key);
  286.     glutSpecialFunc(special);
  287.     glutReshapeFunc(reshape);
  288.     glutMouseFunc(mouse);
  289.     glutMotionFunc(motion);
  290.     glutIdleFunc(animate);
  291.     glutMainLoop();
  292.     return 0;
  293. }