diff options
author | Brian Paul <[email protected]> | 2008-03-17 16:03:06 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2008-03-17 16:03:06 -0600 |
commit | 5456f4f210defe0c4ba17a9314ba0b61334e7976 (patch) | |
tree | 6d252936484039ebbb76c2012cd3348f9b80f42b /progs/tests/mipmap_view.c | |
parent | 088c6404fcae07dec6dcf16d2cb0777aa7b446ad (diff) |
mesa: new mipmap generation, lod bias demo
Show each of the mipmap levels side-by-side.
Press 's' to toggle quad scaling to see mipmap level at actual size.
Diffstat (limited to 'progs/tests/mipmap_view.c')
-rw-r--r-- | progs/tests/mipmap_view.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/progs/tests/mipmap_view.c b/progs/tests/mipmap_view.c new file mode 100644 index 00000000000..d821f432f0b --- /dev/null +++ b/progs/tests/mipmap_view.c @@ -0,0 +1,241 @@ +/* + * 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++) { + + glRasterPos2f(x, y + TexHeight + 5); + sprintf(str, "Texture LOD Bias = %d", bias); + PrintString(str); + + glPushMatrix(); + glTranslatef(x, y, 0); + + glEnable(GL_TEXTURE_2D); + + if (ScaleQuads) { + if (bias > 0) { + 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); + } + + 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; +} |