1/* 2 * Test packed pixel formats for textures. 3 * Brian Paul 4 * 12 May 2004 5 */ 6 7#include <stdio.h> 8#include <stdlib.h> 9#include <math.h> 10#include <string.h> 11#include <GL/glew.h> 12#include "glut_wrap.h" 13 14 15struct pixel_format { 16 const char *name; 17 GLenum format; 18 GLenum type; 19 GLint bytes; 20 GLuint redTexel, greenTexel; /* with approx 51% alpha, when applicable */ 21}; 22 23static const struct pixel_format Formats[] = { 24 25 { "GL_RGBA/GL_UNSIGNED_INT_8_8_8_8", 26 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4, 0xff000080, 0x00ff0080 }, 27 { "GL_RGBA/GL_UNSIGNED_INT_8_8_8_8_REV", 28 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x800000ff, 0x8000ff00 }, 29 { "GL_RGBA/GL_UNSIGNED_INT_10_10_10_2", 30 GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, 4, 0xffc00002, 0x3ff002 }, 31 { "GL_RGBA/GL_UNSIGNED_INT_2_10_10_10_REV", 32 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, 0xc00003ff, 0xc00ffc00 }, 33 { "GL_RGBA/GL_UNSIGNED_SHORT_4_4_4_4", 34 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0xf008, 0x0f08 }, 35 { "GL_RGBA/GL_UNSIGNED_SHORT_4_4_4_4_REV", 36 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x800f, 0x80f0 }, 37 { "GL_RGBA/GL_UNSIGNED_SHORT_5_5_5_1", 38 GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf801, 0x7c1 }, 39 { "GL_RGBA/GL_UNSIGNED_SHORT_1_5_5_5_REV", 40 GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x801f, 0x83e0 }, 41 42 { "GL_BGRA/GL_UNSIGNED_INT_8_8_8_8", 43 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4, 0x0000ff80, 0x00ff0080 }, 44 { "GL_BGRA/GL_UNSIGNED_INT_8_8_8_8_REV", 45 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x80ff0000, 0x8000ff00 }, 46 { "GL_BGRA/GL_UNSIGNED_SHORT_4_4_4_4", 47 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x00f8, 0x0f08 }, 48 { "GL_BGRA/GL_UNSIGNED_SHORT_4_4_4_4_REV", 49 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x8f00, 0x80f0 }, 50 { "GL_BGRA/GL_UNSIGNED_SHORT_5_5_5_1", 51 GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0x3f, 0x7c1 }, 52 { "GL_BGRA/GL_UNSIGNED_SHORT_1_5_5_5_REV", 53 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0xfc00, 0x83e0 }, 54 55 { "GL_ABGR_EXT/GL_UNSIGNED_INT_8_8_8_8", 56 GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, 4, 0x800000ff, 0x8000ff00 }, 57 { "GL_ABGR_EXT/GL_UNSIGNED_INT_8_8_8_8_REV", 58 GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0xff000080, 0x00ff0080 }, 59 { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_4_4_4_4", 60 GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x800f, 0x80f0 }, 61 { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_4_4_4_4_REV", 62 GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0xf008, 0x0f08 }, 63 { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_5_5_5_1", 64 GL_ABGR_EXT, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf801, 0xf83e }, 65 { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_1_5_5_5_REV", 66 GL_ABGR_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x800f, 0x7c0f }, 67 68 { "GL_RGB/GL_UNSIGNED_SHORT_5_6_5", 69 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, 0xf800, 0x7e0 }, 70 { "GL_RGB/GL_UNSIGNED_SHORT_5_6_5_REV", 71 GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, 2, 0x1f, 0x7e0 }, 72 { "GL_RGB/GL_UNSIGNED_BYTE_3_3_2", 73 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 1, 0xe0, 0x1c }, 74 { "GL_RGB/GL_UNSIGNED_BYTE_2_3_3_REV", 75 GL_RGB, GL_UNSIGNED_BYTE_2_3_3_REV, 1, 0x7, 0x38 }, 76 77 { NULL, 0, 0, 0, 0, 0 } 78}; 79 80 81struct name_format { 82 const char *name; 83 GLenum format; 84}; 85 86static const struct name_format IntFormats[] = { 87 { "GL_RGBA", GL_RGBA }, 88 { "GL_RGBA2", GL_RGBA2 }, 89 { "GL_RGBA4", GL_RGBA4 }, 90 { "GL_RGB5_A1", GL_RGB5_A1 }, 91 { "GL_RGBA8", GL_RGBA8 }, 92 { "GL_RGBA12", GL_RGBA12 }, 93 { "GL_RGBA16", GL_RGBA16 }, 94 { "GL_RGB10_A2", GL_RGB10_A2 }, 95 96 { "GL_RGB", GL_RGB }, 97 { "GL_R3_G3_B2", GL_R3_G3_B2 }, 98 { "GL_RGB4", GL_RGB4 }, 99 { "GL_RGB5", GL_RGB5 }, 100 { "GL_RGB8", GL_RGB8 }, 101 { "GL_RGB10", GL_RGB10 }, 102 { "GL_RGB12", GL_RGB12 }, 103 { "GL_RGB16", GL_RGB16 }, 104 105}; 106 107#define NUM_INT_FORMATS (sizeof(IntFormats) / sizeof(IntFormats[0])) 108static GLuint CurFormat = 0; 109 110static GLboolean Test3D = GL_FALSE; 111static GLboolean Blend = GL_FALSE; 112 113 114static void 115PrintString(const char *s) 116{ 117 while (*s) { 118 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 119 s++; 120 } 121} 122 123 124static void 125MakeTexture(const struct pixel_format *format, GLenum intFormat, GLboolean swap) 126{ 127 GLubyte texBuffer[1000]; 128 int i; 129 130 glPixelStorei(GL_UNPACK_SWAP_BYTES, swap); 131 132 if (format->bytes == 1) { 133 for (i = 0; i < 8; i++) { 134 texBuffer[i] = format->redTexel; 135 } 136 for (i = 8; i < 16; i++) { 137 texBuffer[i] = format->greenTexel; 138 } 139 } 140 else if (format->bytes == 2) { 141 GLushort *us = (GLushort *) texBuffer; 142 for (i = 0; i < 8; i++) { 143 us[i] = format->redTexel; 144 } 145 for (i = 8; i < 16; i++) { 146 us[i] = format->greenTexel; 147 } 148 if (swap) { 149 for (i = 0; i < 16; i++) 150 us[i] = (us[i] << 8) | (us[i] >> 8); 151 } 152 } 153 else if (format->bytes == 4) { 154 GLuint *ui = (GLuint *) texBuffer; 155 for (i = 0; i < 8; i++) { 156 ui[i] = format->redTexel; 157 } 158 for (i = 8; i < 16; i++) { 159 ui[i] = format->greenTexel; 160 } 161 if (swap) { 162 for (i = 0; i < 16; i++) { 163 GLuint b = ui[i]; 164 ui[i] = (b >> 24) 165 | ((b >> 8) & 0xff00) 166 | ((b << 8) & 0xff0000) 167 | ((b << 24) & 0xff000000); 168 } 169 } 170 } 171 else { 172 abort(); 173 } 174 175 if (Test3D) { 176 /* 4 x 4 x 4 texture, undefined data */ 177 glTexImage3D(GL_TEXTURE_3D, 0, intFormat, 4, 4, 4, 0, 178 format->format, format->type, NULL); 179 /* fill in Z=1 and Z=2 slices with the real texture data */ 180 glTexSubImage3D(GL_TEXTURE_3D, 0, 181 0, 0, 1, /* offset */ 182 4, 4, 1, /* size */ 183 format->format, format->type, texBuffer); 184 glTexSubImage3D(GL_TEXTURE_3D, 0, 185 0, 0, 2, /* offset */ 186 4, 4, 1, /* size */ 187 format->format, format->type, texBuffer); 188 } 189 else { 190 glTexImage2D(GL_TEXTURE_2D, 0, intFormat, 4, 4, 0, 191 format->format, format->type, texBuffer); 192 } 193 194 if (0) { 195 GLint r, g, b, a, l, i; 196 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r); 197 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g); 198 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b); 199 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a); 200 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l); 201 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i); 202 printf("IntFormat: 0x%x R %d G %d B %d A %d L %d I %d\n", 203 intFormat, r, g, b, a, l, i); 204 glGetError(); 205 } 206 207 if (glGetError()) { 208 printf("GL Error for %s\n", format->name); 209 memset(texBuffer, 255, 1000); 210 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, 211 GL_RGB, GL_UNSIGNED_BYTE, texBuffer); 212 } 213} 214 215 216 217static void 218Draw(void) 219{ 220 char s[1000]; 221 int w = 350, h = 20; 222 int i, swap; 223 224 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 225 226 for (swap = 0; swap < 2; swap++) { 227 for (i = 0; Formats[i].name; i++) { 228 glPushMatrix(); 229 glTranslatef(swap * (w + 2), i * (h + 2), 0); 230 231 MakeTexture(Formats + i, IntFormats[CurFormat].format, swap); 232 233 if (Test3D) 234 glEnable(GL_TEXTURE_3D); 235 else 236 glEnable(GL_TEXTURE_2D); 237 238 if (Blend) 239 glEnable(GL_BLEND); 240 241 glBegin(GL_POLYGON); 242 glTexCoord3f(0, 0, 0.5); glVertex2f(0, 0); 243 glTexCoord3f(1, 0, 0.5); glVertex2f(w, 0); 244 glTexCoord3f(1, 1, 0.5); glVertex2f(w, h); 245 glTexCoord3f(0, 1, 0.5); glVertex2f(0, h); 246 glEnd(); 247 248 if (Test3D) 249 glDisable(GL_TEXTURE_3D); 250 else 251 glDisable(GL_TEXTURE_2D); 252 253 glDisable(GL_BLEND); 254 255 glColor3f(0, 0, 0); 256 glRasterPos2i(8, 6); 257 PrintString(Formats[i].name); 258 259 glPopMatrix(); 260 } 261 } 262 263 glPushMatrix(); 264 glTranslatef(2, i * (h + 2), 0); 265 glColor3f(1, 1, 1); 266 glRasterPos2i(8, 6); 267 PrintString("Normal"); 268 glRasterPos2i(w + 2, 6); 269 PrintString("Byte Swapped"); 270 glPopMatrix(); 271 272 glPushMatrix(); 273 glTranslatef(2, (i + 1) * (h + 2), 0); 274 glRasterPos2i(8, 6); 275 sprintf(s, "Internal Texture Format [f/F]: %s (%d of %lu)", 276 IntFormats[CurFormat].name, CurFormat + 1, (unsigned long) NUM_INT_FORMATS); 277 PrintString(s); 278 glPopMatrix(); 279 280 glPushMatrix(); 281 glTranslatef(2, (i + 2) * (h + 2), 0); 282 glRasterPos2i(8, 6); 283 if (Test3D) 284 PrintString("Target [2/3]: GL_TEXTURE_3D"); 285 else 286 PrintString("Target [2/3]: GL_TEXTURE_2D"); 287 glPopMatrix(); 288 289 glPushMatrix(); 290 glTranslatef(2, (i + 3) * (h + 2), 0); 291 glRasterPos2i(8, 6); 292 if (Blend) 293 PrintString("Blend: Yes"); 294 else 295 PrintString("Blend: No"); 296 glPopMatrix(); 297 298 glutSwapBuffers(); 299} 300 301 302static void 303Reshape(int width, int height) 304{ 305 glViewport(0, 0, width, height); 306 glMatrixMode(GL_PROJECTION); 307 glLoadIdentity(); 308 glOrtho(0, width, 0, height, -1, 1); 309 glMatrixMode(GL_MODELVIEW); 310 glLoadIdentity(); 311} 312 313 314static void 315Key(unsigned char key, int x, int y) 316{ 317 (void) x; 318 (void) y; 319 switch (key) { 320 case 'b': 321 Blend = !Blend; 322 break; 323 case 'F': 324 if (CurFormat == 0) 325 CurFormat = NUM_INT_FORMATS - 1; 326 else 327 CurFormat--; 328 break; 329 case 'f': 330 CurFormat++; 331 if (CurFormat == NUM_INT_FORMATS) 332 CurFormat = 0; 333 break; 334 case '2': 335 Test3D = GL_FALSE; 336 break; 337 case '3': 338 Test3D = GL_TRUE; 339 break; 340 case 27: 341 exit(0); 342 break; 343 } 344 glutPostRedisplay(); 345} 346 347 348static void 349Init(void) 350{ 351 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 352 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 354 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 355 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 356 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 357 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 358 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 359} 360 361 362int 363main(int argc, char *argv[]) 364{ 365 glutInit(&argc, argv); 366 glutInitWindowPosition(0, 0); 367 glutInitWindowSize(700, 800); 368 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 369 glutCreateWindow(argv[0]); 370 glewInit(); 371 glutReshapeFunc(Reshape); 372 glutKeyboardFunc(Key); 373 glutDisplayFunc(Draw); 374 Init(); 375 glutMainLoop(); 376 return 0; 377} 378