// Check if the given image format and datatype are compatible. // Also check for types/formats defined by GL extensions here. bool PixelFormatsTest::CompatibleFormatAndType(GLenum format, GLenum datatype) const { // Special case: GL_BGR can't be used with packed types! // This has to do with putting the most color bits in red and green, // not blue. if (format == GL_BGR && IsPackedType(datatype)) return false; if (datatype == GL_HALF_FLOAT_ARB && !haveHalfFloat) return false; if (format == GL_ABGR_EXT && !haveABGR) return false; // Special case: GL_ABGR_EXT can't be used with packed types // because the packed formats specs (which were all written after the // GL_EXT_abgr) explicitly say that the packed formats can only be used // with GL_RGB, GL_BGR, GL_RGBA, or GL_BGRA and do not mention // GL_ABGR_EXT. if (format == GL_ABGR_EXT && IsPackedType(datatype)) return false; if (format == GL_RG && !haveRG) return false; if (datatype == GL_UNSIGNED_INT_5_9_9_9_REV && !haveTexSharedExp) return false; const int formatComps = NumberOfComponentsInFormat(format); const int typeComps = NumberOfComponentsInPackedType(datatype); return formatComps == typeComps || typeComps == 0; }
// Check if the given image format and datatype are compatible. // Also check for types/formats defined by GL extensions here. bool PixelFormatsTest::CompatibleFormatAndType(GLenum format, GLenum datatype) const { // Special case: GL_BGR can't be used with packed types! // This has to do with putting the most color bits in red and green, // not blue. if (format == GL_BGR && IsPackedType(datatype)) return false; #ifdef GL_ARB_half_float_pixel if (datatype == GL_HALF_FLOAT_ARB && !haveHalfFloat) return false; #endif #ifdef GL_EXT_abgr if (format == GL_ABGR_EXT && !haveABGR) return false; #endif const int formatComps = NumberOfComponentsInFormat(format); const int typeComps = NumberOfComponentsInPackedType(datatype); return formatComps == typeComps || typeComps == 0; }
// Create an image buffer and fill it so that a single image channel is // the max value (1.0) while the other channels are zero. For example, // if fillComponent==2 and we're filling a four-component image, the // pixels will be (0, 0, max, 0). // // We always leave the upper-right quadrant black/zero. This is to help // detect any image conversion issues related to stride, packing, etc. static GLubyte * MakeImage(int width, int height, GLenum format, GLenum type, int fillComponent) { assert(fillComponent < 4); if (type == GL_UNSIGNED_INT_5_9_9_9_REV) { GLubyte *image = new GLubyte [width * height * 4]; int i; assert(format == GL_RGB); GLuint *ui = (GLuint *) image; for (i = 0; i < width * height; i++) { float p[3] = {0, 0, 0}; if (!IsUpperRight(i, width, height)) p[fillComponent] = 1; ui[i] = float3_to_rgb9e5(p); } return image; } else if (IsPackedType(type)) { const int bpp = SizeofType(type); GLubyte *image = new GLubyte [width * height * bpp]; GLuint masks[4]; int pos[4]; int i; ComponentMasks(type, masks); ComponentPositions(format, pos); const GLuint value = masks[fillComponent]; switch (bpp) { case 1: for (i = 0; i < width * height; i++) { if (IsUpperRight(i, width, height)) image[i] = 0; else image[i] = (GLubyte) value; } break; case 2: { GLushort *image16 = (GLushort *) image; for (i = 0; i < width * height; i++) { if (IsUpperRight(i, width, height)) image16[i] = 0; else image16[i] = (GLushort) value; } } break; case 4: { GLuint *image32 = (GLuint *) image; for (i = 0; i < width * height; i++) { if (IsUpperRight(i, width, height)) image32[i] = 0; else image32[i] = (GLuint) value; } } break; default: abort(); } return image; } else { const int comps = NumberOfComponentsInFormat(format); const int bpp = comps * SizeofType(type); assert(bpp > 0); GLubyte *image = new GLubyte [width * height * bpp]; int i; switch (type) { case GL_UNSIGNED_BYTE: for (i = 0; i < width * height * comps; i++) { if (i % comps == fillComponent && !IsUpperRight(i/comps, width, height)) image[i] = 0xff; else image[i] = 0x0; } break; case GL_BYTE: { GLbyte *b = (GLbyte *) image; for (i = 0; i < width * height * comps; i++) { if (i % comps == fillComponent && !IsUpperRight(i/comps, width, height)) b[i] = 0x7f; else b[i] = 0x0; } } break; case GL_UNSIGNED_SHORT: { GLushort *us = (GLushort *) image; for (i = 0; i < width * height * comps; i++) { if (i % comps == fillComponent && !IsUpperRight(i/comps, width, height)) us[i] = 0xffff; else us[i] = 0x0; } } break; case GL_SHORT: { GLshort *s = (GLshort *) image; for (i = 0; i < width * height * comps; i++) { if (i % comps == fillComponent && !IsUpperRight(i/comps, width, height)) s[i] = 0x7fff; else s[i] = 0x0; } } break; case GL_UNSIGNED_INT: { GLuint *ui = (GLuint *) image; for (i = 0; i < width * height * comps; i++) { if (i % comps == fillComponent && !IsUpperRight(i/comps, width, height)) ui[i] = 0xffffffff; else ui[i] = 0x0; } } break; case GL_INT: { GLint *in = (GLint *) image; for (i = 0; i < width * height * comps; i++) { if (i % comps == fillComponent && !IsUpperRight(i/comps, width, height)) in[i] = 0x7fffffff; else in[i] = 0x0; } } break; case GL_FLOAT: { GLfloat *f = (GLfloat *) image; for (i = 0; i < width * height * comps; i++) { if (i % comps == fillComponent && !IsUpperRight(i/comps, width, height)) f[i] = 1.0; else f[i] = 0.0; } } break; case GL_HALF_FLOAT_ARB: { GLhalfARB *f = (GLhalfARB *) image; for (i = 0; i < width * height * comps; i++) { if (i % comps == fillComponent && !IsUpperRight(i/comps, width, height)) f[i] = 0x3c00; /* == 1.0 */ else f[i] = 0; } } break; default: abort(); } return image; } }