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

GIS编程

开发平台:

Visual C++

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <GL/glut.h>
  6. #include "texture.h"
  7. /* Some <math.h> files do not define M_PI... */
  8. #ifndef M_PI
  9. #define M_PI 3.14159265358979323846
  10. #endif
  11. #ifndef __sgi
  12. /* Most math.h's do not define float versions of the trig functions. */
  13. #define sinf sin
  14. #define cosf cos
  15. #define atan2f atan2
  16. #endif
  17. /* taken from skyfly */
  18. static float paper_plane_vertexes[] = {
  19. /*Nx  Ny  Nz   Vx     Vy    Vz */
  20. /* ----------------------------    Top view of plane, middle stretched open  */
  21.  0.2, 0., .98, -.10,    0,  .02,/* vertex #'s      4 (.48,0,-.06)            */
  22.  0., 0., 1.,   -.36,  .20, -.04,/*                 .                         */
  23.  0., 0., 1.,    .36,  .01,    0,/*                ...                        */
  24.  0., 0.,-1.,   -.32,  .02,    0,/*                 .             +X          */
  25.  0., 1., 0.,    .48,    0, -.06,/*               2 . 6,8          ^          */
  26.  0., 1., 0.,   -.30,    0, -.12,/*               . . .            |          */
  27.  0.,-1., 0.,    .36, -.01,    0,/*              .. . ..           |          */
  28.  0.,-1., 0.,   -.32, -.02,    0,/*               . . .            |          */
  29.  0., 0.,-1.,    .36, -.01,    0,/*             . . . . .  +Y<-----*          */
  30.  0., 0.,-1.,   -.36, -.20, -.04,/*               . . .     for this picture  */
  31.  -0.2, 0., .98,  -.10,  0,  .02,/*            .  . . .  .  coord system rot. */
  32.  -0.2, 0., -.98, -.10,  0,  .02,/*               . . .     90 degrees        */
  33.  0., 0., -1.,  -.36,  .20, -.04,/*           .   . . .   .                   */
  34.  0., 0., -1.,   .36,  .01,    0,/*               . # .           # marks     */
  35.  0., 0., 1.,   -.32,  .02,    0,/*          .    . . .    .   (0,0) origin   */
  36.  0., -1., 0.,   .48,    0, -.06,/*               . . .         (z=0 at top   */
  37.  0., -1., 0.,  -.30,    0, -.12,/*         .     0 . 10    .    of plane)    */
  38.  0.,1., 0.,     .36, -.01,    0,/*             . . . . .                     */
  39.  0.,1., 0.,    -.32, -.02,    0,/*        .  .   . . .   .  .                */
  40.  0., 0.,1.,     .36, -.01,    0,/*         .     . . .     .                 */
  41.  0., 0.,1.,    -.36, -.20, -.04,/*       1.......3.5.7.......9               */
  42.  0.2, 0., -.98,  -.10,  0,  .02,/* (-.36,.2,-.04)                            */
  43. };
  44. #define MAX_TIME (2*196)
  45. #define MAX_VAPOR 1024
  46. int vapors = 0;
  47. static struct vapor {
  48.     float x, y, z;
  49.     int time;
  50.     float size;
  51. } vapor[MAX_VAPOR];
  52. static float ttrans[2];
  53. static float scale = 1.;
  54. static float transx, transy, rotx, roty;
  55. static int ox = -1, oy = -1;
  56. static int show_t = 0;
  57. static int mot;
  58. #define PAN 1
  59. #define ROT 2
  60. static int _time = 1;
  61. static float _x = -1.;
  62. static float _y = .75;
  63. void
  64. pan(int x, int y) {
  65.     transx +=  (x-ox)/500.;
  66.     transy -= (y-oy)/500.;
  67.     ox = x; oy = y;
  68.     glutPostRedisplay();
  69. }
  70. void
  71. rotate(int x, int y) {
  72.     rotx += x-ox;
  73.     if (rotx > 360.) rotx -= 360.;
  74.     else if (rotx < -360.) rotx += 360.;
  75.     roty += y-oy;
  76.     if (roty > 360.) roty -= 360.;
  77.     else if (roty < -360.) roty += 360.;
  78.     ox = x; oy = y;
  79.     glutPostRedisplay();
  80. }
  81. void
  82. motion(int x, int y) {
  83.     if (mot == PAN) pan(x, y);
  84.     else if (mot == ROT) rotate(x,y);
  85. }
  86. void
  87. mouse(int button, int state, int x, int y) {
  88.     if(state == GLUT_DOWN) {
  89. switch(button) {
  90. case GLUT_LEFT_BUTTON:
  91.     mot = PAN;
  92.     motion(ox = x, oy = y);
  93.     break;
  94. case GLUT_MIDDLE_BUTTON:
  95.     mot = ROT;
  96.     motion(ox = x, oy = y);
  97.     break;
  98. case GLUT_RIGHT_BUTTON:
  99.     break;
  100. }
  101.     } else if (state == GLUT_UP) {
  102. mot = 0;
  103.     }
  104. }
  105. void toggle_t(void) {
  106.     show_t ^= 1;
  107. }
  108. void wire(void) {
  109.     static int w;
  110.     if (w ^= 1)
  111. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  112.     else
  113. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  114. }
  115. void light(void) {
  116.     static int l;
  117.     if (l ^= 1)
  118. glEnable(GL_LIGHTING);
  119.     else
  120. glDisable(GL_LIGHTING);
  121. }
  122. void up(void) { scale += .1; }
  123. void down(void) { scale -= .1; }
  124. void
  125. draw_plane(void) {
  126.     glEnable(GL_LIGHTING);
  127.     glShadeModel(GL_FLAT);
  128.     glRotatef(-120.f, 1.f, 0.f, 0.f);
  129. #define nv(p) glNormal3fv(paper_plane_vertexes+6*p); glVertex3fv(paper_plane_vertexes+6*p+3)
  130.     glEnable(GL_CULL_FACE);
  131.     glCullFace(GL_FRONT);
  132.     glBegin(GL_TRIANGLE_STRIP);
  133.     nv(0); nv(1); nv(2); nv(3); nv(4); nv(5); nv(6); nv(7); nv(8); nv(9); nv(10);
  134.     glEnd();
  135.     glCullFace(GL_BACK);
  136.     glBegin(GL_TRIANGLE_STRIP);
  137.     nv(11); nv(12); nv(13); nv(14); nv(15); nv(16); nv(17); nv(18); nv(19); nv(20); nv(21);
  138.     glEnd();
  139.     glDisable(GL_CULL_FACE);
  140.     glShadeModel(GL_SMOOTH);
  141.     glDisable(GL_LIGHTING);
  142. #undef nv
  143. }
  144. void
  145. add_vapor(void) {
  146.     int i;
  147.     /* garbage collect */
  148.     for(i = 0; i < vapors; i++)
  149. if (_time - vapor[i].time > MAX_TIME) {
  150.     memcpy(vapor+i, vapor+i+1, (vapors-i-1)*sizeof vapor[0]);
  151.     vapors--;
  152. }
  153.     if (vapors >= MAX_VAPOR) {
  154. printf("max_vaporsn");
  155. return;
  156.     }
  157.     vapor[vapors].time = _time;
  158.     vapor[vapors].x = -.6f + _x;
  159.     vapor[vapors].y = _y;
  160.     vapor[vapors].z = 0.f;
  161.     vapor[vapors].size = 1.f;
  162.     vapors++;
  163.     if (_x > 8.5) {
  164. _y = .75f;
  165. _x = -2.f;
  166. vapors = 0;
  167.     }
  168. }
  169. void
  170. animate(void) {
  171.     static int cnt = 0;
  172.     ttrans[0] += .01;
  173.     if (ttrans[0] == 1.0) ttrans[0] = 0;
  174.     ttrans[1] += .005;
  175.     if (ttrans[1] == 1.0) ttrans[1] = 0;
  176.     _y -= .01f;
  177.     _x +=.025f;
  178.     if (cnt++ & 1) add_vapor();
  179.     _time++;
  180.     glutPostRedisplay();
  181. }
  182. void help(void) {
  183.     printf("Usage: vapor [image]n");
  184.     printf("'h'            - helpn");
  185.     printf("'l'            - toggle lightingn");
  186.     printf("'t'            - toggle wireframen");
  187.     printf("'UP'           - scale upn");
  188.     printf("'DOWN'         - scale downn");
  189.     printf("left mouse     - pann");
  190.     printf("middle mouse   - rotaten");
  191. }
  192. void init(char *filename) {
  193.     static GLfloat plane_mat[] = { 1.f, 1.f, .2f, 1.f };
  194.     static unsigned *image;
  195.     static int width, height, components, i;
  196.     if (filename) {
  197. image = read_texture(filename, &width, &height, &components);
  198. if (image == NULL) {
  199.     fprintf(stderr, "Error: Can't load image file "%s".n",
  200.     filename);
  201.     exit(EXIT_FAILURE);
  202. } else {
  203.     printf("%d x %d image loadedn", width, height);
  204. }
  205. if (components != 2 && components != 4) {
  206.     printf("must be an rgba or la imagen");
  207.     exit(EXIT_FAILURE);
  208. }
  209. for(i = 0; i < width*height; i++)
  210. image[i] = image[i] | 0xffffff00;
  211.     } else {
  212. int i, j;
  213. unsigned char *img;
  214. components = 4; width = height = 512;
  215. image = (unsigned *) malloc(width*height*sizeof(unsigned));
  216. img = (unsigned char *)image;
  217. for (j = 0; j < height; j++)
  218.     for (i = 0; i < width; i++) {
  219. int w2 = width/2, h2 = height/2;
  220. if (i & 32)
  221.     img[4*(i+j*width)+0] = 0xff;
  222. else
  223.     img[4*(i+j*width)+1] = 0xff;
  224. if (j&32)
  225.     img[4*(i+j*width)+2] = 0xff;
  226. if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 &&
  227.     (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff;
  228.     }
  229.     }
  230.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  231.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  232.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  233.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  234.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  235.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  236.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
  237.     glEnable(GL_TEXTURE_2D);
  238.     glMatrixMode(GL_PROJECTION);
  239.     glLoadIdentity();
  240.     gluPerspective(50.,1.,.1,10.);
  241.     glMatrixMode(GL_MODELVIEW);
  242.     glLoadIdentity();
  243.     glTranslatef(0.,0.,-5.5);
  244.     glEnable(GL_LIGHT0);
  245.     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, plane_mat);
  246.     glClearColor(0.1, 0.1, 0.6, 1.0);
  247.     glEnable(GL_BLEND);
  248.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  249.     glEnable(GL_ALPHA_TEST);
  250.     glAlphaFunc(GL_GREATER, 0./255.);
  251.     glEnable(GL_DEPTH_TEST);
  252. }
  253. void
  254. draw_vapor(void) {
  255.     int i;
  256.     float intensity = .9f;
  257.     float t;
  258.     struct vapor *v;
  259.     glDepthMask(0);
  260.     glEnable(GL_TEXTURE_2D);
  261.     for(i = 0; i < vapors; i++) {
  262. v = vapor+i;
  263. t = _time - v->time;
  264. glPushMatrix();
  265. glTranslatef(v->x, v->y, v->z);
  266. glScalef(.5*(t+40)/MAX_TIME, .5*(t+40)/MAX_TIME, 1.);
  267. glColor4f(intensity,intensity,intensity,10./(t+0.f));
  268. glBegin(GL_QUADS);
  269. glTexCoord2f(0, 0); glVertex3f(-1., -1., -0.);
  270. glTexCoord2f(0, 1); glVertex3f(-1., 1.,  0.);
  271. glTexCoord2f(1, 1); glVertex3f( 1., 1.,  0.);
  272. glTexCoord2f(1, 0); glVertex3f( 1., -1., -0.);
  273. glEnd();
  274. if (show_t) {
  275.     glDisable(GL_TEXTURE_2D);
  276.     glColor4f(0.,0.,0.,1.0);
  277.     glBegin(GL_LINE_LOOP);
  278.     glVertex3f(-1., -1., -0.);
  279.     glVertex3f(-1., 1.,  0.);
  280.     glVertex3f( 1., 1.,  0.);
  281.     glVertex3f( 1., -1., -0.);
  282.     glEnd();
  283.     glEnable(GL_TEXTURE_2D);
  284. }
  285. glPopMatrix();
  286.     }
  287.     glDisable(GL_TEXTURE_2D);
  288.     glDepthMask(1);
  289. }
  290. void display(void) {
  291.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  292.     glPushMatrix();
  293.     glPushMatrix();
  294.     glColor4f(1.f,1.f,.2f,1.f);
  295.     glTranslatef(_x, _y+.05f, 0.f);
  296.     glScalef(2.f,2.f,2.f);
  297.     glRotatef(-10.f, 0.f, 0.f, 1.f);
  298.     draw_plane();
  299.     glPopMatrix();
  300.     draw_vapor();
  301.     glPopMatrix();
  302.     glutSwapBuffers();
  303. }
  304. void reshape(int w, int h) {
  305.     glViewport(0, 0, w, h);
  306. }
  307. /*ARGSUSED1*/
  308. void
  309. key(unsigned char key, int x, int y) {
  310.     switch(key) {
  311.     case 'l': light(); break;
  312.     case 't': toggle_t(); break;
  313.     case 'w': wire(); break;
  314.     case 'h': help(); break;
  315.     case '33': exit(EXIT_SUCCESS); break;
  316.     default: break;
  317.     }
  318.     glutPostRedisplay();
  319. }
  320. /*ARGSUSED1*/
  321. void
  322. special(int key, int x, int y) {
  323.     switch(key) {
  324.     case GLUT_KEY_UP: up(); break;
  325.     case GLUT_KEY_DOWN: down(); break;
  326.     }
  327. }
  328. int main(int argc, char** argv) {
  329.     glutInitWindowSize(256, 256);
  330.     glutInit(&argc, argv);
  331.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  332.     (void)glutCreateWindow(argv[0]);
  333.     init(argc == 1 ? "../data/smoke.bw" : argv[1]);
  334.     glutDisplayFunc(display);
  335.     glutKeyboardFunc(key);
  336.     glutSpecialFunc(special);
  337.     glutReshapeFunc(reshape);
  338.     glutMouseFunc(mouse);
  339.     glutMotionFunc(motion);
  340.     glutIdleFunc(animate);
  341.     glutMainLoop();
  342.     return 0;
  343. }