374 lines
7.9 KiB
C
374 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[])
|
|
{
|
|
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;
|
|
}
|