132001f49Smrg/*
232001f49Smrg * Test packed pixel formats for textures.
332001f49Smrg * Brian Paul
432001f49Smrg * 12 May 2004
532001f49Smrg */
632001f49Smrg
732001f49Smrg#include <stdio.h>
832001f49Smrg#include <stdlib.h>
932001f49Smrg#include <math.h>
1032001f49Smrg#include <string.h>
1132001f49Smrg#include <GL/glew.h>
1232001f49Smrg#include "glut_wrap.h"
1332001f49Smrg
1432001f49Smrg
1532001f49Smrgstruct pixel_format {
1632001f49Smrg   const char *name;
1732001f49Smrg   GLenum format;
1832001f49Smrg   GLenum type;
1932001f49Smrg   GLint bytes;
2032001f49Smrg   GLuint redTexel, greenTexel; /* with approx 51% alpha, when applicable */
2132001f49Smrg};
2232001f49Smrg
2332001f49Smrgstatic const struct pixel_format Formats[] = {
2432001f49Smrg
2532001f49Smrg   { "GL_RGBA/GL_UNSIGNED_INT_8_8_8_8",
2632001f49Smrg     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4, 0xff000080, 0x00ff0080 },
2732001f49Smrg   { "GL_RGBA/GL_UNSIGNED_INT_8_8_8_8_REV",
2832001f49Smrg     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x800000ff, 0x8000ff00 },
2932001f49Smrg   { "GL_RGBA/GL_UNSIGNED_INT_10_10_10_2",
3032001f49Smrg     GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, 4, 0xffc00002, 0x3ff002 },
3132001f49Smrg   { "GL_RGBA/GL_UNSIGNED_INT_2_10_10_10_REV",
3232001f49Smrg     GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, 0xc00003ff, 0xc00ffc00 },
3332001f49Smrg   { "GL_RGBA/GL_UNSIGNED_SHORT_4_4_4_4",
3432001f49Smrg     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0xf008, 0x0f08 },
3532001f49Smrg   { "GL_RGBA/GL_UNSIGNED_SHORT_4_4_4_4_REV",
3632001f49Smrg     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x800f, 0x80f0 },
3732001f49Smrg   { "GL_RGBA/GL_UNSIGNED_SHORT_5_5_5_1",
3832001f49Smrg     GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf801, 0x7c1 },
3932001f49Smrg   { "GL_RGBA/GL_UNSIGNED_SHORT_1_5_5_5_REV",
4032001f49Smrg     GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x801f, 0x83e0 },
4132001f49Smrg
4232001f49Smrg   { "GL_BGRA/GL_UNSIGNED_INT_8_8_8_8",
4332001f49Smrg     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4, 0x0000ff80, 0x00ff0080 },
4432001f49Smrg   { "GL_BGRA/GL_UNSIGNED_INT_8_8_8_8_REV",
4532001f49Smrg     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x80ff0000, 0x8000ff00 },
4632001f49Smrg   { "GL_BGRA/GL_UNSIGNED_SHORT_4_4_4_4",
4732001f49Smrg     GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x00f8, 0x0f08 },
4832001f49Smrg   { "GL_BGRA/GL_UNSIGNED_SHORT_4_4_4_4_REV",
4932001f49Smrg     GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x8f00, 0x80f0 },
5032001f49Smrg   { "GL_BGRA/GL_UNSIGNED_SHORT_5_5_5_1",
5132001f49Smrg     GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0x3f, 0x7c1 },
5232001f49Smrg   { "GL_BGRA/GL_UNSIGNED_SHORT_1_5_5_5_REV",
5332001f49Smrg     GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0xfc00, 0x83e0 },
5432001f49Smrg
5532001f49Smrg   { "GL_ABGR_EXT/GL_UNSIGNED_INT_8_8_8_8",
5632001f49Smrg     GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, 4, 0x800000ff, 0x8000ff00 },
5732001f49Smrg   { "GL_ABGR_EXT/GL_UNSIGNED_INT_8_8_8_8_REV",
5832001f49Smrg     GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0xff000080, 0x00ff0080 },
5932001f49Smrg   { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_4_4_4_4",
6032001f49Smrg     GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x800f, 0x80f0 },
6132001f49Smrg   { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_4_4_4_4_REV",
6232001f49Smrg     GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0xf008, 0x0f08 },
6332001f49Smrg   { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_5_5_5_1",
6432001f49Smrg     GL_ABGR_EXT, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf801, 0xf83e },
6532001f49Smrg   { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_1_5_5_5_REV",
6632001f49Smrg     GL_ABGR_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x800f, 0x7c0f },
6732001f49Smrg
6832001f49Smrg   { "GL_RGB/GL_UNSIGNED_SHORT_5_6_5",
6932001f49Smrg     GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, 0xf800, 0x7e0 },
7032001f49Smrg   { "GL_RGB/GL_UNSIGNED_SHORT_5_6_5_REV",
7132001f49Smrg     GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, 2, 0x1f, 0x7e0 },
7232001f49Smrg   { "GL_RGB/GL_UNSIGNED_BYTE_3_3_2",
7332001f49Smrg     GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 1, 0xe0, 0x1c },
7432001f49Smrg   { "GL_RGB/GL_UNSIGNED_BYTE_2_3_3_REV",
7532001f49Smrg     GL_RGB, GL_UNSIGNED_BYTE_2_3_3_REV, 1, 0x7, 0x38 },
7632001f49Smrg
7732001f49Smrg   { NULL, 0, 0, 0, 0, 0 }
7832001f49Smrg};
7932001f49Smrg
8032001f49Smrg
8132001f49Smrgstruct name_format {
8232001f49Smrg   const char *name;
8332001f49Smrg   GLenum format;
8432001f49Smrg};
8532001f49Smrg
8632001f49Smrgstatic const struct name_format IntFormats[] = {
8732001f49Smrg   { "GL_RGBA", GL_RGBA },
8832001f49Smrg   { "GL_RGBA2", GL_RGBA2 },
8932001f49Smrg   { "GL_RGBA4", GL_RGBA4 },
9032001f49Smrg   { "GL_RGB5_A1", GL_RGB5_A1 },
9132001f49Smrg   { "GL_RGBA8", GL_RGBA8 },
9232001f49Smrg   { "GL_RGBA12", GL_RGBA12 },
9332001f49Smrg   { "GL_RGBA16", GL_RGBA16 },
9432001f49Smrg   { "GL_RGB10_A2", GL_RGB10_A2 },
9532001f49Smrg
9632001f49Smrg   { "GL_RGB", GL_RGB },
9732001f49Smrg   { "GL_R3_G3_B2", GL_R3_G3_B2 },
9832001f49Smrg   { "GL_RGB4", GL_RGB4 },
9932001f49Smrg   { "GL_RGB5", GL_RGB5 },
10032001f49Smrg   { "GL_RGB8", GL_RGB8 },
10132001f49Smrg   { "GL_RGB10", GL_RGB10 },
10232001f49Smrg   { "GL_RGB12", GL_RGB12 },
10332001f49Smrg   { "GL_RGB16", GL_RGB16 },
10432001f49Smrg
10532001f49Smrg};
10632001f49Smrg
10732001f49Smrg#define NUM_INT_FORMATS (sizeof(IntFormats) / sizeof(IntFormats[0]))
10832001f49Smrgstatic GLuint CurFormat = 0;
10932001f49Smrg
11032001f49Smrgstatic GLboolean Test3D = GL_FALSE;
11132001f49Smrgstatic GLboolean Blend = GL_FALSE;
11232001f49Smrg
11332001f49Smrg
11432001f49Smrgstatic void
11532001f49SmrgPrintString(const char *s)
11632001f49Smrg{
11732001f49Smrg   while (*s) {
11832001f49Smrg      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
11932001f49Smrg      s++;
12032001f49Smrg   }
12132001f49Smrg}
12232001f49Smrg
12332001f49Smrg
12432001f49Smrgstatic void
12532001f49SmrgMakeTexture(const struct pixel_format *format, GLenum intFormat, GLboolean swap)
12632001f49Smrg{
12732001f49Smrg   GLubyte texBuffer[1000];
12832001f49Smrg   int i;
12932001f49Smrg
13032001f49Smrg   glPixelStorei(GL_UNPACK_SWAP_BYTES, swap);
13132001f49Smrg
13232001f49Smrg   if (format->bytes == 1) {
13332001f49Smrg      for (i = 0; i < 8; i++) {
13432001f49Smrg         texBuffer[i] = format->redTexel;
13532001f49Smrg      }
13632001f49Smrg      for (i = 8; i < 16; i++) {
13732001f49Smrg         texBuffer[i] = format->greenTexel;
13832001f49Smrg      }
13932001f49Smrg   }
14032001f49Smrg   else if (format->bytes == 2) {
14132001f49Smrg      GLushort *us = (GLushort *) texBuffer;
14232001f49Smrg      for (i = 0; i < 8; i++) {
14332001f49Smrg         us[i] = format->redTexel;
14432001f49Smrg      }
14532001f49Smrg      for (i = 8; i < 16; i++) {
14632001f49Smrg         us[i] = format->greenTexel;
14732001f49Smrg      }
14832001f49Smrg      if (swap) {
14932001f49Smrg         for (i = 0; i < 16; i++)
15032001f49Smrg            us[i] = (us[i] << 8) | (us[i] >> 8);
15132001f49Smrg      }
15232001f49Smrg   }
15332001f49Smrg   else if (format->bytes == 4) {
15432001f49Smrg      GLuint *ui = (GLuint *) texBuffer;
15532001f49Smrg      for (i = 0; i < 8; i++) {
15632001f49Smrg         ui[i] = format->redTexel;
15732001f49Smrg      }
15832001f49Smrg      for (i = 8; i < 16; i++) {
15932001f49Smrg         ui[i] = format->greenTexel;
16032001f49Smrg      }
16132001f49Smrg      if (swap) {
16232001f49Smrg         for (i = 0; i < 16; i++) {
16332001f49Smrg            GLuint b = ui[i];
16432001f49Smrg            ui[i] =  (b >> 24)
16532001f49Smrg                  | ((b >> 8) & 0xff00)
16632001f49Smrg                  | ((b << 8) & 0xff0000)
16732001f49Smrg                  | ((b << 24) & 0xff000000);
16832001f49Smrg         }
16932001f49Smrg      }
17032001f49Smrg   }
17132001f49Smrg   else {
17232001f49Smrg      abort();
17332001f49Smrg   }
17432001f49Smrg
17532001f49Smrg   if (Test3D) {
17632001f49Smrg      /* 4 x 4 x 4 texture, undefined data */
17732001f49Smrg      glTexImage3D(GL_TEXTURE_3D, 0, intFormat, 4, 4, 4, 0,
17832001f49Smrg                   format->format, format->type, NULL);
17932001f49Smrg      /* fill in Z=1 and Z=2 slices with the real texture data */
18032001f49Smrg      glTexSubImage3D(GL_TEXTURE_3D, 0,
18132001f49Smrg                      0, 0, 1,  /* offset */
18232001f49Smrg                      4, 4, 1,  /* size */
18332001f49Smrg                      format->format, format->type, texBuffer);
18432001f49Smrg      glTexSubImage3D(GL_TEXTURE_3D, 0,
18532001f49Smrg                      0, 0, 2,  /* offset */
18632001f49Smrg                      4, 4, 1,  /* size */
18732001f49Smrg                      format->format, format->type, texBuffer);
18832001f49Smrg   }
18932001f49Smrg   else {
19032001f49Smrg      glTexImage2D(GL_TEXTURE_2D, 0, intFormat, 4, 4, 0,
19132001f49Smrg                   format->format, format->type, texBuffer);
19232001f49Smrg   }
19332001f49Smrg
19432001f49Smrg   if (0) {
19532001f49Smrg      GLint r, g, b, a, l, i;
19632001f49Smrg      glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
19732001f49Smrg      glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
19832001f49Smrg      glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
19932001f49Smrg      glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
20032001f49Smrg      glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l);
20132001f49Smrg      glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i);
20232001f49Smrg      printf("IntFormat: 0x%x  R %d  G %d  B %d  A %d  L %d  I %d\n",
20332001f49Smrg             intFormat, r, g, b, a, l, i);
20432001f49Smrg      glGetError();
20532001f49Smrg   }
20632001f49Smrg
20732001f49Smrg   if (glGetError()) {
20832001f49Smrg      printf("GL Error for %s\n", format->name);
20932001f49Smrg      memset(texBuffer, 255, 1000);
21032001f49Smrg      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0,
21132001f49Smrg                   GL_RGB, GL_UNSIGNED_BYTE, texBuffer);
21232001f49Smrg   }
21332001f49Smrg}
21432001f49Smrg
21532001f49Smrg
21632001f49Smrg
21732001f49Smrgstatic void
21832001f49SmrgDraw(void)
21932001f49Smrg{
22032001f49Smrg   char s[1000];
22132001f49Smrg   int w = 350, h = 20;
22232001f49Smrg   int i, swap;
22332001f49Smrg
22432001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
22532001f49Smrg
22632001f49Smrg   for (swap = 0; swap < 2; swap++) {
22732001f49Smrg     for (i = 0; Formats[i].name; i++) {
22832001f49Smrg        glPushMatrix();
22932001f49Smrg        glTranslatef(swap * (w + 2), i * (h + 2), 0);
23032001f49Smrg
23132001f49Smrg        MakeTexture(Formats + i, IntFormats[CurFormat].format, swap);
23232001f49Smrg
23332001f49Smrg        if (Test3D)
23432001f49Smrg           glEnable(GL_TEXTURE_3D);
23532001f49Smrg        else
23632001f49Smrg           glEnable(GL_TEXTURE_2D);
23732001f49Smrg
23832001f49Smrg        if (Blend)
23932001f49Smrg           glEnable(GL_BLEND);
24032001f49Smrg
24132001f49Smrg        glBegin(GL_POLYGON);
24232001f49Smrg        glTexCoord3f(0, 0, 0.5);  glVertex2f(0, 0);
24332001f49Smrg        glTexCoord3f(1, 0, 0.5);  glVertex2f(w, 0);
24432001f49Smrg        glTexCoord3f(1, 1, 0.5);  glVertex2f(w, h);
24532001f49Smrg        glTexCoord3f(0, 1, 0.5);  glVertex2f(0, h);
24632001f49Smrg        glEnd();
24732001f49Smrg
24832001f49Smrg        if (Test3D)
24932001f49Smrg           glDisable(GL_TEXTURE_3D);
25032001f49Smrg        else
25132001f49Smrg           glDisable(GL_TEXTURE_2D);
25232001f49Smrg
25332001f49Smrg        glDisable(GL_BLEND);
25432001f49Smrg
25532001f49Smrg        glColor3f(0, 0, 0);
25632001f49Smrg        glRasterPos2i(8, 6);
25732001f49Smrg        PrintString(Formats[i].name);
25832001f49Smrg
25932001f49Smrg        glPopMatrix();
26032001f49Smrg     }
26132001f49Smrg   }
26232001f49Smrg
26332001f49Smrg   glPushMatrix();
26432001f49Smrg   glTranslatef(2, i * (h + 2), 0);
26532001f49Smrg   glColor3f(1, 1, 1);
26632001f49Smrg   glRasterPos2i(8, 6);
26732001f49Smrg   PrintString("Normal");
26832001f49Smrg   glRasterPos2i(w + 2, 6);
26932001f49Smrg   PrintString("Byte Swapped");
27032001f49Smrg   glPopMatrix();
27132001f49Smrg
27232001f49Smrg   glPushMatrix();
27332001f49Smrg   glTranslatef(2, (i + 1) * (h + 2), 0);
27432001f49Smrg   glRasterPos2i(8, 6);
27532001f49Smrg   sprintf(s, "Internal Texture Format [f/F]: %s (%d of %lu)",
27632001f49Smrg           IntFormats[CurFormat].name, CurFormat + 1, (unsigned long) NUM_INT_FORMATS);
27732001f49Smrg   PrintString(s);
27832001f49Smrg   glPopMatrix();
27932001f49Smrg
28032001f49Smrg   glPushMatrix();
28132001f49Smrg   glTranslatef(2, (i + 2) * (h + 2), 0);
28232001f49Smrg   glRasterPos2i(8, 6);
28332001f49Smrg   if (Test3D)
28432001f49Smrg      PrintString("Target [2/3]: GL_TEXTURE_3D");
28532001f49Smrg   else
28632001f49Smrg      PrintString("Target [2/3]: GL_TEXTURE_2D");
28732001f49Smrg   glPopMatrix();
28832001f49Smrg
28932001f49Smrg   glPushMatrix();
29032001f49Smrg   glTranslatef(2, (i + 3) * (h + 2), 0);
29132001f49Smrg   glRasterPos2i(8, 6);
29232001f49Smrg   if (Blend)
29332001f49Smrg      PrintString("Blend: Yes");
29432001f49Smrg   else
29532001f49Smrg      PrintString("Blend: No");
29632001f49Smrg   glPopMatrix();
29732001f49Smrg
29832001f49Smrg   glutSwapBuffers();
29932001f49Smrg}
30032001f49Smrg
30132001f49Smrg
30232001f49Smrgstatic void
30332001f49SmrgReshape(int width, int height)
30432001f49Smrg{
30532001f49Smrg   glViewport(0, 0, width, height);
30632001f49Smrg   glMatrixMode(GL_PROJECTION);
30732001f49Smrg   glLoadIdentity();
30832001f49Smrg   glOrtho(0, width, 0, height, -1, 1);
30932001f49Smrg   glMatrixMode(GL_MODELVIEW);
31032001f49Smrg   glLoadIdentity();
31132001f49Smrg}
31232001f49Smrg
31332001f49Smrg
31432001f49Smrgstatic void
31532001f49SmrgKey(unsigned char key, int x, int y)
31632001f49Smrg{
31732001f49Smrg   (void) x;
31832001f49Smrg   (void) y;
31932001f49Smrg   switch (key) {
32032001f49Smrg      case 'b':
32132001f49Smrg         Blend = !Blend;
32232001f49Smrg         break;
32332001f49Smrg      case 'F':
32432001f49Smrg         if (CurFormat == 0)
32532001f49Smrg            CurFormat = NUM_INT_FORMATS - 1;
32632001f49Smrg         else
32732001f49Smrg            CurFormat--;
32832001f49Smrg         break;
32932001f49Smrg      case 'f':
33032001f49Smrg         CurFormat++;
33132001f49Smrg         if (CurFormat == NUM_INT_FORMATS)
33232001f49Smrg            CurFormat = 0;
33332001f49Smrg         break;
33432001f49Smrg      case '2':
33532001f49Smrg         Test3D = GL_FALSE;
33632001f49Smrg         break;
33732001f49Smrg      case '3':
33832001f49Smrg         Test3D = GL_TRUE;
33932001f49Smrg         break;
34032001f49Smrg      case 27:
34132001f49Smrg         exit(0);
34232001f49Smrg         break;
34332001f49Smrg   }
34432001f49Smrg   glutPostRedisplay();
34532001f49Smrg}
34632001f49Smrg
34732001f49Smrg
34832001f49Smrgstatic void
34932001f49SmrgInit(void)
35032001f49Smrg{
35132001f49Smrg   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
35232001f49Smrg   printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
35332001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
35432001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
35532001f49Smrg   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
35632001f49Smrg   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
35732001f49Smrg   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
35832001f49Smrg   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
35932001f49Smrg}
36032001f49Smrg
36132001f49Smrg
36232001f49Smrgint
36332001f49Smrgmain(int argc, char *argv[])
36432001f49Smrg{
36532001f49Smrg   glutInit(&argc, argv);
36632001f49Smrg   glutInitWindowPosition(0, 0);
36732001f49Smrg   glutInitWindowSize(700, 800);
36832001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
36932001f49Smrg   glutCreateWindow(argv[0]);
37032001f49Smrg   glewInit();
37132001f49Smrg   glutReshapeFunc(Reshape);
37232001f49Smrg   glutKeyboardFunc(Key);
37332001f49Smrg   glutDisplayFunc(Draw);
37432001f49Smrg   Init();
37532001f49Smrg   glutMainLoop();
37632001f49Smrg   return 0;
37732001f49Smrg}
378