diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2002-10-25 17:20:26 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2002-10-25 17:20:26 +0000 | 
| commit | a4f0b6884ceb966305181045bbdced013e857d38 (patch) | |
| tree | b359188a1ae115bbb4156955c80c8b3bff25e627 | |
| parent | 92c195211a9f9d6cfcf369230c799a468fa2dc37 (diff) | |
added skybox and options to load real images
| -rw-r--r-- | progs/demos/cubemap.c | 234 | 
1 files changed, 198 insertions, 36 deletions
| diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c index 56e7ea1457..5818337c12 100644 --- a/progs/demos/cubemap.c +++ b/progs/demos/cubemap.c @@ -1,4 +1,4 @@ -/* $Id: cubemap.c,v 1.3 2000/06/27 17:04:43 brianp Exp $ */ +/* $Id: cubemap.c,v 1.4 2002/10/25 17:20:26 brianp Exp $ */  /*   * GL_ARB_texture_cube_map demo @@ -36,25 +36,100 @@   */ +#include <assert.h>  #include <math.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h>  #include "GL/glut.h" +#include "../util/readtex.c" /* a hack */ +  static GLfloat Xrot = 0, Yrot = 0; +static GLfloat EyeDist = 10; + + +static void draw_skybox( void ) +{ +   const GLfloat eps1 = 0.99; +   const GLfloat br = 20.0; /* box radius */ + +   glBegin(GL_QUADS); + +   /* +X side */ +   glTexCoord3f(1.0, -eps1, -eps1);  glVertex3f(br, -br, -br); +   glTexCoord3f(1.0, -eps1,  eps1);  glVertex3f(br, -br,  br); +   glTexCoord3f(1.0,  eps1,  eps1);  glVertex3f(br,  br,  br); +   glTexCoord3f(1.0,  eps1, -eps1);  glVertex3f(br,  br, -br); + +   /* -X side */ +   glTexCoord3f(-1.0,  eps1, -eps1);  glVertex3f(-br,  br, -br); +   glTexCoord3f(-1.0,  eps1,  eps1);  glVertex3f(-br,  br,  br); +   glTexCoord3f(-1.0, -eps1,  eps1);  glVertex3f(-br, -br,  br); +   glTexCoord3f(-1.0, -eps1, -eps1);  glVertex3f(-br, -br, -br); + +   /* +Y side */ +   glTexCoord3f(-eps1, 1.0, -eps1);  glVertex3f(-br,  br, -br); +   glTexCoord3f(-eps1, 1.0,  eps1);  glVertex3f(-br,  br,  br); +   glTexCoord3f( eps1, 1.0,  eps1);  glVertex3f( br,  br,  br); +   glTexCoord3f( eps1, 1.0, -eps1);  glVertex3f( br,  br, -br); + +   /* -Y side */ +   glTexCoord3f(-eps1, -1.0, -eps1);  glVertex3f(-br, -br, -br); +   glTexCoord3f(-eps1, -1.0,  eps1);  glVertex3f(-br, -br,  br); +   glTexCoord3f( eps1, -1.0,  eps1);  glVertex3f( br, -br,  br); +   glTexCoord3f( eps1, -1.0, -eps1);  glVertex3f( br, -br, -br); + +   /* +Z side */ +   glTexCoord3f( eps1, -eps1, 1.0);  glVertex3f( br, -br, br); +   glTexCoord3f(-eps1, -eps1, 1.0);  glVertex3f(-br, -br, br); +   glTexCoord3f(-eps1,  eps1, 1.0);  glVertex3f(-br,  br, br); +   glTexCoord3f( eps1,  eps1, 1.0);  glVertex3f( br,  br, br); + +   /* -Z side */ +   glTexCoord3f( eps1,  eps1, -1.0);  glVertex3f( br,  br, -br); +   glTexCoord3f(-eps1,  eps1, -1.0);  glVertex3f(-br,  br, -br); +   glTexCoord3f(-eps1, -eps1, -1.0);  glVertex3f(-br, -br, -br); +   glTexCoord3f( eps1, -eps1, -1.0);  glVertex3f( br, -br, -br); + +   glEnd(); +}  static void draw( void )  {     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -   glMatrixMode(GL_TEXTURE); -   glLoadIdentity(); -   glRotatef(Xrot, 1, 0, 0); -   glRotatef(Yrot, 0, 1, 0); -   glutSolidSphere(2.0, 20, 20); -   glMatrixMode(GL_MODELVIEW); +   glPushMatrix(); /*MODELVIEW*/ +      glTranslatef( 0.0, 0.0, -EyeDist ); + +      /* skybox */ +      glDisable(GL_TEXTURE_GEN_S); +      glDisable(GL_TEXTURE_GEN_T); +      glDisable(GL_TEXTURE_GEN_R); + +      glMatrixMode(GL_MODELVIEW); +      glPushMatrix(); +         glRotatef(Xrot, 1, 0, 0); +         glRotatef(Yrot, 0, 1, 0); +         draw_skybox(); +      glPopMatrix(); + +      /* sphere */ +      glMatrixMode(GL_TEXTURE); +      glLoadIdentity(); +      glRotatef(-Yrot, 0, 1, 0); +      glRotatef(-Xrot, 1, 0, 0); + +      glEnable(GL_TEXTURE_GEN_S); +      glEnable(GL_TEXTURE_GEN_T); +      glEnable(GL_TEXTURE_GEN_R); +      glutSolidSphere(2.0, 20, 20); + +      glLoadIdentity(); /* texture */ + +      glMatrixMode(GL_MODELVIEW); +   glPopMatrix();     glutSwapBuffers();  } @@ -62,7 +137,8 @@ static void draw( void )  static void idle(void)  { -   Yrot += 5.0; +   GLfloat t = 0.05 * glutGet(GLUT_ELAPSED_TIME); +   Yrot = t;     glutPostRedisplay();  } @@ -81,9 +157,6 @@ static void set_mode(GLuint mode)        glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);        printf("GL_NORMAL_MAP_ARB mode\n");     } -   glEnable(GL_TEXTURE_GEN_S); -   glEnable(GL_TEXTURE_GEN_T); -   glEnable(GL_TEXTURE_GEN_R);  } @@ -105,6 +178,16 @@ static void key(unsigned char k, int x, int y)           mode = !mode;           set_mode(mode);           break; +      case 'z': +         EyeDist -= 0.5; +         if (EyeDist < 6.0) +            EyeDist = 6.0; +         break; +      case 'Z': +         EyeDist += 0.5; +         if (EyeDist > 90.0) +            EyeDist = 90; +         break;        case 27:           exit(0);     } @@ -114,15 +197,15 @@ static void key(unsigned char k, int x, int y)  static void specialkey(int key, int x, int y)  { -   GLfloat step = 10; +   GLfloat step = 5;     (void) x;     (void) y;     switch (key) {        case GLUT_KEY_UP: -         Xrot -= step; +         Xrot += step;           break;        case GLUT_KEY_DOWN: -         Xrot += step; +         Xrot -= step;           break;        case GLUT_KEY_LEFT:           Yrot -= step; @@ -138,17 +221,17 @@ static void specialkey(int key, int x, int y)  /* new window size or exposure */  static void reshape(int width, int height)  { +   GLfloat ar = (float) width / (float) height;     glViewport(0, 0, (GLint)width, (GLint)height);     glMatrixMode(GL_PROJECTION);     glLoadIdentity(); -   glFrustum( -2.0, 2.0, -2.0, 2.0, 6.0, 20.0 ); +   glFrustum( -2.0*ar, 2.0*ar, -2.0, 2.0, 4.0, 100.0 );     glMatrixMode(GL_MODELVIEW);     glLoadIdentity(); -   glTranslatef( 0.0, 0.0, -8.0 );  } -static void init( void ) +static void init_checkers( void )  {  #define CUBE_TEX_SIZE 64     GLubyte image[CUBE_TEX_SIZE][CUBE_TEX_SIZE][3]; @@ -171,16 +254,6 @@ static void init( void )     GLint i, j, f; -   /* check for extension */ -   { -      char *exten = (char *) glGetString(GL_EXTENSIONS); -      if (!strstr(exten, "GL_ARB_texture_cube_map")) { -         printf("Sorry, this demo requires GL_ARB_texture_cube_map\n"); -         exit(0); -      } -   } - -     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);     /* make colored checkerboard cube faces */ @@ -203,18 +276,102 @@ static void init( void )        glTexImage2D(targets[f], 0, GL_RGB, CUBE_TEX_SIZE, CUBE_TEX_SIZE, 0,                     GL_RGB, GL_UNSIGNED_BYTE, image);     } +} + + +static void load(GLenum target, const char *filename, +                 GLboolean flipTB, GLboolean flipLR) +{ +   GLint w, h; +   GLenum format; +   GLubyte *img = LoadRGBImage( filename, &w, &h, &format ); +   if (!img) { +      printf("Error: couldn't load texture image %s\n", filename); +      exit(1); +   } +   assert(format == GL_RGB); + +   /* <sigh> the way the texture cube mapping works, we have to flip +    * images to make things look right. +    */ +   if (flipTB) { +      const int stride = 3 * w; +      GLubyte temp[3*1024]; +      int i; +      for (i = 0; i < h / 2; i++) { +         memcpy(temp, img + i * stride, stride); +         memcpy(img + i * stride, img + (h - i - 1) * stride, stride); +         memcpy(img + (h - i - 1) * stride, temp, stride); +      } +   } +   if (flipLR) { +      const int stride = 3 * w; +      GLubyte temp[3]; +      GLubyte *row; +      int i, j; +      for (i = 0; i < h; i++) { +         row = img + i * stride; +         for (j = 0; j < w / 2; j++) { +            int k = w - j - 1; +            temp[0] = row[j*3+0]; +            temp[1] = row[j*3+1]; +            temp[2] = row[j*3+2]; +            row[j*3+0] = row[k*3+0]; +            row[j*3+1] = row[k*3+1]; +            row[j*3+2] = row[k*3+2]; +            row[k*3+0] = temp[0]; +            row[k*3+1] = temp[1]; +            row[k*3+2] = temp[2]; +         } +      } +   } -#if 1 -   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); -#else -   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#endif +   gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img); +   free(img); +} + + +static void load_envmaps(void) +{ +   load(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, "right.rgb", GL_TRUE, GL_FALSE); +   load(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, "left.rgb", GL_TRUE, GL_FALSE); +   load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, "top.rgb", GL_FALSE, GL_TRUE); +   load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, "bottom.rgb", GL_FALSE, GL_TRUE); +   load(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, "front.rgb", GL_TRUE, GL_FALSE); +   load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, "back.rgb", GL_TRUE, GL_FALSE); +} + + +static void init( GLboolean useImageFiles ) +{ +   GLenum filter; + +   /* check for extension */ +   { +      char *exten = (char *) glGetString(GL_EXTENSIONS); +      if (!strstr(exten, "GL_ARB_texture_cube_map")) { +         printf("Sorry, this demo requires GL_ARB_texture_cube_map\n"); +         exit(0); +      } +   } +   printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); + +   if (useImageFiles) { +      load_envmaps(); +      filter = GL_LINEAR; +   } +   else { +      init_checkers(); +      filter = GL_NEAREST; +   } + +   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, filter); +   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, filter);     glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);     glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);     glEnable(GL_TEXTURE_CUBE_MAP_ARB); +   glEnable(GL_DEPTH_TEST);     glClearColor(.3, .3, .3, 0);     glColor3f( 1.0, 1.0, 1.0 ); @@ -229,16 +386,21 @@ static void usage(void)     printf("  SPACE - toggle animation\n");     printf("  CURSOR KEYS - rotation\n");     printf("  m - toggle texgen reflection mode\n"); +   printf("  z/Z - change viewing distance\n");  }  int main( int argc, char *argv[] )  {     glutInitWindowPosition(0, 0); -   glutInitWindowSize(300, 300); +   glutInitWindowSize(600, 500);     glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );     glutCreateWindow("Texture Cube Maping"); -   init(); + +   if (argc > 1 && strcmp(argv[1] , "-i") == 0) +      init( 1 ); +   else +      init( 0 );     glutReshapeFunc( reshape );     glutKeyboardFunc( key );     glutSpecialFunc( specialkey ); | 
