/* static */ GLenum GlfBaseTextureData::_GLInternalFormatFromImageData( GLenum format, GLenum type, bool isSRGB) { int numElements = GlfGetNumElements(format); bool g = (numElements == 1); bool a = (numElements == 4); switch (type) { case GL_UNSIGNED_INT: return g ? GL_R16 : (a ? GL_RGBA16 : GL_RGB16); case GL_HALF_FLOAT: return g ? GL_R16F : (a ? GL_RGBA16F : GL_RGB16F); case GL_FLOAT: case GL_DOUBLE: return g ? GL_R32F : (a ? GL_RGBA32F : GL_RGB32F); case GL_UNSIGNED_BYTE: default: return g ? GL_RED : (a ? (isSRGB ? GL_SRGB_ALPHA : GL_RGBA) : (isSRGB ? GL_SRGB : GL_RGB)); } }
void GlfBaseTexture::_CreateTexture(GlfBaseTextureDataConstPtr texData, bool const generateMipmap, int const unpackCropTop, int const unpackCropBottom, int const unpackCropLeft, int const unpackCropRight) { TRACE_FUNCTION(); if (texData and texData->HasRawBuffer()) { glBindTexture( GL_TEXTURE_2D, _textureName); glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, generateMipmap ? GL_TRUE : GL_FALSE); if (not texData->IsCompressed()) { if (GlfGetNumElements(texData->GLFormat()) == 1) { GLint swizzleMask[] = {GL_RED, GL_RED, GL_RED, GL_ONE}; glTexParameteriv( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } int texDataWidth = texData->ResizedWidth(); int texDataHeight = texData->ResizedHeight(); int unpackRowLength = texDataWidth; int unpackSkipPixels = 0; int unpackSkipRows = 0; if (unpackCropTop < 0 or unpackCropTop > texDataHeight) { return; } else if (unpackCropTop > 0) { unpackSkipRows = unpackCropTop; texDataHeight -= unpackCropTop; } if (unpackCropBottom < 0 or unpackCropBottom > texDataHeight) { return; } else if (unpackCropBottom) { texDataHeight -= unpackCropBottom; } if (unpackCropLeft < 0 or unpackCropLeft > texDataWidth) { return; } else { unpackSkipPixels = unpackCropLeft; texDataWidth -= unpackCropLeft; } if (unpackCropRight < 0 or unpackCropRight > texDataWidth) { return; } else if (unpackCropRight > 0) { texDataWidth -= unpackCropRight; } glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels); glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackSkipRows); glTexImage2D( GL_TEXTURE_2D, 0, texData->GLInternalFormat(), texDataWidth, texDataHeight, 0, texData->GLFormat(), texData->GLType(), texData->GetRawBuffer()); glPopClientAttrib(); } else { // There should be no cropping when using compressed textures TF_VERIFY(unpackCropTop == 0 && unpackCropBottom == 0 && unpackCropLeft == 0 && unpackCropRight == 0); glCompressedTexImage2D( GL_TEXTURE_2D, 0, texData->GLInternalFormat(), texData->ResizedWidth(), texData->ResizedHeight(), 0, texData->ComputeBytesUsed(), texData->GetRawBuffer()); } glBindTexture( GL_TEXTURE_2D, 0); _SetMemoryUsed(texData->ComputeBytesUsed()); } }
void GlfBaseTexture::_CreateTexture(GlfBaseTextureDataConstPtr texData, bool const useMipmaps, int const unpackCropTop, int const unpackCropBottom, int const unpackCropLeft, int const unpackCropRight) { TRACE_FUNCTION(); if (texData && texData->HasRawBuffer()) { glBindTexture(GL_TEXTURE_2D, _textureName); // Check if mip maps have been requested, if so, it will either // enable automatic generation or use the ones loaded in cpu memory int numMipLevels = 1; if (useMipmaps) { numMipLevels = texData->GetNumMipLevels(); // When we are using uncompressed textures and late cropping // we won't use cpu loaded mips. if (!texData->IsCompressed() && (unpackCropRight || unpackCropLeft || unpackCropTop || unpackCropBottom)) { numMipLevels = 1; } if (numMipLevels > 1) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, numMipLevels-1); } else { glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); } } else { glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); } if (texData->IsCompressed()) { // Compressed textures don't have as many options, so // we just need to send the mips to the driver. for (int i = 0 ; i < numMipLevels; i++) { glCompressedTexImage2D( GL_TEXTURE_2D, i, texData->GLInternalFormat(), texData->ResizedWidth(i), texData->ResizedHeight(i), 0, texData->ComputeBytesUsedByMip(i), texData->GetRawBuffer(i)); } } else { // Uncompressed textures can have cropping and other special // behaviours. if (GlfGetNumElements(texData->GLFormat()) == 1) { GLint swizzleMask[] = {GL_RED, GL_RED, GL_RED, GL_ONE}; glTexParameteriv( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } // If we are not sending full mipchains to the gpu then we can // do some extra work in the driver to prepare our textures. if (numMipLevels == 1) { int texDataWidth = texData->ResizedWidth(); int texDataHeight = texData->ResizedHeight(); int unpackRowLength = texDataWidth; int unpackSkipPixels = 0; int unpackSkipRows = 0; if (unpackCropTop < 0 || unpackCropTop > texDataHeight) { return; } else if (unpackCropTop > 0) { unpackSkipRows = unpackCropTop; texDataHeight -= unpackCropTop; } if (unpackCropBottom < 0 || unpackCropBottom > texDataHeight) { return; } else if (unpackCropBottom) { texDataHeight -= unpackCropBottom; } if (unpackCropLeft < 0 || unpackCropLeft > texDataWidth) { return; } else { unpackSkipPixels = unpackCropLeft; texDataWidth -= unpackCropLeft; } if (unpackCropRight < 0 || unpackCropRight > texDataWidth) { return; } else if (unpackCropRight > 0) { texDataWidth -= unpackCropRight; } glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels); glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackSkipRows); // Send the mip to the driver now glTexImage2D( GL_TEXTURE_2D, 0, texData->GLInternalFormat(), texDataWidth, texDataHeight, 0, texData->GLFormat(), texData->GLType(), texData->GetRawBuffer(0)); // Reset the OpenGL state if we have modify it previously glPopClientAttrib(); } else { // Send the mips to the driver now for (int i = 0 ; i < numMipLevels; i++) { glTexImage2D( GL_TEXTURE_2D, i, texData->GLInternalFormat(), texData->ResizedWidth(i), texData->ResizedHeight(i), 0, texData->GLFormat(), texData->GLType(), texData->GetRawBuffer(i)); } } } glBindTexture(GL_TEXTURE_2D, 0); _SetMemoryUsed(texData->ComputeBytesUsed()); } }