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

GIS编程

开发平台:

Visual C++

  1. #include <assert.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <GL/glut.h>
  7. #include "texture.h"
  8. #ifndef __sgi
  9. #define trunc(x) ((double)((int)(x)))
  10. #endif
  11. GLsizei sphereTexW, sphereTexH, padSphereTexW, padSphereTexH;
  12. GLint sphereTexComp;
  13. const char defaultSphereMap[] = "../data/spheremap.rgb";
  14. int drawTorus = 1;
  15. int roundup(int n)
  16. {
  17.   int val = 1;
  18.   while (val < n) val <<= 1;
  19.   return val;
  20. }
  21. void create_texture(const char *fname, GLsizei *w,  GLsizei *h, 
  22.       GLsizei *padW, GLsizei *padH, GLint *comps)
  23. {
  24.   GLuint *img, *padImg = NULL;
  25.   int y;
  26.   img = read_texture(fname, w, h, comps);
  27.   if (!img) {
  28.     fprintf(stderr, "Could not open %sn", fname);
  29.     exit(1);
  30.   }
  31.   /* if width & height are not powers of two, pad image with black */
  32.   if (*w & (*w - 1)) {
  33.     *padW = roundup(*w);
  34.   } else {
  35.     *padW = *w;
  36.   }
  37.   if (*h & (*h - 1)) {
  38.     *padH = roundup(*h);
  39.   } else {
  40.     *padH = *h;
  41.   }
  42.   if (*padW != *w || *padH != *h) {
  43. printf("rounding %s up...n", fname);
  44.     padImg = (GLuint *)malloc(*padW * *padH * sizeof(GLuint));
  45.     if (!padImg) {
  46.       fprintf(stderr, "Malloc of %d bytes failed.n", 
  47.       *padW * *padH * sizeof(GLuint));
  48.       exit(1);
  49.     }
  50.     memset(padImg, 0, *padW * *padH * sizeof(GLuint));
  51.     for (y = 0; y < *h; y++) {
  52.       memcpy(&padImg[y * *padW], &img[y * *w], *w * sizeof(GLuint));
  53.     }
  54.   }
  55.   /* you should use texture objects here if your system supports them... */
  56. printf("w = %d h = %dn", *padW, *padH);
  57.   glTexImage2D(GL_TEXTURE_2D, 0, 4, *padW, *padH, 0, 
  58.        GL_RGBA, GL_UNSIGNED_BYTE, img);
  59.   free(img);
  60.   if (padImg) free(padImg);
  61. }
  62. void init(const char *sphereFile)
  63. {
  64.   static GLfloat lightpos[] = {.5, .75, 1.5, 1};
  65.   glEnable(GL_DEPTH_TEST); 
  66.   glEnable(GL_LIGHTING);
  67.   glEnable(GL_LIGHT0);
  68.   glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  69.     create_texture(sphereFile, &sphereTexW, &sphereTexH, 
  70.    &padSphereTexW, &padSphereTexH, &sphereTexComp);
  71. }
  72. void reshape(GLsizei w, GLsizei h) 
  73. {
  74.   glViewport(0, 0, w, h);
  75.   
  76.   glMatrixMode(GL_PROJECTION);
  77.   glLoadIdentity();
  78.   gluPerspective(60, 1, .01, 10);
  79.   gluLookAt(0, 0, 0, 
  80.     0, 0, -1, 
  81.     0, 1, 0);
  82.   
  83.   glMatrixMode(GL_MODELVIEW);
  84.   glLoadIdentity();
  85. }
  86. void draw_room(void)
  87. {
  88.   /* material for the walls, floor, ceiling */
  89.   static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f};
  90.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);
  91.   glBegin(GL_QUADS);
  92.   
  93.   /* floor */
  94.   glNormal3f(0, 1, 0);
  95.   glVertex3f(-1, -1, 1);
  96.   glVertex3f(1, -1, 1);
  97.   glVertex3f(1, -1, -1);
  98.   glVertex3f(-1, -1, -1);
  99.   /* ceiling */
  100.   glNormal3f(0, -1, 0);
  101.   glVertex3f(-1, 1, -1);
  102.   glVertex3f(1, 1, -1);
  103.   glVertex3f(1, 1, 1);
  104.   glVertex3f(-1, 1, 1);  
  105.   /* left wall */
  106.   glNormal3f(1, 0, 0);
  107.   glVertex3f(-1, -1, -1);
  108.   glVertex3f(-1, 1, -1); 
  109.   glVertex3f(-1, 1, 1);
  110.   glVertex3f(-1, -1, 1);
  111.   /* right wall */
  112.   glNormal3f(-1, 0, 0);
  113.   glVertex3f(1, -1, 1);
  114.   glVertex3f(1, 1, 1);
  115.   glVertex3f(1, 1, -1);
  116.   glVertex3f(1, -1, -1);
  117.   /* far wall */
  118.   glNormal3f(0, 0, 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. void draw_torus(GLdouble angle)
  126. {
  127.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
  128.   GL_NEAREST);
  129.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
  130.   GL_NEAREST);
  131.   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  132.   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  133.   glEnable(GL_TEXTURE_GEN_S);
  134.   glEnable(GL_TEXTURE_GEN_T);
  135.   glEnable(GL_TEXTURE_2D);  
  136.   glEnable(GL_CULL_FACE); 
  137.   
  138.   glPushMatrix();
  139.   glTranslatef(0, 0, -3);
  140.   glRotatef(angle, 1, 1, 0);
  141.   
  142.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  143.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  144.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  145.   
  146.   if (drawTorus) {
  147.     glutSolidTorus(.4, .75, 32, 32);
  148.   } else {
  149.     GLUquadricObj *sphere = gluNewQuadric();
  150.     gluSphere(sphere, 1, 32, 32);
  151.   }
  152.   glDisable(GL_TEXTURE_2D);
  153.   glDisable(GL_TEXTURE_GEN_S);
  154.   glDisable(GL_TEXTURE_GEN_T);
  155.   glEnable(GL_LIGHTING);
  156.   glDisable(GL_CULL_FACE);
  157.   glPopMatrix();
  158. }
  159. GLdouble get_secs(void)
  160. {
  161.   return glutGet(GLUT_ELAPSED_TIME) / 1000.0;
  162. }
  163. void draw(void)
  164. {
  165.     GLenum err;
  166.     GLdouble secs, degrees;
  167.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  168.     /* one revolution every 10 seconds... */
  169.     secs = get_secs();
  170.     secs = secs - 10.*trunc(secs / 10.);
  171.     degrees = (secs/10.) * (360.);
  172. #if 0
  173.     draw_room();
  174. #endif
  175.     draw_torus(degrees);
  176.     err = glGetError();
  177.     if (err != GL_NO_ERROR) printf("Error:  %sn", gluErrorString(err));
  178.     glutSwapBuffers();
  179. }
  180. /* ARGSUSED1 */
  181. void key(unsigned char key, int x, int y)
  182. {
  183.   static int idle = 1;
  184.   if (key == 27) exit(0);
  185.   if (key == 'o' || key == 'O') {
  186.     drawTorus = (drawTorus == 0);
  187.     draw();
  188.   } else {
  189.     if (idle) {
  190.       glutIdleFunc(0);
  191.     } else {
  192.       glutIdleFunc(draw);
  193.     }
  194.     idle = (idle == 0);
  195.   }
  196. }
  197. main(int argc, char *argv[])
  198. {
  199.     glutInit(&argc, argv);
  200.     glutInitWindowSize(256, 256);
  201.     glutInitWindowPosition(0, 0);
  202.     glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  203.     glutCreateWindow(argv[0]);
  204.     glutDisplayFunc(draw);
  205.     glutIdleFunc(draw); 
  206.     glutKeyboardFunc(key);
  207.     glutReshapeFunc(reshape);
  208.     init(defaultSphereMap);
  209.     glutMainLoop();
  210.     return 0;
  211. }