Module: Demos Branch: master Commit: 4d981d192bcff29fd85c794415148988518c6eae URL: http://cgit.freedesktop.org/mesa/demos/commit/?id=4d981d192bcff29fd85c794415148988518c6eae
Author: Brian Paul <[email protected]> Date: Thu Oct 14 08:49:01 2010 -0600 mipmap_tunnel: new test to examine mipmap filtering --- src/tests/Makefile.am | 1 + src/tests/mipmap_tunnel.c | 250 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+), 0 deletions(-) diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 03e3c97..cd7424b 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -107,6 +107,7 @@ noinst_PROGRAMS = \ mipmap_comp_tests \ mipmap_limits \ mipmap_view \ + mipmap_tunnel \ multipal \ multitexarray \ multiwindow \ diff --git a/src/tests/mipmap_tunnel.c b/src/tests/mipmap_tunnel.c new file mode 100644 index 0000000..05c4e9e --- /dev/null +++ b/src/tests/mipmap_tunnel.c @@ -0,0 +1,250 @@ +/** + * Display trilinear mipmap filtering quality. + * We look down a long tunnel shape which has a mipmapped texture + * applied to it. Ideally, the transition from one mipmap level to + * another should be nice and regular/circular. + * This sort of test is frequently seen in online articles about GPU + * texture filtering. + * + * Brian Paul + * 13 Oct 2010 + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <GL/glew.h> +#include <GL/glut.h> +#include <GL/glu.h> + + +static GLfloat LodBias = 0.0; +static GLboolean NearestFilter = GL_FALSE; +static GLfloat Zpos = -10.0, Zrot = 0.0; +static GLuint TexObj; + +#define TEX_SIZE 1024 + + +/** Make a solid-colored texture image */ +static void +MakeImage(int level, int width, int height, const GLubyte color[4]) +{ + const int makeStripes = 0; + GLubyte img[TEX_SIZE * TEX_SIZE * 3]; + int i, j; + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + int k = (i * width + j) * 3; + int p = (i / 8) & makeStripes; + if (p == 0) { + img[k + 0] = color[0]; + img[k + 1] = color[1]; + img[k + 2] = color[2]; + } + else { + img[k + 0] = 0; + img[k + 1] = 0; + img[k + 2] = 0; + } + } + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, level, GL_RGB, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, img); +} + + +/** Make a mipmap in which each level is a different, solid color */ +static void +MakeMipmap(void) +{ + static const GLubyte colors[12][3] = { + {255, 0, 0}, + {0, 255, 0}, + {0, 0, 255}, + {0, 255, 255}, + {255, 0, 255}, + {255, 255, 0}, + {255, 0, 0}, + {0, 255, 0}, + {0, 0, 255}, + {0, 255, 255}, + {255, 0, 255}, + {255, 255, 0}, + }; + int i, sz = TEX_SIZE; + + for (i = 0; sz > 0; i++) { + MakeImage(i, sz, sz, colors[i]); + printf("Level %d size: %d x %d\n", i, sz, sz); + sz /= 2; + } +} + + +static void +Init(void) +{ + glClearColor(.5, .5, .5, .5); + + glGenTextures(1, &TexObj); + glBindTexture(GL_TEXTURE_2D, TexObj); + MakeMipmap(); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); +} + + +static void +DrawTunnel(void) +{ + const float radius = 10.0, height = 500.0; + const int slices = 24, stacks = 52; + const float bias = 0.995; + GLUquadric *q = gluNewQuadric(); + + glPushMatrix(); + glRotatef(180, 1, 0, 0); + glEnable(GL_TEXTURE_2D); + gluQuadricTexture(q, GL_TRUE); + gluCylinder(q, radius, radius, height, slices, stacks); + + glDisable(GL_TEXTURE_2D); + glColor3f(0, 0, 0); + gluQuadricDrawStyle(q, GLU_LINE); + gluCylinder(q, bias*radius, bias*radius, height/4, slices, stacks/4); + glPopMatrix(); + + gluDeleteQuadric(q); +} + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +Display(void) +{ + char str[100]; + + glBindTexture(GL_TEXTURE_2D, TexObj); + + if (NearestFilter) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST_MIPMAP_NEAREST); + } + else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + } + + glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, LodBias); + + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(0.0, 0.0, Zpos); + glRotatef(Zrot, 0, 0, 1); + DrawTunnel(); + glPopMatrix(); + + glColor3f(1, 1, 1); + glWindowPos2i(10, 10); + sprintf(str, "LOD bias (b/B): %.3f", LodBias); + PrintString(str); + + glutSwapBuffers(); +} + + +static void +Reshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(80.0, 1.0 * (GLfloat) w / (GLfloat) h, 1.0, 3000.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +Key(unsigned char k, int x, int y) +{ + (void) x; + (void) y; + switch (k) { + case 'b': + LodBias -= 0.125; + break; + case 'B': + LodBias += 0.125; + break; + case 'f': + NearestFilter = !NearestFilter; + break; + case 'r': + Zrot--; + break; + case 'R': + Zrot++; + break; + case 'z': + Zpos--; + break; + case 'Z': + Zpos++; + break; + case 27: + exit(0); + break; + default: + return; + } + glutPostRedisplay(); +} + + +static void +Usage(void) +{ + printf("Keys:\n"); + printf(" b/B decrease/increase GL_TEXTURE_LOD_BIAS\n"); + printf(" f toggle nearest/linear filtering\n"); + printf(" r/R rotate tunnel\n"); +} + + +int +main(int argc, char **argv) +{ + glutInitWindowSize(600, 600); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); + glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc(Reshape); + glutDisplayFunc(Display); + glutKeyboardFunc(Key); + Init(); + Usage(); + glutMainLoop(); + return 0; +} _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
