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

GIS编程

开发平台:

Visual C++

  1. #include <assert.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdlib.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. #define trunc(x) ((double)((int)(x)))
  13. #endif
  14. GLUquadricObj *cone, *base, *qsphere;
  15. static char defaultFile[] = "../data/mandrill.rgb";
  16. GLuint floorList;
  17. GLboolean animate = 1, useSphereMaps = 1;
  18. GLsizei w = 256, h = 256;
  19. #define LEFT  3
  20. #define RIGHT  1
  21. #define FRONT 2
  22. #define BACK 0
  23. #define TOP 4
  24. #define BOTTOM  5
  25. GLuint *faceMap[6];
  26. GLsizei faceW = 128;
  27. GLuint *sphereMap[2];
  28. GLuint sphereW = 256;
  29. GLfloat angle1[6] = {90, 180, 270, 0, 90, -90};
  30. GLfloat axis1[6][3] = {{0,1,0}, {0,1,0}, {0,1,0}, {0,1,0}, {1,0,0}, {1,0,0}};
  31. GLfloat angle2[6] = {0, 0, 0, 0, 180, 180};
  32. GLfloat axis2[6][3] = {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, {0,1,0}};
  33. #define TORUS_BIT 1
  34. #define SPHERE_BIT 2
  35. void reset_textures(void)
  36. {
  37.   unsigned int i;
  38.   /* make sphereMap[0] start out all red... */
  39.   for (i = 0; i < sphereW*sphereW; i++) sphereMap[0][i] = 0xff0000ff;
  40.   /* make sphereMap[1] start out all green... */
  41.   for (i = 0; i < sphereW*sphereW; i++) sphereMap[1][i] = 0x00ff00ff;
  42. }
  43. void realloc_textures(void)
  44. {
  45.   static int first = 1;
  46.   int i;
  47.   if (!first) {
  48.     for (i = 0; i < 6; i++) free(faceMap[i]);
  49.   } else {
  50.     first = 0;
  51.   }
  52.   for (i = 0; i < 6; i++) {
  53.     faceMap[i] = (GLuint *)malloc(faceW*faceW*sizeof(GLuint));
  54.     if (!faceMap[i]) {
  55.       fprintf(stderr, "malloc of %d bytes failed.n", 
  56.       faceW*faceW*sizeof(GLuint));
  57.     }
  58.   }
  59.   sphereMap[0] = (GLuint *)malloc(sphereW * sphereW * sizeof(GLuint));
  60.   sphereMap[1] = (GLuint *)malloc(sphereW * sphereW * sizeof(GLuint));
  61.   reset_textures();
  62. }
  63. void eliminate_alpha(GLsizei w, GLsizei h, GLuint *map)
  64. {
  65.   int x, y;
  66.   /* top & bottom rows */
  67.   for (x = 0; x < w; x++) {
  68.     map[x] &= 0xffffff00;
  69.     map[x + (h-1)*w] &= 0xffffff00;
  70.   }
  71.   for (y = 0; y < h; y++) {
  72.     map[y*w] &= 0xffffff00;
  73.     map[y*w + (w-1)] &= 0xffffff00;
  74.   }
  75. }
  76. void init(const char *fname)
  77. {
  78.   GLuint *img;
  79.   GLsizei w, h;
  80.   int comps;
  81.   glEnable(GL_DEPTH_TEST); 
  82.   glEnable(GL_CULL_FACE); 
  83.   cone = gluNewQuadric();
  84.   base = gluNewQuadric();
  85.   qsphere = gluNewQuadric();
  86.   img = read_texture(fname, &w, &h, &comps);
  87.   if (!img) {
  88.     fprintf(stderr, "Could not open %sn", fname);
  89.     exit(1);
  90.   }
  91.   floorList = glGenLists(1);
  92.   glNewList(floorList, GL_COMPILE);
  93.   glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, 
  94.        GL_RGBA, GL_UNSIGNED_BYTE, img);
  95.   glEndList();
  96.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  97.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  98.   free(img);
  99.   glClearColor(.25, .25, .5, 1.0);
  100.   realloc_textures();
  101. }
  102. void reshape(GLsizei winW, GLsizei winH) 
  103. {
  104.   w = winW/2;
  105.   glViewport(0, 0, w, h);
  106.   
  107.   glMatrixMode(GL_PROJECTION);
  108.   glLoadIdentity();
  109.   gluPerspective(60, 1, .01, 10);
  110.   gluLookAt(-1, 0, 2.577, 0, 0, -5, 0, 1, 0);
  111.   
  112.   glMatrixMode(GL_MODELVIEW);
  113.   glLoadIdentity();
  114. }
  115. void draw_room(void)
  116. {
  117.   /* material for the walls, floor, ceiling */
  118.   static GLfloat wallMat[] = {1.f, 1.f, 1.f, 1.f};
  119.   glPushMatrix();
  120.   glScalef(3, 2, 3);
  121.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wallMat);
  122.   /* floor, textured */
  123.   glColor3f(1, 1, 1);
  124.   glEnable(GL_TEXTURE_2D);
  125.   glCallList(floorList);
  126.   glBegin(GL_QUADS);
  127.   glNormal3f(0, 1, 0);
  128.   glTexCoord2f(0, 0);
  129.   glVertex3f(-1, -1, 1);
  130.   glTexCoord2f(1, 0);
  131.   glVertex3f(1, -1, 1);
  132.   glTexCoord2f(1, 1);
  133.   glVertex3f(1, -1, -1);
  134.   glTexCoord2f(0, 1);
  135.   glVertex3f(-1, -1, -1);
  136.   glEnd();
  137.   glDisable(GL_TEXTURE_2D);
  138.   /* ceiling */
  139.   glColor3f(wallMat[0] * 1., wallMat[1] * 1., wallMat[2] * 1.);
  140.   glBegin(GL_QUADS);
  141.   glNormal3f(0, -1, 0);
  142.   glVertex3f(-1, 1, -1);
  143.   glVertex3f(1, 1, -1);
  144.   glVertex3f(1, 1, 1);
  145.   glVertex3f(-1, 1, 1);  
  146.   /* left wall */
  147.   glColor3f(wallMat[0] * .75, wallMat[1] * .75, wallMat[2] * .75);
  148.   glNormal3f(1, 0, 0);
  149.   glVertex3f(-1, -1, -1);
  150.   glVertex3f(-1, 1, -1);
  151.   glVertex3f(-1, 1, 1);
  152.   glVertex3f(-1, -1, 1);
  153.   /* right wall */
  154.   glColor3f(wallMat[0] * .25, wallMat[1] * .25, wallMat[2] * .25);
  155.   glNormal3f(-1, 0, 0);
  156.   glVertex3f(1, -1, 1);
  157.   glVertex3f(1, 1, 1);
  158.   glVertex3f(1, 1, -1);
  159.   glVertex3f(1, -1, -1);
  160.   /* far wall */
  161.   glColor3f(wallMat[0] * .5, wallMat[1] * .5, wallMat[2] * .5);
  162.   glNormal3f(0, 0, 1);
  163.   glVertex3f(-1, -1, -1);
  164.   glVertex3f(1, -1, -1);
  165.   glVertex3f(1, 1, -1);
  166.   glVertex3f(-1, 1, -1);
  167.   /* back wall */
  168.   glColor3f(wallMat[0] * .5, wallMat[1] * .5, wallMat[2] * .5);
  169.   glNormal3f(0, 0, -1);
  170.   glVertex3f(-1, 1, 1);
  171.   glVertex3f(1, 1, 1);
  172.   glVertex3f(1, -1, 1);
  173.   glVertex3f(-1, -1, 1);
  174.   glEnd();
  175.   glPopMatrix();
  176. }
  177. void draw_cone(void)
  178. {
  179.   static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f};
  180.   glPushMatrix();
  181.   glTranslatef(0, -1, 0);
  182.   glRotatef(-90, 1, 0, 0);
  183.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat);
  184.   
  185.   /* base is coplanar with floor, so turn off depth testing */
  186.   glDisable(GL_DEPTH_TEST);
  187.   gluDisk(base, 0., .3, 20, 1); 
  188.   glEnable(GL_DEPTH_TEST);
  189.   gluCylinder(cone, .3, 0, 1.25, 20, 1);
  190.   glPopMatrix();
  191. }
  192. void draw_cube(void)
  193. {
  194.   glBegin(GL_QUADS);
  195.   glNormal3f(0, -1, 0);
  196.   glVertex3f(-.25, -.25, -.25);
  197.   glVertex3f(.25, -.25, -.25);
  198.   glVertex3f(.25, -.25, .25);
  199.   glVertex3f(-.25, -.25, .25);
  200.   glNormal3f(0, 1, 0);
  201.   glVertex3f(-.25, .25, .25);  
  202.   glVertex3f(.25, .25, .25);
  203.   glVertex3f(.25, .25, -.25);
  204.   glVertex3f(-.25, .25, -.25);
  205.   glNormal3f(1, 0, 0);
  206.   glVertex3f(.25, -.25, -.25);
  207.   glVertex3f(.25, .25, -.25);
  208.   glVertex3f(.25, .25, .25);
  209.   glVertex3f(.25, -.25, .25);
  210.   glNormal3f(-1, 0, 0);
  211.   glVertex3f(-.25, -.25, .25);
  212.   glVertex3f(-.25, .25, .25);
  213.   glVertex3f(-.25, .25, -.25);
  214.   glVertex3f(-.25, -.25, -.25);
  215.   glNormal3f(0, 0, -1);
  216.   glVertex3f(-.25, .25, -.25);
  217.   glVertex3f(.25, .25, -.25);
  218.   glVertex3f(.25, -.25, -.25);
  219.   glVertex3f(-.25, -.25, -.25);
  220.   glNormal3f(0, 0, 1);
  221.   glVertex3f(-.25, -.25, .25);
  222.   glVertex3f(.25, -.25, .25);
  223.   glVertex3f(.25, .25, .25);
  224.   glVertex3f(-.25, .25, .25);
  225.   glEnd();
  226. }
  227. void draw_sphere(GLdouble angle)
  228. {
  229.   static GLfloat sphere_mat[] = {.2f, .7f, .2f, 1.f};
  230.   glTexImage2D(GL_TEXTURE_2D, 0, 4, sphereW, sphereW, 0,
  231.        GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[1]);
  232.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  233.   
  234.   if (useSphereMaps) glEnable(GL_TEXTURE_2D);
  235.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  236.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  237.   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  238.   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  239.   glEnable(GL_TEXTURE_GEN_S);
  240.   glEnable(GL_TEXTURE_GEN_T);
  241.   glPushMatrix();
  242.   glRotatef(45, 0, 0, 1);
  243.   glRotatef(angle, 0, 1, 0);
  244.   glTranslatef(1, 0, 0);
  245.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat);
  246.   glColor3fv(sphere_mat);
  247. #if 1
  248.   {
  249.     GLUquadricObj *sphere = gluNewQuadric();
  250.     gluSphere(sphere, .6, 64, 64);
  251.     gluDeleteQuadric(sphere);
  252.   }
  253. #else
  254.   draw_cube();
  255. #endif
  256.   glPopMatrix();
  257.   glDisable(GL_TEXTURE_GEN_S);
  258.   glDisable(GL_TEXTURE_GEN_T);
  259.   glDisable(GL_TEXTURE_2D);
  260. }
  261. void draw_torus(GLdouble angle)
  262. {
  263.   angle = 0;
  264.   glTexImage2D(GL_TEXTURE_2D, 0, 4, sphereW, sphereW, 0,
  265.        GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[0]);
  266.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  267.   if (useSphereMaps) glEnable(GL_TEXTURE_2D);  
  268.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  269.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  270.   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  271.   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  272.   glEnable(GL_TEXTURE_GEN_S);
  273.   glEnable(GL_TEXTURE_GEN_T);
  274.   glColor3f(1, .5, .5);
  275.   glPushMatrix();
  276.   glRotatef(angle, 1, 0, 0);
  277.   glRotatef(0, 0, 1, 0);
  278. #if 0
  279.   glutSolidTorus(.2, .25, 32, 32);
  280. #else
  281.   {
  282.     GLUquadricObj *sphere = gluNewQuadric();
  283.     gluSphere(sphere, .2, 64, 64);
  284.   }
  285. #endif
  286.   glPopMatrix();
  287.   glDisable(GL_TEXTURE_GEN_S);
  288.   glDisable(GL_TEXTURE_GEN_T);
  289.   glDisable(GL_TEXTURE_2D);
  290. }
  291. void draw_scene(GLdouble degrees, GLint bits)
  292. {
  293.   glEnable(GL_CULL_FACE);
  294.   draw_room();
  295.   if (bits & TORUS_BIT) draw_torus(degrees); 
  296.   if (bits & SPHERE_BIT) draw_sphere(degrees);
  297. }
  298. GLdouble get_secs(void)
  299. {
  300.   return glutGet(GLUT_ELAPSED_TIME) / 1000.0;
  301. }
  302. void draw_special_sphere(int tess)
  303. {
  304.   float r = 1.0, r1, r2, z1, z2;
  305.   float theta, phi;
  306.   int nlon = tess, nlat = tess;
  307.   int i, j;
  308.   glBegin(GL_TRIANGLE_FAN);
  309.   theta = M_PI*1.0/nlat;
  310.   r2 = r*sin(theta); z2 = r*cos(theta);
  311.   glNormal3f(0.0, 0.0, 1.0);
  312.   glVertex4f(0.0, 0.0, r*r, r);
  313.   for (j = 0, phi = 0.0; j <= nlon; j++, phi = 2*M_PI*j/nlon) {
  314.     glNormal3f(r2*cos(phi), r2*sin(phi), z2);
  315.     glVertex4f(r2*cos(phi)*z2, r2*sin(phi)*z2, z2*z2, z2); /* top */
  316.   }
  317.   glEnd();
  318.   for (i = 2; i < nlat; i++) {
  319.     theta = M_PI*i/nlat;
  320.     r1 = r*sin(M_PI*(i-1)/nlat); z1 = r*cos(M_PI*(i-1)/nlat);
  321.     r2 = r*sin(theta); z2 = r*cos(theta);
  322.     if (fabs(z1) < 0.01 || fabs(z2) < 0.01)
  323.       break;
  324.     glBegin(GL_QUAD_STRIP);
  325.     for (j = 0, phi = 0; j <= nlat; j++, phi = 2*M_PI*j/nlon) {
  326.       glNormal3f(r1*cos(phi), r1*sin(phi), z1);
  327.       glVertex4f(r1*cos(phi)*z1, r1*sin(phi)*z1, z1*z1, z1);
  328.       glNormal3f(r2*cos(phi), r2*sin(phi), z2);
  329.       glVertex4f(r2*cos(phi)*z2, r2*sin(phi)*z2, z2*z2, z2);
  330.     }
  331.     glEnd();
  332.   }
  333. }
  334. void render_spheremap(void)
  335. {
  336.   GLfloat p[4];
  337.   int i;
  338.   glColor4f(1, 1, 1, 1);
  339. #if 1
  340.   glEnable(GL_TEXTURE_2D);
  341. #endif
  342.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  343.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  344.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  345.   glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  346.   p[0] = 2.0; p[1] = p[2] = p[3] = 0.0; /* 2zx */
  347.   glTexGenfv(GL_S, GL_OBJECT_PLANE, p);
  348.   
  349.   glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  350.   p[0] = 0.0; p[1] = 2.0; p[2] = p[3] = 0.0; /* 2zy */
  351.   glTexGenfv(GL_T, GL_OBJECT_PLANE, p);
  352.   
  353.   glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  354.   p[0] = p[1] = 0.0; p[2] = 0.0; p[3] = 2.0; /* 2z */
  355.   glTexGenfv(GL_R, GL_OBJECT_PLANE, p);
  356.   glEnable(GL_TEXTURE_GEN_S);
  357.   glEnable(GL_TEXTURE_GEN_T);
  358.   glEnable(GL_TEXTURE_GEN_R);
  359.   
  360.   glMatrixMode(GL_PROJECTION);
  361.   glPushMatrix();
  362.   glMatrixMode(GL_MODELVIEW);
  363.   glPushMatrix();
  364.   glMatrixMode(GL_TEXTURE);
  365.   glPushMatrix();
  366.   glMatrixMode(GL_PROJECTION);
  367.   glLoadIdentity();
  368.   glOrtho(-.98, .98, -.98, .98, 1.0, 100);
  369.   glMatrixMode(GL_MODELVIEW);
  370.   glLoadIdentity();
  371.   gluLookAt(0, 0, 6,
  372.     0, 0, 0,
  373.     0, 1, 0);
  374.   glEnable(GL_DEPTH_TEST);
  375.   glEnable(GL_CULL_FACE);
  376.   glEnable(GL_BLEND);
  377.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  378. #if 1
  379.   glClearColor(0.25, 0.25, 0.5, 1.0);
  380.   glClearDepth(1.0);
  381.   glClear(/* GL_COLOR_BUFFER_BIT | */GL_DEPTH_BUFFER_BIT);
  382. #endif
  383.   for (i = 0; i < 6; i++) {
  384.     glTexImage2D(GL_TEXTURE_2D, 0, 4, faceW, faceW, 0, 
  385.  GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)faceMap[i]);
  386.     glMatrixMode(GL_TEXTURE);
  387.     glLoadIdentity();
  388.     glScalef(0.5, 0.5, 1.0);
  389.     glTranslatef(1.0, 1.0, 0.0);
  390.     glFrustum(-1.01, 1.01, -1.01, 1.01, 1.0, 100.0);
  391.     if (angle2[i]) {
  392.       glRotatef(angle2[i], axis2[i][0], axis2[i][1], axis2[i][2]);
  393.     }
  394.     glRotatef(angle1[i], axis1[i][0], axis1[i][1], axis1[i][2]);
  395.     
  396.     /* XXX atul does another angle thing here... */
  397.     /* XXX atul does a third angle thing here... */
  398.     
  399.     glTranslatef(0.0, 0.0, -1.00);
  400.     
  401.     glMatrixMode(GL_MODELVIEW);
  402.     glClear(GL_DEPTH_BUFFER_BIT);
  403.     draw_special_sphere(20);
  404.   }
  405.   glDisable(GL_BLEND);
  406.   glDisable(GL_CULL_FACE);
  407.   glMatrixMode(GL_PROJECTION);
  408.   glPopMatrix();
  409.   glMatrixMode(GL_MODELVIEW);
  410.   glPopMatrix();
  411.   glMatrixMode(GL_TEXTURE);
  412.   glPopMatrix();
  413.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  414.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  415.   glDisable(GL_TEXTURE_GEN_S);
  416.   glDisable(GL_TEXTURE_GEN_T);
  417.   glDisable(GL_TEXTURE_GEN_R);
  418.   glDisable(GL_TEXTURE_2D);
  419. }
  420. void make_projection(int face, GLfloat xpos, GLfloat ypos, GLfloat zpos)
  421. {
  422.   glMatrixMode(GL_PROJECTION);
  423.   glLoadIdentity();
  424.   gluPerspective(90, 1, .01, 10);
  425.   if (angle2[face]) {
  426.       glRotatef(angle2[face], axis2[face][0], axis2[face][1], axis2[face][2]);
  427.     }
  428.   glRotatef(angle1[face], axis1[face][0], axis1[face][1], axis1[face][2]);
  429.   gluLookAt(xpos, ypos, zpos,
  430.     ypos, ypos, zpos - 1,
  431.     0, 1, 0);
  432.   glMatrixMode(GL_MODELVIEW);
  433.   glLoadIdentity();
  434. }
  435. void draw(void)
  436. {
  437.   static int frame = 0;
  438.   GLenum err;
  439.   GLdouble secs;
  440.   static double degrees = 0;
  441.   GLfloat sphereX, sphereY, sphereZ;
  442.   
  443.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  444.   
  445.   /* one revolution every 10 seconds... */
  446.   if (animate) {
  447.     secs = get_secs();
  448.     secs = secs - 10.*trunc(secs / 10.);
  449.     degrees = (secs/10.) * (360.);
  450.   }
  451.   
  452.   if (frame == 0) {
  453.     /* switch the viewport and draw the faces of the cube from the 
  454.      * point of view of the square... */
  455.   
  456.     glViewport(w + 0*faceW, 0, faceW, faceW);
  457.     make_projection(LEFT, 0, 0, 0);
  458.     draw_scene(degrees, -1 & ~TORUS_BIT);
  459.     glReadPixels(w + 0*faceW, 0, faceW, faceW, 
  460.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[LEFT]);
  461.     eliminate_alpha(faceW, faceW, faceMap[LEFT]);
  462.     glViewport(w + 1*faceW, 0, faceW, faceW);
  463.     make_projection(RIGHT, 0, 0, 0);
  464.     draw_scene(degrees, -1 & ~TORUS_BIT);
  465.     glReadPixels(w + 1*faceW, 0, faceW, faceW, 
  466.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[RIGHT]);
  467.     eliminate_alpha(faceW, faceW, faceMap[RIGHT]);
  468.     glViewport(w + 2*faceW, 0, faceW, faceW);
  469.     make_projection(BOTTOM, 0, 0, 0);
  470.     draw_scene(degrees, -1 & ~TORUS_BIT);
  471.     glReadPixels(w + 2*faceW, 0, faceW, faceW, 
  472.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[BOTTOM]);
  473.     eliminate_alpha(faceW, faceW, faceMap[BOTTOM]);
  474.     glViewport(w + 0*faceW, faceW, faceW, faceW);
  475.     make_projection(TOP, 0, 0, 0);
  476.     draw_scene(degrees, -1 & ~TORUS_BIT);
  477.     glReadPixels(w + 0*faceW, faceW, faceW, faceW, 
  478.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[TOP]);
  479.     eliminate_alpha(faceW, faceW, faceMap[TOP]);
  480.     glViewport(w + 1*faceW, faceW, faceW, faceW);
  481.     make_projection(FRONT, 0, 0, 0);
  482.     draw_scene(degrees, -1 & ~TORUS_BIT);
  483.     glReadPixels(w + 1*faceW, faceW, faceW, faceW, 
  484.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[FRONT]);
  485.     eliminate_alpha(faceW, faceW, faceMap[FRONT]);
  486.     glViewport(w + 2*faceW, faceW, faceW, faceW);
  487.     make_projection(BACK, 0, 0, 0);
  488.     draw_scene(degrees, -1 & ~TORUS_BIT);
  489.     glReadPixels(w + 2*faceW, faceW, faceW, faceW, 
  490.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[BACK]);
  491.     eliminate_alpha(faceW, faceW, faceMap[BACK]);
  492.     /* create the sphere map for the cube... */
  493.     glViewport(w, 2*faceW, sphereW, sphereW);
  494.     render_spheremap();
  495.     glReadPixels(w, 2*faceW, sphereW, sphereW, GL_RGBA, GL_UNSIGNED_BYTE,
  496.  sphereMap[0]);
  497.   } else {
  498.     sphereX = 
  499.     sphereY = cos((degrees/360.) * 2.*M_PI);
  500.     sphereZ = -sin((degrees/360.) * 2.*M_PI);
  501.     glViewport(w + 0*faceW, 0, faceW, faceW);
  502.     make_projection(LEFT, sphereX, sphereY, sphereZ);
  503.     draw_scene(degrees, -1 & ~SPHERE_BIT);
  504.     glReadPixels(w + 0*faceW, 0, faceW, faceW, 
  505.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[LEFT]);
  506.     eliminate_alpha(faceW, faceW, faceMap[LEFT]);
  507.     glViewport(w + 1*faceW, 0, faceW, faceW);
  508.     make_projection(RIGHT, sphereX, sphereY, sphereZ);
  509.     draw_scene(degrees, -1 & ~SPHERE_BIT);
  510.     glReadPixels(w + 1*faceW, 0, faceW, faceW, 
  511.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[RIGHT]);
  512.     eliminate_alpha(faceW, faceW, faceMap[RIGHT]);
  513.     glViewport(w + 2*faceW, 0, faceW, faceW);
  514.     make_projection(BOTTOM, sphereX, sphereY, sphereZ);
  515.     draw_scene(degrees, -1 & ~SPHERE_BIT);
  516.     glReadPixels(w + 2*faceW, 0, faceW, faceW, 
  517.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[BOTTOM]);
  518.     eliminate_alpha(faceW, faceW, faceMap[BOTTOM]);
  519.     glViewport(w + 0*faceW, faceW, faceW, faceW);
  520.     make_projection(TOP, sphereX, sphereY, sphereZ);
  521.     draw_scene(degrees, -1 & ~SPHERE_BIT);
  522.     glReadPixels(w + 0*faceW, faceW, faceW, faceW, 
  523.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[TOP]);
  524.     eliminate_alpha(faceW, faceW, faceMap[TOP]);
  525.     glViewport(w + 1*faceW, faceW, faceW, faceW);
  526.     make_projection(FRONT, sphereX, sphereY, sphereZ);
  527.     draw_scene(degrees, -1 & ~SPHERE_BIT);
  528.     glReadPixels(w + 1*faceW, faceW, faceW, faceW, 
  529.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[FRONT]);
  530.     eliminate_alpha(faceW, faceW, faceMap[FRONT]);
  531.     glViewport(w + 2*faceW, faceW, faceW, faceW);
  532.     make_projection(BACK, sphereX, sphereY, sphereZ);
  533.     draw_scene(degrees, -1 & ~SPHERE_BIT);
  534.     glReadPixels(w + 2*faceW, faceW, faceW, faceW, 
  535.  GL_RGBA, GL_UNSIGNED_BYTE, faceMap[BACK]);
  536.     eliminate_alpha(faceW, faceW, faceMap[BACK]);
  537.     /* create the sphere map for the cube... */
  538.     glViewport(w + sphereW, 2*faceW, sphereW, sphereW);
  539.     render_spheremap();
  540.     glReadPixels(w+sphereW, 2*faceW, sphereW, sphereW, 
  541.  GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[1]);
  542.   }
  543.   frame = (frame == 0);
  544.   /* draw both spheremaps */
  545.   glViewport(w, 2*faceW, 2*sphereW, sphereW);
  546.   glMatrixMode(GL_PROJECTION);
  547.   glLoadIdentity();
  548.   glOrtho(0, 2*sphereW, 0, sphereW, 0, 1);
  549.   glRasterPos2i(0, 0);
  550.   glDrawPixels(sphereW, sphereW, GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[0]);
  551.   glRasterPos2i(sphereW, 0);
  552.   glDrawPixels(sphereW, sphereW, GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[1]);
  553.     /* draw the scene for the viewer's visual gratification... */
  554.     glViewport(0, 0, w, h); 
  555.     glMatrixMode(GL_PROJECTION);
  556.     glLoadIdentity();
  557.     gluPerspective(60, 1, .01, 10);
  558.     gluLookAt(0, 0, 0, 
  559.       0, 0, -1, 
  560.       0, 1, 0);
  561.     glMatrixMode(GL_MODELVIEW);
  562.     glLoadIdentity();
  563.     glTranslatef(0, 0, -2.577);
  564.     draw_scene(degrees, -1);
  565.     glLoadIdentity();
  566.     err = glGetError();
  567.     if (err != GL_NO_ERROR) printf("Error:  %sn", gluErrorString(err));
  568.     glutSwapBuffers();
  569. }
  570. /* ARGSUSED1 */
  571. void key(unsigned char key, int x, int y)
  572. {
  573.   static int idle = 1;
  574.   switch(key) {
  575.   case 'a': case 'A':
  576.     animate = (animate == 0);
  577.     printf("%sanimatingn", animate ? "" : "not ");
  578.     break;
  579.   case 'd': case 'D':
  580.     printf("drawingn");
  581.     draw();
  582.     break;
  583.   case 'r': case 'R':
  584.     printf("resetting sphere maps...n");
  585.     reset_textures();
  586.     draw();
  587.     break;
  588.   case 't': case 'T':
  589.     useSphereMaps = (useSphereMaps == 0);
  590.     printf("%susing sphere mapsn", useSphereMaps ? "" : "not ");
  591.     break;
  592.   case 27:
  593.     exit(0);
  594.   default:
  595.     if (idle) {
  596.       glutIdleFunc(0);
  597.     } else {
  598.       glutIdleFunc(draw);
  599.     }
  600.     idle = (idle == 0);
  601.     printf("%sdrawing when idlen", idle ? "" : "not ");
  602.     break;
  603.   }
  604. }
  605. main(int argc, char *argv[])
  606. {
  607.     glutInitWindowSize(w*2, h);
  608.     glutInitWindowPosition(0, 0);
  609.     glutInit(&argc, argv);
  610.     glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
  611.     glutCreateWindow(argv[0]);
  612.     glutDisplayFunc(draw);
  613.     glutIdleFunc(draw);
  614.     glutKeyboardFunc(key);
  615.     glutReshapeFunc(reshape);
  616.     init(defaultFile);
  617.     glutMainLoop();
  618.     return 0;
  619. }