/* * Simple test of multiple textures */ #include #include #include #include #include "readtex.h" #define TEST_CLAMP 0 #define TEST_MIPMAPS 0 #define MAX_TEXTURES 8 static int Win; static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; static GLboolean Anim = GL_TRUE; static GLboolean Blend = GL_FALSE; static GLuint Filter = 0; static GLboolean Clamp = GL_FALSE; static GLuint NumTextures; static GLuint Textures[MAX_TEXTURES]; static float TexRot[MAX_TEXTURES][3]; static float TexPos[MAX_TEXTURES][3]; static float TexAspect[MAX_TEXTURES]; static const char *DefaultFiles[] = { "../images/arch.rgb", "../images/reflect.rgb", "../images/tree2.rgba", "../images/tile.rgb" }; #define NUM_FILTERS 5 static struct filter { GLenum min, mag; const char *name; } FilterModes[NUM_FILTERS] = { { GL_NEAREST, GL_NEAREST, "Nearest,Nearest" }, { GL_LINEAR, GL_LINEAR, "Linear,Linear" }, { GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, "NearestMipmapNearest,Nearest" }, { GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, "LinearMipmapNearest,Linear" }, { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, "LinearMipmapLinear,Linear" } }; static void Idle(void) { Xrot = glutGet(GLUT_ELAPSED_TIME) * 0.02; Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.04; /* Zrot += 2.0; */ glutPostRedisplay(); } static void DrawTextures(void) { GLuint i; for (i = 0; i < NumTextures; i++) { GLfloat ar = TexAspect[i]; glPushMatrix(); glTranslatef(TexPos[i][0], TexPos[i][1], TexPos[i][2]); glRotatef(TexRot[i][0], 1, 0, 0); glRotatef(TexRot[i][1], 0, 1, 0); glRotatef(TexRot[i][2], 0, 0, 1); glBindTexture(GL_TEXTURE_2D, Textures[i]); glBegin(GL_POLYGON); #if TEST_CLAMP glTexCoord2f( -0.5, -0.5 ); glVertex2f( -ar, -1.0 ); glTexCoord2f( 1.5, -0.5 ); glVertex2f( ar, -1.0 ); glTexCoord2f( 1.5, 1.5 ); glVertex2f( ar, 1.0 ); glTexCoord2f( -0.5, 1.5 ); glVertex2f( -ar, 1.0 ); #else glTexCoord2f( 0.0, 0.0 ); glVertex2f( -ar, -1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex2f( ar, -1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex2f( ar, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex2f( -ar, 1.0 ); #endif glEnd(); glPopMatrix(); } } static void Draw(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (Blend) { glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); } else { glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); } glPushMatrix(); glRotatef(Xrot, 1, 0, 0); glRotatef(Yrot, 0, 1, 0); glRotatef(Zrot, 0, 0, 1); DrawTextures(); glPopMatrix(); glutSwapBuffers(); } static void Reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 50.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -10.0); } static GLfloat RandFloat(float min, float max) { float x = (float) (rand() % 1000) * 0.001; x = x * (max - min) + min; return x; } static void Randomize(void) { GLfloat k = 1.0; GLuint i; srand(glutGet(GLUT_ELAPSED_TIME)); for (i = 0; i < NumTextures; i++) { TexRot[i][0] = RandFloat(0.0, 360); TexRot[i][1] = RandFloat(0.0, 360); TexRot[i][2] = RandFloat(0.0, 360); TexPos[i][0] = RandFloat(-k, k); TexPos[i][1] = RandFloat(-k, k); TexPos[i][2] = RandFloat(-k, k); } } static void SetTexParams(void) { GLuint i; for (i = 0; i < NumTextures; i++) { glBindTexture(GL_TEXTURE_2D, Textures[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilterModes[Filter].min); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, FilterModes[Filter].mag); if (Clamp) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } } } static void Key(unsigned char key, int x, int y) { const GLfloat step = 3.0; (void) x; (void) y; switch (key) { case 'a': case ' ': Anim = !Anim; if (Anim) glutIdleFunc(Idle); else glutIdleFunc(NULL); break; case 'b': Blend = !Blend; break; case 'f': Filter = (Filter + 1) % NUM_FILTERS; SetTexParams(); break; case 'r': Randomize(); break; #if TEST_CLAMP case 'c': Clamp = !Clamp; SetTexParams(); break; #endif case 'z': Zrot -= step; break; case 'Z': Zrot += step; break; case 27: glutDestroyWindow(Win); exit(0); break; } printf("Blend=%s Filter=%s\n", Blend ? "Y" : "n", FilterModes[Filter].name); glutPostRedisplay(); } static void SpecialKey(int key, int x, int y) { const GLfloat step = 3.0; (void) x; (void) y; switch (key) { case GLUT_KEY_UP: Xrot -= step; break; case GLUT_KEY_DOWN: Xrot += step; break; case GLUT_KEY_LEFT: Yrot -= step; break; case GLUT_KEY_RIGHT: Yrot += step; break; } glutPostRedisplay(); } static void LoadTextures(GLuint n, const char *files[]) { GLuint i; NumTextures = n < MAX_TEXTURES ? n : MAX_TEXTURES; glGenTextures(n, Textures); SetTexParams(); for (i = 0; i < n; i++) { GLint w, h; glBindTexture(GL_TEXTURE_2D, Textures[i]); #if TEST_MIPMAPS { static const GLubyte color[9][4] = { {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {0, 255, 255}, {255, 0, 255}, {255, 255, 0}, {255, 128, 255}, {128, 128, 128}, {64, 64, 64} }; GLubyte image[256*256*4]; int i, level; w = h = 256; for (level = 0; level <= 8; level++) { for (i = 0; i < w * h; i++) { image[i*4+0] = color[level][0]; image[i*4+1] = color[level][1]; image[i*4+2] = color[level][2]; image[i*4+3] = color[level][3]; } printf("Load level %d: %d x %d\n", level, w>>level, h>>level); glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w>>level, h>>level, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); } } #else if (!LoadRGBMipmaps2(files[i], GL_TEXTURE_2D, GL_RGB, &w, &h)) { printf("Error: couldn't load %s\n", files[i]); exit(1); } #endif TexAspect[i] = (float) w / (float) h; printf("Loaded %s\n", files[i]); } } static void Init(int argc, const char *argv[]) { if (argc == 1) LoadTextures(4, DefaultFiles); else LoadTextures(argc - 1, argv + 1); Randomize(); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(1, 1, 1, 0.5); #if 0 /* setup lighting, etc */ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); #endif } static void Usage(void) { printf("Usage:\n"); printf(" textures [file.rgb] ...\n"); printf("Keys:\n"); printf(" a - toggle animation\n"); printf(" b - toggle blending\n"); printf(" f - change texture filter mode\n"); printf(" r - randomize\n"); printf(" ESC - exit\n"); } int main(int argc, char *argv[]) { glutInitWindowSize(700, 700); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); Win = glutCreateWindow(argv[0]); glutReshapeFunc(Reshape); glutKeyboardFunc(Key); glutSpecialFunc(SpecialKey); glutDisplayFunc(Draw); if (Anim) glutIdleFunc(Idle); Init(argc, (const char **) argv); Usage(); glutMainLoop(); return 0; }