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

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 trig functions. */
  12. #define sinf sin
  13. #define cosf cos
  14. #define atan2f atan2
  15. #endif
  16. static int texture = 1;
  17. static float rot = 0;
  18. static float opacity = 1.0;
  19. static float intensity = 1.0;
  20. static float size = .001, delta = 0;
  21. static float scale = 1.;
  22. static float transx, transy, rotx, roty;
  23. static int ox = -1, oy = -1;
  24. static int mot = 0;
  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_RIGHT_BUTTON:
  59.     mot = ROT;
  60.     motion(ox = x, oy = y);
  61.     break;
  62. case GLUT_MIDDLE_BUTTON:
  63.     break;
  64. }
  65.     } else if (state == GLUT_UP) {
  66. mot = 0;
  67.     }
  68. }
  69. void afunc(void) {
  70.     static int state;
  71.     if (state ^= 1) {
  72. glAlphaFunc(GL_GREATER, .01);
  73. glEnable(GL_ALPHA_TEST);
  74.     } else {
  75. glDisable(GL_ALPHA_TEST);
  76.     }
  77. }
  78. void bfunc(void) {
  79.     static int state;
  80.     if (state ^= 1) {
  81. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  82. glEnable(GL_BLEND);
  83.     } else {
  84. glDisable(GL_BLEND);
  85.     }
  86. }
  87. void tfunc(void) {
  88.     texture ^= 1;
  89. }
  90. void up(void) { scale += .1; }
  91. void down(void) { scale -= .1; }
  92. void left(void) { intensity -= .05f; if (intensity < 0.f) intensity = 0.0f; }
  93. void right(void) { intensity += .05f; if (intensity > 1.f) intensity = 1.0f; }
  94. void help(void) {
  95.     printf("Usage: smoke [image]n");
  96.     printf("'h'            - helpn");
  97.     printf("'a'            - toggle alpha testn");
  98.     printf("'b'            - toggle blendn");
  99.     printf("'t'            - toggle texturingn");
  100.     printf("'UP'           - scale upn");
  101.     printf("'DOWN'         - scale downn");
  102.     printf("'LEFT'    - darkenn");
  103.     printf("'RIGHT'    - brightenn");
  104.     printf("left mouse     - pann");
  105.     printf("right mouse    - rotaten");
  106. }
  107. void init(char *filename) {
  108.     static unsigned *image;
  109.     static int width, height, components;
  110.     if (filename) {
  111. image = read_texture(filename, &width, &height, &components);
  112. if (image == NULL) {
  113.     fprintf(stderr, "Error: Can't load image file "%s".n",
  114.     filename);
  115.     exit(EXIT_FAILURE);
  116. } else {
  117.     printf("%d x %d image loadedn", width, height);
  118. }
  119. #if 0
  120. if (components == 1) {
  121.     GLubyte *p = (GLubyte *)image;
  122.     int i;
  123.     for (i = 0; i < width*height; i++) {
  124. p[i*4+3] = p[i*4+0];
  125.     }
  126.     components = 2;
  127. }
  128. #endif
  129. if (components != 2 && components != 4) {
  130.     printf("must be an RGBA or LA imagen");
  131.     exit(EXIT_FAILURE);
  132. }
  133.     } else {
  134. int i, j;
  135. unsigned char *img;
  136. components = 4; width = height = 512;
  137. image = (unsigned *) malloc(width*height*sizeof(unsigned));
  138. img = (unsigned char *)image;
  139. for (j = 0; j < height; j++)
  140.     for (i = 0; i < width; i++) {
  141. int w2 = width/2, h2 = height/2;
  142. if (i & 32)
  143.     img[4*(i+j*width)+0] = 0xff;
  144. else
  145.     img[4*(i+j*width)+1] = 0xff;
  146. if (j&32)
  147.     img[4*(i+j*width)+2] = 0xff;
  148. if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 &&
  149.     (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff;
  150.     }
  151.     }
  152.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  153.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  154.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  155.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  156.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  157.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  158.                  image);
  159.     glEnable(GL_TEXTURE_2D);
  160.     glMatrixMode(GL_PROJECTION);
  161.     glLoadIdentity();
  162.     gluPerspective(50.,1.,.1,20.);
  163.     glMatrixMode(GL_MODELVIEW);
  164.     glLoadIdentity();
  165.     glTranslatef(0.,0.,-5.5);
  166.     glClearColor(.25f, .25f, .75f, .25f);
  167.     glAlphaFunc(GL_GREATER, 0.016);
  168.     glEnable(GL_ALPHA_TEST);
  169.     glEnable(GL_BLEND);
  170.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  171.     glEnable(GL_DEPTH_TEST);
  172.     glEnable(GL_LIGHT0);
  173.     glEnable(GL_NORMALIZE);
  174. }
  175. void
  176. animate(void) {
  177.     if (delta > 8) {
  178. delta = 0.f;
  179. size = 0.f;
  180.         opacity = 1.f;
  181. rot = 0.f;
  182.     }
  183.     size += .02f;
  184.     delta += .03f;
  185.     rot += .9f;
  186.     opacity -= .005f;
  187.     glutPostRedisplay();
  188. }
  189. void
  190. cube(void) {
  191.     glBegin(GL_QUADS);
  192. glNormal3f(0.f, 0.f, -1.f);
  193. glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  194. glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  195. glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
  196. glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
  197. glNormal3f(0.f, 0.f, 1.f);
  198. glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
  199. glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
  200. glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  201. glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  202. glNormal3f(0.f, 1.f, 0.f);
  203. glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0, -1.0);
  204. glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0, -1.0);
  205. glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  206. glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  207. glNormal3f(0.f, -1.f, 0.f);
  208. glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  209. glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  210. glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0,  1.0);
  211. glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0,  1.0);
  212. glNormal3f( 1.f, 0.f, 0.f);
  213. glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  214. glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0, -1.0);
  215. glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  216. glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0,  1.0);
  217. glNormal3f(-1.f, 0.f, 0.f);
  218. glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  219. glTexCoord2f(1.0, 0.0); glVertex3f(-1.0,  1.0, -1.0);
  220. glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  221. glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0,  1.0);
  222.     glEnd();
  223. }
  224. static void calcMatrix(void);
  225. void display(void) {
  226.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  227.     glLoadIdentity();
  228. #define RAD(x) (((x)*M_PI)/180.)
  229.     gluLookAt(-sinf(RAD(rotx))*5.5,transy,cosf(RAD(rotx))*5.5, 0.,0.,0., 0.,1.,0.);
  230.     /* floor */
  231.     glColor4f(0.f,.2f,0.f,1.f);
  232.     glBegin(GL_POLYGON);
  233. glVertex3f(-4.0, -1.0, -4.0);
  234. glVertex3f( 4.0, -1.0, -4.0);
  235. glVertex3f( 4.0, -1.0,  4.0);
  236. glVertex3f(-4.0, -1.0,  4.0);
  237.     glEnd();
  238.     glEnable(GL_COLOR_MATERIAL);
  239.     glEnable(GL_LIGHTING);
  240.     glColor3f(.3f,.3f,.3f);
  241.     glPushMatrix();
  242.     glTranslatef(-1.f, -1.+.2f, -1.5f);
  243.     glScalef(.2f,.2f, .2f);
  244.     cube();
  245.     glDisable(GL_LIGHTING);
  246.     glPopMatrix();
  247.     glPushMatrix();
  248.     glTranslatef(delta/2.f-1.f, delta-1.f, -1.5f);
  249.     calcMatrix();
  250.     glScalef(size,size,1.);
  251.     if (texture) glEnable(GL_TEXTURE_2D);
  252.     glColor4f(intensity, intensity, intensity, opacity);
  253.     glRotatef(rot, 0., 0., 1.);
  254.     glDepthMask(0);
  255.     glBegin(GL_POLYGON);
  256. glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
  257. glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
  258. glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
  259. glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
  260.     glEnd();
  261.     glDepthMask(1);
  262.     glPopMatrix();
  263.     glDisable(GL_TEXTURE_2D);
  264.     glutSwapBuffers();
  265. }
  266. void reshape(int w, int h) {
  267.     glViewport(0, 0, w, h);
  268. }
  269. /* ARGSUSED1 */
  270. void
  271. key(unsigned char key, int x, int y) {
  272.     switch(key) {
  273.     case 'a': afunc(); break;
  274.     case 'b': bfunc(); break;
  275.     case 'h': help(); break;
  276.     case 't': tfunc(); break;
  277.     case '33': exit(EXIT_SUCCESS); break;
  278.     default: break;
  279.     }
  280.     glutPostRedisplay();
  281. }
  282. /* ARGSUSED1 */
  283. void
  284. special(int key, int x, int y) {
  285.     switch(key) {
  286.     case GLUT_KEY_UP: up(); break;
  287.     case GLUT_KEY_DOWN: down(); break;
  288.     case GLUT_KEY_LEFT: left(); break;
  289.     case GLUT_KEY_RIGHT:right(); break;
  290.     }
  291. }
  292. int main(int argc, char** argv) {
  293.     glutInitWindowSize(512, 512);
  294.     glutInit(&argc, argv);
  295.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  296.     (void)glutCreateWindow("smoke");
  297.     init(argc == 1 ? "../data/smoke.bw" : argv[1]);
  298.     glutDisplayFunc(display);
  299.     glutKeyboardFunc(key);
  300.     glutSpecialFunc(special);
  301.     glutReshapeFunc(reshape);
  302.     glutMouseFunc(mouse);
  303.     glutMotionFunc(motion);
  304.     glutIdleFunc(animate);
  305.     glutMainLoop();
  306.     return 0;
  307. }
  308. void
  309. printmat(float *m) {
  310.     int i;
  311.     for(i = 0; i < 4; i++) {
  312. printf("%f %f %f %fn", m[4*i+0], m[4*i+1], m[4*i+2], m[4*i+3]);
  313.     }
  314. }
  315. void
  316. buildRot(float theta, float x, float y, float z, float m[16]) {
  317.     float d = x*x + y*y + z*z;
  318.     float ct = cosf(RAD(theta)), st = sinf(RAD(theta));
  319.     /* normalize */
  320.     if (d > 0) {
  321. d = 1/d;
  322. x *= d;
  323. y *= d;
  324. z *= d;
  325.     }
  326.     m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0;
  327.     m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0;
  328.     m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0;
  329.     m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
  330.     /* R = uu' + cos(theta)*(I-uu') + sin(theta)*S
  331.      *
  332.      * S =  0  -z   y    u' = (x, y, z)
  333.      *     z   0  -x
  334.      *    -y   x   0
  335.      */
  336.      m[0] = x*x + ct*(1-x*x) + st*0;
  337.      m[4] = x*y + ct*(0-x*y) + st*-z;
  338.      m[8] = x*z + ct*(0-x*z) + st*y;
  339.      m[1] = y*x + ct*(0-y*x) + st*z;
  340.      m[5] = y*y + ct*(1-y*y) + st*0;
  341.      m[9] = y*z + ct*(0-y*z) + st*-x;
  342.      m[2] = z*x + ct*(0-z*x) + st*-y;
  343.      m[6] = z*y + ct*(0-z*y) + st*x;
  344.      m[10]= z*z + ct*(1-z*z) + st*0;
  345. }
  346. static void
  347. calcMatrix(void) {
  348.     float mat[16];
  349.     glGetFloatv(GL_MODELVIEW_MATRIX, mat);
  350.     buildRot(-180*atan2f(mat[8], mat[10])/M_PI, 0, 1, 0, mat);
  351.     glMultMatrixf(mat);
  352. }