mesa/progs/demos/textures.c

375 lines
7.9 KiB
C

/*
* Simple test of multiple textures
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#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[])
{
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
glutInitWindowSize(700, 700);
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;
}