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

GIS编程

开发平台:

Visual C++

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include "texture.h"
  5. #include <GL/glut.h>
  6. #ifndef __sgi
  7. /* Most math.h's do not define float versions of the trig functions. */
  8. #define sinf sin
  9. #define cosf cos
  10. #define atan2f atan2
  11. #endif
  12. /* Some <math.h> files do not define M_PI... */
  13. #ifndef M_PI
  14. #define M_PI 3.14159265358979323846
  15. #endif
  16. static int billboard = 1, texture = 1;
  17. static float scale = 1.;
  18. static float transx = 1.0, transy, rotx, roty;
  19. static int ox = -1, oy = -1;
  20. static int mot = 0;
  21. #define PAN 1
  22. #define ROT 2
  23. void
  24. pan(const int x, const int y) {
  25.     transx +=  (x-ox)/500.;
  26.     transy -= (y-oy)/500.;
  27.     ox = x; oy = y;
  28.     glutPostRedisplay();
  29. }
  30. void
  31. rotate(const int x, const int y) {
  32.     rotx += x-ox;
  33.     if (rotx > 360.) rotx -= 360.;
  34.     else if (rotx < -360.) rotx += 360.;
  35.     roty += y-oy;
  36.     if (roty > 360.) roty -= 360.;
  37.     else if (roty < -360.) roty += 360.;
  38.     ox = x; oy = y;
  39.     glutPostRedisplay();
  40. }
  41. void
  42. motion(int x, int y) {
  43.     if (mot == PAN) pan(x, y);
  44.     else if (mot == ROT) rotate(x,y);
  45. }
  46. void
  47. mouse(int button, int state, int x, int y) {
  48.     if(state == GLUT_DOWN) {
  49. switch(button) {
  50. case GLUT_LEFT_BUTTON:
  51.     mot = PAN;
  52.     motion(ox = x, oy = y);
  53.     break;
  54. case GLUT_MIDDLE_BUTTON:
  55.     break;
  56. case GLUT_RIGHT_BUTTON:
  57.     mot = ROT;
  58.     motion(ox = x, oy = y);
  59.     break;
  60. }
  61.     } else if (state == GLUT_UP) {
  62. mot = 0;
  63.     }
  64. }
  65. void afunc(void) {
  66.     static int state;
  67.     if (state ^= 1) {
  68. glAlphaFunc(GL_GREATER, .01);
  69. glEnable(GL_ALPHA_TEST);
  70.     } else {
  71. glDisable(GL_ALPHA_TEST);
  72.     }
  73. }
  74. void demofunc(void) {
  75.     static float deltax = -.03;
  76.     static float deltay = 2.;
  77.     transx += deltax;
  78.     if (transx > 2.0 || transx < -2.0) deltax = -deltax;
  79.     rotx += deltay;
  80.     if (rotx > 360.f || rotx < 0.f) deltay = -deltay;
  81.     glutPostRedisplay();
  82. }
  83. void dfunc(void) {
  84.     static int demo;
  85.     if (demo ^= 1) {
  86. glutIdleFunc(demofunc);
  87.     } else {
  88. glutIdleFunc(0);
  89.     }
  90. }
  91. void bfunc(void) {
  92.     static int state;
  93.     if (state ^= 1) {
  94. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  95. glEnable(GL_BLEND);
  96.     } else {
  97. glDisable(GL_BLEND);
  98.     }
  99. }
  100. void ffunc(void) {
  101.     billboard ^= 1;
  102. }
  103. void tfunc(void) {
  104.     texture ^= 1;
  105. }
  106. void up(void) { scale += .1; }
  107. void down(void) { scale -= .1; }
  108. void help(void) {
  109.     printf("Usage: billboard [image]n");
  110.     printf("'h'            - helpn");
  111.     printf("'a'            - toggle alpha testn");
  112.     printf("'b'            - toggle blendn");
  113.     printf("'d'            - toggle demo moden");
  114.     printf("'f'            - toggle fixed moden");
  115.     printf("'t'            - toggle texturingn");
  116.     printf("'UP'           - scale upn");
  117.     printf("'DOWN'         - scale downn");
  118.     printf("left mouse     - pann");
  119.     printf("right mouse    - rotaten");
  120. }
  121. void init(char *filename) {
  122.     static unsigned *image;
  123.     static int width, height, components;
  124.     if (filename) {
  125. image = read_texture(filename, &width, &height, &components);
  126. if (image == NULL) {
  127.     fprintf(stderr, "Error: Can't load image file "%s".n",
  128.     filename);
  129.     exit(EXIT_FAILURE);
  130. } else {
  131.     printf("%d x %d image loadedn", width, height);
  132. }
  133. if (components != 4) {
  134.     printf("must be an RGBA imagen");
  135.     exit(EXIT_FAILURE);
  136. }
  137.     } else {
  138. int i, j;
  139. unsigned char *img;
  140. components = 4; width = height = 256;
  141. image = (unsigned *) malloc(width*height*sizeof(unsigned));
  142. img = (unsigned char *)image;
  143. for (j = 0; j < height; j++)
  144.     for (i = 0; i < width; i++) {
  145. int w2 = width/2, h2 = height/2;
  146. if ((i & 32) ^ (j & 32)) {
  147.     img[4*(i+j*width)+0] = 0xff;
  148.     img[4*(i+j*width)+1] = 0xff;
  149.     img[4*(i+j*width)+2] = 0xff;
  150. } else {
  151.     img[4*(i+j*width)+0] = 0x0;
  152.     img[4*(i+j*width)+1] = 0x0;
  153.     img[4*(i+j*width)+2] = 0x0;
  154. }
  155. if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 &&
  156.     (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff;
  157.     }
  158.     }
  159.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  160.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  161.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  162.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  163.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  164.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  165.     glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0,
  166.  GL_RGBA, GL_UNSIGNED_BYTE, image);
  167.     glEnable(GL_TEXTURE_2D);
  168.     glMatrixMode(GL_PROJECTION);
  169.     glLoadIdentity();
  170.     gluPerspective(50.,1.,.1,10.);
  171.     glMatrixMode(GL_MODELVIEW);
  172.     glLoadIdentity();
  173.     glTranslatef(0.,0.,-5.5);
  174.     glClearColor(.25f, .25f, .25f, .25f);
  175.     glEnable(GL_DEPTH_TEST);
  176. }
  177. static void calcMatrix(void);
  178. void display(void) {
  179. #if NATE
  180.     float mat[16];
  181. #endif
  182.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  183.     glLoadIdentity();
  184. #define RAD(x) (((x)*M_PI)/180.)
  185.     gluLookAt(-sinf(RAD(rotx))*5.5,transy,cosf(RAD(rotx))*5.5, 0.,0.,0., 0.,1.,0.);
  186. #if NATE
  187.     glGetFloatv(GL_MODELVIEW_MATRIX, mat);
  188. #endif
  189.     /* floor */
  190.     glDisable(GL_TEXTURE_2D);
  191.     glColor4f(0.2, 0.8, 0.2, 1.);
  192.     glBegin(GL_POLYGON);
  193. glVertex3f(-2.0, -1.0, -2.0);
  194. glVertex3f( 2.0, -1.0, -2.0);
  195. glVertex3f( 2.0, -1.0,  2.0);
  196. glVertex3f(-2.0, -1.0,  2.0);
  197.     glEnd();
  198.     glPushMatrix();
  199. #if 0
  200.     glTranslatef(transx, transy, 0.f);
  201.     glRotatef(rotx, 0., 1., 0.);
  202.     glRotatef(roty, 1., 0., 0.);
  203. #endif
  204.     glTranslatef(0.f, 0.f, -transx);
  205.     if (billboard) calcMatrix();
  206.     glScalef(scale,scale,1.);
  207.     if (texture) glEnable(GL_TEXTURE_2D);
  208.     glColor4f(1.f, 1.f, 1.f, 1.f);
  209.     glBegin(GL_POLYGON);
  210. glTexCoord2f(0.0, 0.0);
  211. glVertex2f(-1.0, -1.0);
  212. glTexCoord2f(1.0, 0.0);
  213. glVertex2f(1.0, -1.0);
  214. glTexCoord2f(1.0, 1.0);
  215. glVertex2f(1.0, 1.0);
  216. glTexCoord2f(0.0, 1.0);
  217. glVertex2f(-1.0, 1.0);
  218.     glEnd();
  219.     glPopMatrix();
  220.     glutSwapBuffers();
  221. }
  222. void reshape(int w, int h) {
  223.     glViewport(0, 0, w, h);
  224. }
  225. /*ARGSUSED*/
  226. void
  227. key(unsigned char key, int x, int y) {
  228.     switch(key) {
  229.     case 'a': afunc(); break;
  230.     case 'd': dfunc(); break;
  231.     case 'b': bfunc(); break;
  232.     case 'f': ffunc(); break;
  233.     case 't': tfunc(); break;
  234.     case 'h': help(); break;
  235.     case '33': exit(EXIT_SUCCESS); break;
  236.     default: break;
  237.     }
  238.     glutPostRedisplay();
  239. }
  240. /*ARGSUSED*/
  241. void
  242. special(int key, int x, int y) {
  243.     switch(key) {
  244.     case GLUT_KEY_UP: up(); break;
  245.     case GLUT_KEY_DOWN: down(); break;
  246.     }
  247.     glutPostRedisplay();
  248. }
  249. int main(int argc, char** argv) {
  250.     glutInitWindowSize(512, 512);
  251.     glutInit(&argc, argv);
  252.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  253.     (void)glutCreateWindow("billboard");
  254.     init(argv[1]);
  255.     glutDisplayFunc(display);
  256.     glutKeyboardFunc(key);
  257.     glutSpecialFunc(special);
  258.     glutReshapeFunc(reshape);
  259.     glutMouseFunc(mouse);
  260.     glutMotionFunc(motion);
  261.     glutMainLoop();
  262.     return 0;
  263. }
  264. void
  265. buildRot(float theta, float x, float y, float z, float m[16]) {
  266.     float d = x*x + y*y + z*z;
  267.     float ct = cosf(RAD(theta)), st = sinf(RAD(theta));
  268.     /* normalize */
  269.     if (d > 0) {
  270. d = 1/d;
  271. x *= d;
  272. y *= d;
  273. z *= d;
  274.     }
  275.     m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0;
  276.     m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0;
  277.     m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0;
  278.     m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
  279.     /* R = uu' + cos(theta)*(I-uu') + sin(theta)*S
  280.      *
  281.      * S =  0  -z   y    u' = (x, y, z)
  282.      *     z   0  -x
  283.      *    -y   x   0
  284.      */
  285.      m[0] = x*x + ct*(1-x*x) + st*0;
  286.      m[4] = x*y + ct*(0-x*y) + st*-z;
  287.      m[8] = x*z + ct*(0-x*z) + st*y;
  288.      m[1] = y*x + ct*(0-y*x) + st*z;
  289.      m[5] = y*y + ct*(1-y*y) + st*0;
  290.      m[9] = y*z + ct*(0-y*z) + st*-x;
  291.      m[2] = z*x + ct*(0-z*x) + st*-y;
  292.      m[6] = z*y + ct*(0-z*y) + st*x;
  293.      m[10]= z*z + ct*(1-z*z) + st*0;
  294. }
  295. static void
  296. calcMatrix(void) {
  297.     float mat[16];
  298.     glGetFloatv(GL_MODELVIEW_MATRIX, mat);
  299.     buildRot(-180*atan2f(mat[8], mat[10])/M_PI, 0, 1, 0, mat);
  300.     glMultMatrixf(mat);
  301. }