bubble.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(x) ((float)sin((x)))
  13. #define cosf(x) ((float)cos((x)))
  14. #endif
  15. static float transp = .5f;
  16. static int normals;
  17. static float phase = .05;
  18. static int tess = 10;
  19. static float freq = 10.f, scale = .03;
  20. static float transx = 1.0, transy, rotx, roty;
  21. static int ox = -1, oy = -1;
  22. static int mot = 0;
  23. #define PAN 1
  24. #define ROT 2
  25. void
  26. pan(const int x, const int y) {
  27.     transx +=  (x-ox)/5.;
  28.     transy -= (y-oy)/5.;
  29.     ox = x; oy = y;
  30.     glutPostRedisplay();
  31. }
  32. void
  33. rotate(const int x, const int y) {
  34.     rotx += x-ox;
  35.     if (rotx > 360.) rotx -= 360.;
  36.     else if (rotx < -360.) rotx += 360.;
  37.     roty += y-oy;
  38.     if (roty > 360.) roty -= 360.;
  39.     else if (roty < -360.) roty += 360.;
  40.     ox = x; oy = y;
  41.     glutPostRedisplay();
  42. }
  43. void
  44. motion(int x, int y) {
  45.     if (mot == PAN) pan(x, y);
  46.     else if (mot == ROT) rotate(x,y);
  47. }
  48. void
  49. mouse(int button, int state, int x, int y) {
  50.     if(state == GLUT_DOWN) {
  51. switch(button) {
  52. case GLUT_LEFT_BUTTON:
  53.     mot = PAN;
  54.     motion(ox = x, oy = y);
  55.     break;
  56. case GLUT_MIDDLE_BUTTON:
  57.     mot = ROT;
  58.     motion(ox = x, oy = y);
  59.     break;
  60. case GLUT_RIGHT_BUTTON:
  61.     break;
  62. }
  63.     } else if (state == GLUT_UP) {
  64. mot = 0;
  65.     }
  66. }
  67. void init(char *fname) {
  68.     int width, height, components;
  69.     GLubyte *image;
  70.     glClearColor(0.0, 0.0, 0.0, 0.0);
  71.     glEnable(GL_DEPTH_TEST);
  72.     glShadeModel(GL_SMOOTH);
  73.     if (!(image = (GLubyte *)read_texture(fname, &width, &height, &components))) {
  74. perror(fname);
  75. exit(EXIT_FAILURE);
  76.     }
  77.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  78.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  79.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  80.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  81.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  82.     glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0,
  83. GL_RGBA, GL_UNSIGNED_BYTE, image);
  84.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  85.     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  86.     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  87.     glEnable(GL_TEXTURE_GEN_S);
  88.     glEnable(GL_TEXTURE_GEN_T);
  89.     glEnable(GL_TEXTURE_2D);
  90.     glEnable(GL_CULL_FACE);
  91.     glEnable(GL_LIGHTING);
  92.     glEnable(GL_LIGHT0);
  93.     glEnable(GL_NORMALIZE);
  94.     glFrontFace(GL_CW);
  95.     glCullFace(GL_BACK);
  96.     glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
  97.     glEnable(GL_COLOR_MATERIAL);
  98. #if 1
  99.     glMaterialf (GL_FRONT, GL_SHININESS, 64.0);
  100.     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
  101.     {
  102.     GLfloat pos[4] = { 0, 0, 1, 1};
  103.     glLightfv(GL_LIGHT0, GL_POSITION, pos);
  104.     }
  105. #endif
  106.     { int e; if (e = glGetError()) printf("error %xn", e); }
  107. #if 0
  108.     glClearColor(.2,.2f,.58f,1.f);
  109. #endif
  110.     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  111.     glEnable(GL_BLEND);
  112. }
  113. #if 0
  114. cube(void) {
  115.     glBegin(GL_QUAD_STRIP);
  116. glVertex3f(-1.,-1.,-1.);
  117. glVertex3f(-1., 1.,-1.);
  118. glVertex3f( 1.,-1.,-1.);
  119. glVertex3f( 1., 1.,-1.);
  120. glVertex3f(-1.,-1.,-1.);
  121. glVertex3f(-1.,-1.,-1.);
  122. glVertex3f(-1.,-1.,-1.);
  123.     glEnd();
  124. }
  125. #endif
  126. /*
  127.  * bilinear (longitude/lattitude) tesselation
  128.  * x = cos(theta)*cos(phi)
  129.  * y = sin(phi)
  130.  * z = sin(theta)*cos(phi)
  131.  */
  132. float *normalize(float *v) {
  133.     static float vv[3];
  134.     float len;
  135.     len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  136.     vv[0] = v[0]/len; vv[1] = v[1]/len; vv[2] = v[2]/len;
  137.     return vv;
  138. }
  139. void
  140. bubble(float rad) {
  141.     float v[3],s;
  142.     float phi, mod;
  143.     static float off;
  144.     int i, j;
  145. #define N tess
  146.     off += phase;
  147. #if 0
  148.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  149. #endif
  150. #if 1
  151.     /* top cap */
  152.     glBegin(GL_TRIANGLE_FAN);
  153.     glNormal3f(0.f, 1.f, 0.f);
  154.     glVertex3f(0.f, 1.f, 0.f);
  155.     v[1] = rad*sinf(phi = M_PI*(N+2)/(2*N));
  156.     mod = 1+scale*sinf(freq*v[1]+off);
  157.     s = cosf(phi)*rad*mod;
  158.     for(i = 0; i <= 2*N; i++) {
  159. v[0] = s*cosf((M_PI/N)*i);
  160. v[2] = s*sinf((M_PI/N)*i);
  161. glNormal3fv(v);
  162. glVertex3fv(v);
  163.     }
  164.     glEnd();
  165. #endif
  166. #if 1
  167.     for(i = 1; i < N-1; i++) {
  168. float v0[3], v1[3], s0, s1;
  169. v0[1] = rad*sinf(phi=M_PI/2+M_PI/N*i); s0 = rad*cosf(phi);
  170. mod = mod = 1+scale*sin(freq*v0[1]+off); s0 *= mod;
  171. v1[1] = rad*sinf(phi=M_PI/2+M_PI/N*(i+1)); s1 = rad*cosf(phi);
  172. mod = mod = 1+scale*sin(freq*v1[1]+off); s1 *= mod;
  173. glBegin(GL_TRIANGLE_STRIP);
  174. for(j = 0; j <= 2*N; j++) {
  175.     float x, z;
  176.     v0[0] = s0*(x = sinf(M_PI/N*j));
  177.     v0[2] = s0*(z = cosf(M_PI/N*j));
  178.     v1[0] = s1*x; v1[2] = s1*z;
  179.     glNormal3fv(normalize(v1));
  180.     glVertex3fv(v1);
  181.     glNormal3fv(normalize(v0));
  182.     glVertex3fv(v0);
  183. }
  184. glEnd();
  185. #if 1
  186. if (normals) {
  187. float nscale = 1.2;
  188. /*glDisable(GL_LIGHTING);*/
  189. glBegin(GL_LINES);
  190. /*glColor3f(1.f, 1.f, 0.f);*/
  191. for(j = 0; j <= 2*N; j++) {
  192.     GLfloat x[3], x1, z1, *vv;
  193.     v0[0] = s0*(x1 = sinf(M_PI/N*j));
  194.     v0[2] = s0*(z1 = cosf(M_PI/N*j));
  195.     glVertex3fv(vv = normalize(v0));
  196.     x[0] = nscale*vv[0]; x[1] = nscale*vv[1]; x[2] = nscale*vv[2];
  197.     glVertex3fv(x);
  198.     v1[0] = s1*x1; v1[2] = s1*z1;
  199.     glVertex3fv(vv = normalize(v1));
  200.     x[0] = nscale*vv[0]; x[1] = nscale*vv[1]; x[2] = nscale*vv[2];
  201.     glVertex3fv(x);
  202. }
  203. glEnd();
  204. /*glEnable(GL_LIGHTING);*/
  205. }
  206. #endif
  207.     }
  208. #endif
  209. #if 1
  210.     /* bottom cap */
  211.     glBegin(GL_TRIANGLE_FAN);
  212.     glNormal3f(0.f, -1.f, 0.f);
  213.     glVertex3f(0.f, -1.f, 0.f);
  214.     v[1] = -rad*sinf(phi=M_PI*(N+2)/(2*N));
  215.     mod = 1+scale*sin(freq*v[1]+off);
  216.     s = cosf(phi)*rad*mod;
  217.     for(i = 2*N; i >= 0; --i) {
  218. v[0] = s*cosf((M_PI/N)*i);
  219. v[2] = s*sinf((M_PI/N)*i);
  220. glNormal3fv(v);
  221. glVertex3fv(v);
  222.     }
  223.     glEnd();
  224. #endif
  225. }
  226. void display(void) {
  227. #if 0
  228.     static float phase;
  229. #endif
  230.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  231. #if 0
  232.     glMatrixMode(GL_TEXTURE);
  233.     glPushMatrix();
  234.     s = sinf(phase); t = s; phase += M_PI/25.f;
  235.     if (phase > 2*M_PI) phase -= 2*M_PI;
  236.     glTranslatef(.5f, -0.5f, 0.f);
  237.     glScalef(.1f, .1f, 1.f);
  238.     glTranslatef(s, t, 0.f);
  239.     glMatrixMode(GL_MODELVIEW);
  240. #endif
  241.     glPushMatrix();
  242.     glTranslatef(0., 0., -100.+transx);
  243.     glRotatef(roty, 1.0, 0.0, 0.0);
  244.     glScalef(10.f, 10.f, 10.f);
  245.     glColor4f(1.f,1.f,1.f,transp);
  246.     bubble(1.0f);
  247.     glPopMatrix ();
  248. #if 0
  249.     glMatrixMode(GL_TEXTURE);
  250.     glPopMatrix();
  251.     glMatrixMode(GL_MODELVIEW);
  252. #endif
  253.     glutSwapBuffers();
  254. }
  255. void reshape(int w, int h) {
  256.     glViewport(0, 0, (GLsizei) w, (GLsizei) h);
  257.     glMatrixMode(GL_PROJECTION);
  258.     glLoadIdentity();
  259. #if 0
  260.     if (w <= h)
  261.        glOrtho (-3.5, 3.5, -3.5*(GLfloat)h/(GLfloat)w, 
  262.                 3.5*(GLfloat)h/(GLfloat)w, -3.5, 10.5);
  263.     else
  264.        glOrtho (-3.5*(GLfloat)w/(GLfloat)h, 
  265.                 3.5*(GLfloat)w/(GLfloat)h, -3.5, 3.5, -3.5, 10.5);
  266. #endif
  267.     gluPerspective(40., 1.0, 10.0, 200000.);
  268.     glMatrixMode(GL_MODELVIEW);
  269.     glLoadIdentity();
  270. }
  271. void ffunc(void) {
  272.     static int state = 1;
  273.     if (state ^= 1)
  274. glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
  275.     else
  276. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  277. }
  278. void tfunc(void) {
  279.     static int state = 1;
  280.     if (state ^= 1)
  281. glEnable(GL_TEXTURE_2D);
  282.     else
  283. glDisable(GL_TEXTURE_2D);
  284. }
  285. void lfunc(void) {
  286.     static int state = 1;
  287.     if (state ^= 1)
  288. glEnable(GL_LIGHTING);
  289.     else
  290. glDisable(GL_LIGHTING);
  291.     glEnable(GL_COLOR_MATERIAL);
  292. }
  293. void bfunc(void) {
  294.     static int state = 1;
  295.     if (state ^= 1) {
  296. glEnable(GL_BLEND);
  297. glDisable(GL_DEPTH_TEST);
  298.     } else {
  299. glDisable(GL_BLEND);
  300. glEnable(GL_DEPTH_TEST);
  301.     }
  302. }
  303. void cfunc(void) {
  304.     static int state = 1;
  305.     if (state ^= 1)
  306. glEnable(GL_CULL_FACE);
  307.     else
  308. glDisable(GL_CULL_FACE);
  309. }
  310. void wfunc(void) {
  311.     static int state;
  312.     glPolygonMode(GL_FRONT_AND_BACK, (state ^= 1) ? GL_LINE : GL_FILL);
  313. }
  314. void ufunc(void) {
  315. tess *= 2;
  316. if (tess > 160) tess = 160;
  317. }
  318. void Ufunc(void) {
  319. tess /= 2;
  320. if (tess < 10) tess = 10;
  321. }
  322. void pfunc(void) {
  323.     phase += .01;
  324. }
  325. void Pfunc(void) {
  326.     phase -= .01;
  327. }
  328. void nfunc(void) {
  329.     normals ^= 1;
  330. }
  331. void xfunc(void) {
  332.     transp += .1;
  333. }
  334. void Xfunc(void) {
  335.     transp -= .1;
  336. }
  337. void yfunc(void) {
  338.     static int state;
  339.     if (state ^= 1)
  340. /*glClearColor(.2,.2f,.58f,0.f);*/
  341. glClearColor(.0,.0f,.65,0.f);
  342.     else
  343. glClearColor(0.f, 0.f, 0.f, 0.f);
  344. }
  345. void up(void) {
  346.     scale += .01f;
  347. }
  348. void down(void) {
  349.     scale -= .01f;
  350. }
  351. void left(void) {
  352.     freq -= 1.f;
  353. }
  354. void right(void) {
  355.     freq += 1.f;
  356. }
  357. /*ARGSUSED1*/
  358. void key (unsigned char key, int x, int y) {
  359.     switch (key) {
  360.     case 'b': bfunc(); break;
  361.     case 'c': cfunc(); break;
  362.     case 'l': lfunc(); break;
  363.     case 't': tfunc(); break;
  364.     case 'f': ffunc(); break;
  365.     case 'n': nfunc(); break;
  366.     case 'u': ufunc(); break;
  367.     case 'U': Ufunc(); break;
  368.     case 'p': pfunc(); break;
  369.     case 'P': Pfunc(); break;
  370.     case 'w': wfunc(); break;
  371.     case 'x': xfunc(); break;
  372.     case 'X': Xfunc(); break;
  373.     case 'y': yfunc(); break;
  374.     case '33': exit(EXIT_SUCCESS); break;
  375.     default: break;
  376.     }
  377. }
  378. /*ARGSUSED1*/
  379. void
  380. special(int key, int x, int y) {
  381.     switch(key) {
  382.     case GLUT_KEY_UP: up(); break;
  383.     case GLUT_KEY_DOWN: down(); break;
  384.     case GLUT_KEY_LEFT: left(); break;
  385.     case GLUT_KEY_RIGHT:right(); break;
  386.     }
  387. }
  388. void animate(void) {
  389.     glutPostRedisplay();
  390. }
  391. int main(int argc, char** argv) {
  392.     glutInitWindowSize(256, 256);
  393.     glutInit(&argc, argv);
  394.     glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  395.     glutInitWindowPosition(100, 100);
  396.     glutCreateWindow (argv[0]);
  397.     init(argc > 1 ? argv[1] : "../data/spheremap.rgb");
  398.     glutDisplayFunc(display);
  399.     glutReshapeFunc(reshape);
  400.     glutKeyboardFunc(key);
  401.     glutSpecialFunc(special);
  402.     glutIdleFunc(animate);
  403.     glutMouseFunc(mouse);
  404.     glutMotionFunc(motion);
  405.     glutMainLoop();
  406.     return 0;
  407. }