mesa: new mipmap generation, lod bias demo
authorBrian Paul <brian.paul@tungstengraphics.com>
Mon, 17 Mar 2008 22:03:06 +0000 (16:03 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Mon, 17 Mar 2008 22:03:06 +0000 (16:03 -0600)
Show each of the mipmap levels side-by-side.
Press 's' to toggle quad scaling to see mipmap level at actual size.

progs/tests/Makefile
progs/tests/mipmap_view.c [new file with mode: 0644]

index 7053ebc86aa6f3092dc7f0e8c9dc126fa6150f57..ea34a708553b851f13ee843cf9bffc39b1afb690 100644 (file)
@@ -51,6 +51,7 @@ SOURCES = \
        manytex.c \
        minmag.c \
        mipmap_limits.c \
+       mipmap_view.c \
        multipal.c \
        no_s3tc.c \
        packedpixels.c \
@@ -158,6 +159,14 @@ invert: invert.o readtex.o
 invert.o: invert.c readtex.h
        $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
 
+mipmap_view: mipmap_view.o readtex.o
+       $(CC) $(CFLAGS) mipmap_view.o readtex.o $(LIBS) -o $@
+
+mipmap_view.o: mipmap_view.c readtex.h
+       $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+
+
 readtex.o: readtex.c
        $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
 
diff --git a/progs/tests/mipmap_view.c b/progs/tests/mipmap_view.c
new file mode 100644 (file)
index 0000000..d821f43
--- /dev/null
@@ -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;
+}