mesa/progs/tests/mipmap_view.c

249 lines
5.8 KiB
C

/*
* Test mipmap generation and lod bias.
*
* Brian Paul
* 17 March 2008
*/
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include "readtex.h"
#define TEXTURE_FILE "../images/arch.rgb"
static int TexWidth = 256, TexHeight = 256;
static int WinWidth = 1044, WinHeight = 900;
static GLfloat Bias = 0.0;
static GLboolean ScaleQuads = GL_FALSE;
static void
PrintString(const char *s)
{
while (*s) {
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
s++;
}
}
static void
Display(void)
{
int x, y, bias;
char str[100];
int texWidth = TexWidth, texHeight = TexHeight;
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WinWidth, 0, WinHeight, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1,1,1);
y = WinHeight - 300;
x = 4;
for (bias = -1; bias < 11; bias++) {
if (ScaleQuads) {
if (bias > 0) {
if (texWidth == 1 && texHeight == 1)
break;
texWidth = TexWidth >> bias;
texHeight = TexHeight >> bias;
if (texWidth < 1)
texWidth = 1;
if (texHeight < 1)
texHeight = 1;
}
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.0);
}
else {
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias);
}
glRasterPos2f(x, y + TexHeight + 5);
if (ScaleQuads)
sprintf(str, "Texture Level %d: %d x %d",
(bias < 0 ? 0 : bias),
texWidth, texHeight);
else
sprintf(str, "Texture LOD Bias = %d", bias);
PrintString(str);
glPushMatrix();
glTranslatef(x, y, 0);
glEnable(GL_TEXTURE_2D);
glBegin(GL_POLYGON);
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(1, 0); glVertex2f(texWidth, 0);
glTexCoord2f(1, 1); glVertex2f(texWidth, texHeight);
glTexCoord2f(0, 1); glVertex2f(0, texHeight);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
x += TexWidth + 4;
if (x >= WinWidth) {
x = 4;
y -= 300;
}
}
glutSwapBuffers();
}
static void
Reshape(int width, int height)
{
WinWidth = width;
WinHeight = height;
glViewport(0, 0, width, height);
}
static void
Key(unsigned char key, int x, int y)
{
(void) x;
(void) y;
switch (key) {
case 'b':
Bias -= 10;
break;
case 'B':
Bias += 10;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
Bias = 100.0 * (key - '0');
break;
case 's':
ScaleQuads = !ScaleQuads;
break;
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
static void
Init(void)
{
GLfloat maxBias;
if (!glutExtensionSupported("GL_EXT_texture_lod_bias")) {
printf("Sorry, GL_EXT_texture_lod_bias not supported by this renderer.\n");
exit(1);
}
if (!glutExtensionSupported("GL_SGIS_generate_mipmap")) {
printf("Sorry, GL_SGIS_generate_mipmap not supported by this renderer.\n");
exit(1);
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (1) {
/* test auto mipmap generation */
GLint width, height, i;
GLenum format;
GLubyte *image = LoadRGBImage(TEXTURE_FILE, &width, &height, &format);
if (!image) {
printf("Error: could not load texture image %s\n", TEXTURE_FILE);
exit(1);
}
/* resize to TexWidth x TexHeight */
if (width != TexWidth || height != TexHeight) {
GLubyte *newImage = malloc(TexWidth * TexHeight * 4);
gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
TexWidth, TexHeight, GL_UNSIGNED_BYTE, newImage);
free(image);
image = newImage;
}
printf("Using GL_SGIS_generate_mipmap\n");
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, format, TexWidth, TexHeight, 0,
format, GL_UNSIGNED_BYTE, image);
free(image);
/* make sure mipmap was really generated correctly */
width = TexWidth;
height = TexHeight;
for (i = 0; i < 9; i++) {
GLint w, h;
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
printf("Level %d size: %d x %d\n", i, w, h);
assert(w == width);
assert(h == height);
width /= 2;
height /= 2;
}
}
else {
if (LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
printf("Using gluBuildMipmaps()\n");
}
else {
printf("Error: could not load texture image %s\n", TEXTURE_FILE);
exit(1);
}
}
/* mipmapping required for this extension */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &maxBias);
printf("GL_RENDERER: %s\n", (char*) glGetString(GL_RENDERER));
printf("LOD bias range: [%g, %g]\n", -maxBias, maxBias);
printf("Press 's' to toggle quad scaling\n");
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
glutInitWindowSize(WinWidth, WinHeight);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutDisplayFunc(Display);
Init();
glutMainLoop();
return 0;
}