Test program to check that packed pixel formats work as expected with
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 12 May 2004 23:05:21 +0000 (23:05 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 12 May 2004 23:05:21 +0000 (23:05 +0000)
glTexImage2D.  All samples should appear identical.  Press f/F to change
the internal texture format.

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

index f224934d7e22126d735edb294a8a5b178c557abe..52b6b1e2a657742242dde8311b0a8d3cb1a32694 100644 (file)
@@ -31,6 +31,7 @@ SOURCES = antialias.c \
        getprocaddress.c \
        manytex.c \
        multipal.c \
+       packedpixels.c \
        pbo.c \
        projtex.c \
        seccolor.c \
diff --git a/progs/tests/packedpixels.c b/progs/tests/packedpixels.c
new file mode 100644 (file)
index 0000000..842cf7f
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Test packed pixel formats for textures.
+ * Brian Paul
+ * 12 May 2004
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <GL/glut.h>
+
+
+struct pixel_format {
+   const char *name;
+   GLenum format;
+   GLenum type;
+   GLint bytes;
+   GLuint redTexel, greenTexel;
+};
+
+static const struct pixel_format Formats[] = {
+
+   { "GL_RGBA/GL_UNSIGNED_INT_8_8_8_8",
+     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4, 0xff000000, 0x00ff0000 },
+   { "GL_RGBA/GL_UNSIGNED_INT_8_8_8_8_REV",
+     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x000000ff, 0x0000ff00 },
+   { "GL_RGBA/GL_UNSIGNED_INT_10_10_10_2",
+     GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, 4, 0xffc00000, 0x3ff000 },
+   { "GL_RGBA/GL_UNSIGNED_INT_2_10_10_10_REV",
+     GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, 0x3ff, 0xffc00 },
+   { "GL_RGBA/GL_UNSIGNED_SHORT_4_4_4_4",
+     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0xf000, 0x0f00 },
+   { "GL_RGBA/GL_UNSIGNED_SHORT_4_4_4_4_REV",
+     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x000f, 0x00f0 },
+   { "GL_RGBA/GL_UNSIGNED_SHORT_5_5_5_1",
+     GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf800, 0x7c0 },
+   { "GL_RGBA/GL_UNSIGNED_SHORT_1_5_5_5_REV",
+     GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x1f, 0x3e0 },
+
+   { "GL_BGRA/GL_UNSIGNED_INT_8_8_8_8",
+     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4, 0x0000ff00, 0x00ff0000 },
+   { "GL_BGRA/GL_UNSIGNED_INT_8_8_8_8_REV",
+     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x00ff0000, 0x0000ff00 },
+   { "GL_BGRA/GL_UNSIGNED_SHORT_4_4_4_4",
+     GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x00f0, 0x0f00 },
+   { "GL_BGRA/GL_UNSIGNED_SHORT_4_4_4_4_REV",
+     GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x0f00, 0x00f0 },
+   { "GL_BGRA/GL_UNSIGNED_SHORT_5_5_5_1",
+     GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0x3e, 0x7c0 },
+   { "GL_BGRA/GL_UNSIGNED_SHORT_1_5_5_5_REV",
+     GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x7c00, 0x3e0 },
+
+   { "GL_ABGR_EXT/GL_UNSIGNED_INT_8_8_8_8",
+     GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, 4, 0x000000ff, 0x0000ff00 },
+   { "GL_ABGR_EXT/GL_UNSIGNED_INT_8_8_8_8_REV",
+     GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0xff000000, 0x00ff0000 },
+   { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_4_4_4_4",
+     GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x000f, 0x00f0 },
+   { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_4_4_4_4_REV",
+     GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0xf000, 0x0f00 },
+   { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_5_5_5_1",
+     GL_ABGR_EXT, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0x1, 0x3e },
+   { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_1_5_5_5_REV",
+     GL_ABGR_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x8000, 0x7c00 },
+
+   { "GL_RGB/GL_UNSIGNED_SHORT_5_6_5",
+     GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, 0xf800, 0x7e0 },
+   { "GL_RGB/GL_UNSIGNED_SHORT_5_6_5_REV",
+     GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, 2, 0x1f, 0x7e0 },
+   { "GL_RGB/GL_UNSIGNED_BYTE_3_3_2",
+     GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 1, 0xe0, 0x1c },
+   { "GL_RGB/GL_UNSIGNED_BYTE_2_3_3_REV",
+     GL_RGB, GL_UNSIGNED_BYTE_2_3_3_REV, 1, 0x7, 0x38 },
+
+   { NULL, 0, 0, 0, 0, 0 }
+};
+
+
+struct name_format {
+   const char *name;
+   GLenum format;
+};
+
+static const struct name_format IntFormats[] = {
+   { "GL_RGBA", GL_RGBA },
+   { "GL_RGBA2", GL_RGBA2 },
+   { "GL_RGBA4", GL_RGBA4 },
+   { "GL_RGB5_A1", GL_RGB5_A1 },
+   { "GL_RGBA8", GL_RGBA8 },
+   { "GL_RGBA12", GL_RGBA12 },
+   { "GL_RGBA16", GL_RGBA16 },
+   { "GL_RGB10_A2", GL_RGB10_A2 },
+
+   { "GL_RGB", GL_RGB },
+   { "GL_R3_G3_B2", GL_R3_G3_B2 },
+   { "GL_RGB4", GL_RGB4 },
+   { "GL_RGB5", GL_RGB5 },
+   { "GL_RGB8", GL_RGB8 },
+   { "GL_RGB10", GL_RGB10 },
+   { "GL_RGB12", GL_RGB12 },
+   { "GL_RGB16", GL_RGB16 },
+
+};
+
+#define NUM_INT_FORMATS (sizeof(IntFormats) / sizeof(IntFormats[0]))
+static GLuint CurFormat = 0;
+
+
+static void
+PrintString(const char *s)
+{
+   while (*s) {
+      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
+      s++;
+   }
+}
+
+
+static void
+MakeTexture(const struct pixel_format *format, GLenum intFormat, GLboolean swap)
+{
+   GLubyte texBuffer[1000];
+   int i;
+
+   glPixelStorei(GL_UNPACK_SWAP_BYTES, swap);
+
+   if (format->bytes == 1) {
+      for (i = 0; i < 8; i++) {
+         texBuffer[i] = format->redTexel;
+      }
+      for (i = 8; i < 16; i++) {
+         texBuffer[i] = format->greenTexel;
+      }
+   }
+   else if (format->bytes == 2) {
+      GLushort *us = (GLushort *) texBuffer;
+      for (i = 0; i < 8; i++) {
+         us[i] = format->redTexel;
+      }
+      for (i = 8; i < 16; i++) {
+         us[i] = format->greenTexel;
+      }
+      if (swap) {
+         for (i = 0; i < 16; i++)
+            us[i] = (us[i] << 8) | (us[i] >> 8);
+      }
+   }
+   else if (format->bytes == 4) {
+      GLuint *ui = (GLuint *) texBuffer;
+      for (i = 0; i < 8; i++) {
+         ui[i] = format->redTexel;
+      }
+      for (i = 8; i < 16; i++) {
+         ui[i] = format->greenTexel;
+      }
+      if (swap) {
+         for (i = 0; i < 16; i++) {
+            GLuint b = ui[i];
+            ui[i] =  (b >> 24)
+                  | ((b >> 8) & 0xff00)
+                  | ((b << 8) & 0xff0000)
+                  | ((b << 24) & 0xff000000);
+         }
+      }
+   }
+   else {
+      abort();
+   }
+   glTexImage2D(GL_TEXTURE_2D, 0, intFormat, 4, 4, 0,
+                format->format, format->type, texBuffer);
+
+   if (glGetError()) {
+      printf("GL Error for %s\n", format->name);
+      memset(texBuffer, 255, 1000);
+      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0,
+                   GL_RGB, GL_UNSIGNED_BYTE, texBuffer);
+   }
+}
+
+
+
+static void
+Draw(void)
+{
+   char s[1000];
+   int w = 350, h = 20;
+   int i, swap;
+
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   for (swap = 0; swap < 2; swap++) {
+     for (i = 0; Formats[i].name; i++) {
+        glPushMatrix();
+        glTranslatef(swap * (w + 2), i * (h + 2), 0);
+
+        MakeTexture(Formats + i, IntFormats[CurFormat].format, swap);
+
+        glEnable(GL_TEXTURE_2D);
+        glBegin(GL_POLYGON);
+        glTexCoord2f(0, 0);  glVertex2f(0, 0);
+        glTexCoord2f(1, 0);  glVertex2f(w, 0);
+        glTexCoord2f(1, 1);  glVertex2f(w, h);
+        glTexCoord2f(0, 1);  glVertex2f(0, h);
+        glEnd();
+
+        glDisable(GL_TEXTURE_2D);
+        glColor3f(0, 0, 0);
+        glRasterPos2i(8, 6);
+        PrintString(Formats[i].name);
+
+        glPopMatrix();
+     }
+   }
+
+   glPushMatrix();
+   glTranslatef(2, i * (h + 2), 0);
+   glColor3f(1, 1, 1);
+   glRasterPos2i(8, 6);
+   PrintString("Normal");
+   glRasterPos2i(w + 2, 6);
+   PrintString("Byte Swapped");
+   glPopMatrix();
+
+   glPushMatrix();
+   glTranslatef(2, (i + 1) * (h + 2), 0);
+   glRasterPos2i(8, 6);
+   sprintf(s, "Internal Texture Format [f/F]: %s (%d of %d)",
+           IntFormats[CurFormat].name, CurFormat + 1, NUM_INT_FORMATS);
+   PrintString(s);
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+   glViewport(0, 0, width, height);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(0, width, 0, height, -1, 1);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 'F':
+         if (CurFormat == 0)
+            CurFormat = NUM_INT_FORMATS - 1;
+         else
+            CurFormat--;
+         break;
+      case 'f':
+         CurFormat++;
+         if (CurFormat == NUM_INT_FORMATS)
+            CurFormat = 0;
+         break;
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+   printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+   glutInit(&argc, argv);
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(700, 800);
+   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+   glutCreateWindow(argv[0]);
+   glutReshapeFunc(Reshape);
+   glutKeyboardFunc(Key);
+   glutDisplayFunc(Draw);
+   Init();
+   glutMainLoop();
+   return 0;
+}