diff options
-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 56e7ea1457a..5818337c126 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); } +} + -#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 +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]; + } + } + } + + 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 ); |