Demos (master): mipmap_tunnel: new test to examine mipmap filtering
Brian Paul
brianp at kemper.freedesktop.org
Thu Oct 14 14:55:20 UTC 2010
Module: Demos
Branch: master
Commit: 4d981d192bcff29fd85c794415148988518c6eae
URL: http://cgit.freedesktop.org/mesa/demos/commit/?id=4d981d192bcff29fd85c794415148988518c6eae
Author: Brian Paul <brianp at vmware.com>
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;
+}
More information about the mesa-commit
mailing list