Added support for compressed textures in OpenGL ES1 driver.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@4533 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
334cf13cd6
commit
a4b52c5c8a
|
@ -200,15 +200,16 @@ namespace video
|
|||
return true; // non-square is always supported
|
||||
case EVDF_TEXTURE_NPOT:
|
||||
return FeatureAvailable[IRR_APPLE_texture_2D_limited_npot];
|
||||
case EVDF_TEXTURE_COMPRESSED_DXT:
|
||||
return false; // NV Tegra need improvements here
|
||||
case EVDF_TEXTURE_COMPRESSED_PVRTC:
|
||||
case EVDF_TEXTURE_COMPRESSED_PVRTC2:
|
||||
return false; // PowerVR need improvements here
|
||||
case EVDF_TEXTURE_COMPRESSED_ETC1:
|
||||
return false; // Android based devices need improvements here
|
||||
case EVDF_TEXTURE_COMPRESSED_ETC2:
|
||||
return false;
|
||||
case EVDF_TEXTURE_COMPRESSED_DXT:
|
||||
return false; // NV Tegra need improvements here
|
||||
case EVDF_TEXTURE_COMPRESSED_PVRTC:
|
||||
return FeatureAvailable[IRR_IMG_texture_compression_pvrtc];
|
||||
case EVDF_TEXTURE_COMPRESSED_PVRTC2:
|
||||
return false;
|
||||
case EVDF_TEXTURE_COMPRESSED_ETC1:
|
||||
return FeatureAvailable[IRR_OES_compressed_ETC1_RGB8_texture];
|
||||
case EVDF_TEXTURE_COMPRESSED_ETC2:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -41,25 +41,45 @@ COGLES1Texture::COGLES1Texture(IImage* origImage, const io::path& name, COGLES1D
|
|||
#ifdef _DEBUG
|
||||
setDebugName("COGLES1Texture");
|
||||
#endif
|
||||
|
||||
#ifndef GL_BGRA
|
||||
// whoa, pretty badly implemented extension...
|
||||
if (Driver->FeatureAvailable[COGLES2ExtensionHandler::IRR_IMG_texture_format_BGRA8888] ||
|
||||
Driver->FeatureAvailable[COGLES2ExtensionHandler::IRR_EXT_texture_format_BGRA8888] ||
|
||||
Driver->FeatureAvailable[COGLES2ExtensionHandler::IRR_APPLE_texture_format_BGRA8888])
|
||||
GL_BGRA = 0x80E1;
|
||||
else
|
||||
GL_BGRA = GL_RGBA;
|
||||
#endif
|
||||
|
||||
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
|
||||
getImageValues(origImage);
|
||||
|
||||
glGenTextures(1, &TextureName);
|
||||
|
||||
Image = new CImage(ColorFormat, TextureSize);
|
||||
if (ImageSize==TextureSize)
|
||||
if (IsCompressed)
|
||||
{
|
||||
Image = origImage;
|
||||
Image->grab();
|
||||
KeepImage = false;
|
||||
}
|
||||
else if (ImageSize==TextureSize)
|
||||
{
|
||||
Image = Driver->createImage(ColorFormat, ImageSize);
|
||||
origImage->copyTo(Image);
|
||||
}
|
||||
else
|
||||
// scale texture
|
||||
{
|
||||
Image = Driver->createImage(ColorFormat, TextureSize);
|
||||
origImage->copyToScaling(Image);
|
||||
}
|
||||
|
||||
glGenTextures(1, &TextureName);
|
||||
uploadTexture(true, mipmapData);
|
||||
|
||||
if (!KeepImage)
|
||||
{
|
||||
Image->drop();
|
||||
Image=0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,53 +107,218 @@ COGLES1Texture::~COGLES1Texture()
|
|||
}
|
||||
|
||||
|
||||
//! Choose best matching color format, based on texture creation flags
|
||||
ECOLOR_FORMAT COGLES1Texture::getBestColorFormat(ECOLOR_FORMAT format)
|
||||
{
|
||||
ECOLOR_FORMAT destFormat = ECF_A8R8G8B8;
|
||||
switch (format)
|
||||
|
||||
if (!IImage::isCompressedFormat(format))
|
||||
{
|
||||
case ECF_A1R5G5B5:
|
||||
if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT))
|
||||
destFormat = ECF_A1R5G5B5;
|
||||
break;
|
||||
case ECF_R5G6B5:
|
||||
if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT))
|
||||
destFormat = ECF_A1R5G5B5;
|
||||
break;
|
||||
case ECF_A8R8G8B8:
|
||||
if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) ||
|
||||
switch (format)
|
||||
{
|
||||
case ECF_A1R5G5B5:
|
||||
if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT))
|
||||
destFormat = ECF_A1R5G5B5;
|
||||
break;
|
||||
case ECF_R5G6B5:
|
||||
if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT))
|
||||
destFormat = ECF_A1R5G5B5;
|
||||
break;
|
||||
case ECF_A8R8G8B8:
|
||||
if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) ||
|
||||
Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
|
||||
destFormat = ECF_A1R5G5B5;
|
||||
break;
|
||||
case ECF_R8G8B8:
|
||||
if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) ||
|
||||
destFormat = ECF_A1R5G5B5;
|
||||
break;
|
||||
case ECF_R8G8B8:
|
||||
if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) ||
|
||||
Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
|
||||
destFormat = ECF_A1R5G5B5;
|
||||
break;
|
||||
destFormat = ECF_A1R5G5B5;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
destFormat = format;
|
||||
|
||||
if (Driver->getTextureCreationFlag(ETCF_NO_ALPHA_CHANNEL))
|
||||
{
|
||||
switch (destFormat)
|
||||
{
|
||||
case ECF_A1R5G5B5:
|
||||
destFormat = ECF_R5G6B5;
|
||||
break;
|
||||
break;
|
||||
case ECF_A8R8G8B8:
|
||||
destFormat = ECF_R8G8B8;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return destFormat;
|
||||
}
|
||||
|
||||
|
||||
//! Get the OpenGL color format parameters based on the given Irrlicht color format
|
||||
void COGLES1Texture::getFormatParameters(ECOLOR_FORMAT format, GLint& internalFormat, GLint& filtering,
|
||||
GLenum& pixelFormat, GLenum& type, void(*&convert)(const void*, s32, void*))
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case ECF_A1R5G5B5:
|
||||
internalFormat = GL_RGBA;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGBA;
|
||||
type = GL_UNSIGNED_SHORT_5_5_5_1;
|
||||
convert = CColorConverter::convert_A1R5G5B5toR5G5B5A1;
|
||||
break;
|
||||
case ECF_R5G6B5:
|
||||
internalFormat = GL_RGB;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGB;
|
||||
type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
break;
|
||||
case ECF_R8G8B8:
|
||||
internalFormat = GL_RGB;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGB;
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
convert = CColorConverter::convert_R8G8B8toB8G8R8;
|
||||
break;
|
||||
case ECF_A8R8G8B8:
|
||||
filtering = GL_LINEAR;
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
if (!Driver->queryOpenGLFeature(COGLES1ExtensionHandler::IRR_IMG_texture_format_BGRA8888) &&
|
||||
!Driver->queryOpenGLFeature(COGLES1ExtensionHandler::IRR_EXT_texture_format_BGRA8888) &&
|
||||
!Driver->queryOpenGLFeature(COGLES1ExtensionHandler::IRR_APPLE_texture_format_BGRA8888))
|
||||
{
|
||||
internalFormat = GL_RGBA;
|
||||
pixelFormat = GL_RGBA;
|
||||
convert = CColorConverter::convert_A8R8G8B8toA8B8G8R8;
|
||||
}
|
||||
else
|
||||
{
|
||||
internalFormat = GL_BGRA;
|
||||
pixelFormat = GL_BGRA;
|
||||
}
|
||||
break;
|
||||
#ifdef GL_EXT_texture_compression_s3tc
|
||||
case ECF_DXT1:
|
||||
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_BGRA;
|
||||
type = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_EXT_texture_compression_s3tc
|
||||
case ECF_DXT2:
|
||||
case ECF_DXT3:
|
||||
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_BGRA;
|
||||
type = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_EXT_texture_compression_s3tc
|
||||
case ECF_DXT4:
|
||||
case ECF_DXT5:
|
||||
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_BGRA;
|
||||
type = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_IMG_texture_compression_pvrtc
|
||||
case ECF_PVRTC_RGB2:
|
||||
internalFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGB;
|
||||
type = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_IMG_texture_compression_pvrtc
|
||||
case ECF_PVRTC_ARGB2:
|
||||
internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGBA;
|
||||
type = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_IMG_texture_compression_pvrtc
|
||||
case ECF_PVRTC_RGB4:
|
||||
internalFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGB;
|
||||
type = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_IMG_texture_compression_pvrtc
|
||||
case ECF_PVRTC_ARGB4:
|
||||
internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGBA;
|
||||
type = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_IMG_texture_compression_pvrtc2
|
||||
case ECF_PVRTC2_ARGB2:
|
||||
internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGBA;
|
||||
type = GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_IMG_texture_compression_pvrtc2
|
||||
case ECF_PVRTC2_ARGB4:
|
||||
internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGBA;
|
||||
type = GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_OES_compressed_ETC1_RGB8_texture
|
||||
case ECF_ETC1:
|
||||
internalFormat = GL_ETC1_RGB8_OES;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGB;
|
||||
type = GL_ETC1_RGB8_OES;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_ES_VERSION_3_0 // TO-DO - fix when extension name will be available
|
||||
case ECF_ETC2_RGB:
|
||||
internalFormat = GL_COMPRESSED_RGB8_ETC2;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGB;
|
||||
type = GL_COMPRESSED_RGB8_ETC2;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_ES_VERSION_3_0 // TO-DO - fix when extension name will be available
|
||||
case ECF_ETC2_ARGB:
|
||||
internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
|
||||
filtering = GL_LINEAR;
|
||||
pixelFormat = GL_RGBA;
|
||||
type = GL_COMPRESSED_RGBA8_ETC2_EAC;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
os::Printer::log("Unsupported texture format", ELL_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
// Hack for iPhone SDK, which requires a different InternalFormat
|
||||
#ifdef _IRR_IPHONE_PLATFORM_
|
||||
if (internalFormat == GL_BGRA)
|
||||
internalFormat = GL_RGBA;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void COGLES1Texture::getImageValues(IImage* image)
|
||||
{
|
||||
if (!image)
|
||||
{
|
||||
os::Printer::log("No image for OGLES1 texture.", ELL_ERROR);
|
||||
os::Printer::log("No image for OpenGL ES1 texture.", ELL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -141,7 +326,7 @@ void COGLES1Texture::getImageValues(IImage* image)
|
|||
|
||||
if ( !ImageSize.Width || !ImageSize.Height)
|
||||
{
|
||||
os::Printer::log("Invalid size of image for OGLES1 Texture.", ELL_ERROR);
|
||||
os::Printer::log("Invalid size of image for OpenGL ES1 Texture.", ELL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -167,107 +352,59 @@ void COGLES1Texture::getImageValues(IImage* image)
|
|||
//! copies the the texture into an open gl texture.
|
||||
void COGLES1Texture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
||||
{
|
||||
// check which image needs to be uploaded
|
||||
IImage* image = level?MipImage:Image;
|
||||
if (!image)
|
||||
{
|
||||
os::Printer::log("No image for OGLES1 texture to upload", ELL_ERROR);
|
||||
os::Printer::log("No image for OpenGL ES1 texture to upload", ELL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef GL_BGRA
|
||||
// whoa, pretty badly implemented extension...
|
||||
if (Driver->FeatureAvailable[COGLES1ExtensionHandler::IRR_IMG_texture_format_BGRA8888] || Driver->FeatureAvailable[COGLES1ExtensionHandler::IRR_EXT_texture_format_BGRA8888])
|
||||
GL_BGRA=0x80E1;
|
||||
else
|
||||
GL_BGRA=GL_RGBA;
|
||||
#endif
|
||||
// get correct opengl color data values
|
||||
GLint oldInternalFormat = InternalFormat;
|
||||
GLint filtering = GL_LINEAR;
|
||||
void(*convert)(const void*, s32, void*) = 0;
|
||||
getFormatParameters(ColorFormat, InternalFormat, filtering, PixelFormat, PixelType, convert);
|
||||
|
||||
GLenum oldInternalFormat = InternalFormat;
|
||||
void(*convert)(const void*, s32, void*)=0;
|
||||
switch (Image->getColorFormat())
|
||||
{
|
||||
case ECF_A1R5G5B5:
|
||||
InternalFormat=GL_RGBA;
|
||||
PixelFormat=GL_RGBA;
|
||||
PixelType=GL_UNSIGNED_SHORT_5_5_5_1;
|
||||
convert=CColorConverter::convert_A1R5G5B5toR5G5B5A1;
|
||||
break;
|
||||
case ECF_R5G6B5:
|
||||
InternalFormat=GL_RGB;
|
||||
PixelFormat=GL_RGB;
|
||||
PixelType=GL_UNSIGNED_SHORT_5_6_5;
|
||||
break;
|
||||
case ECF_R8G8B8:
|
||||
InternalFormat=GL_RGB;
|
||||
PixelFormat=GL_RGB;
|
||||
PixelType=GL_UNSIGNED_BYTE;
|
||||
convert=CColorConverter::convert_R8G8B8toB8G8R8;
|
||||
break;
|
||||
case ECF_A8R8G8B8:
|
||||
PixelType=GL_UNSIGNED_BYTE;
|
||||
if (!Driver->queryOpenGLFeature(COGLES1ExtensionHandler::IRR_IMG_texture_format_BGRA8888) && !Driver->queryOpenGLFeature(COGLES1ExtensionHandler::IRR_EXT_texture_format_BGRA8888))
|
||||
{
|
||||
convert=CColorConverter::convert_A8R8G8B8toA8B8G8R8;
|
||||
InternalFormat=GL_RGBA;
|
||||
PixelFormat=GL_RGBA;
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalFormat=GL_BGRA;
|
||||
PixelFormat=GL_BGRA;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
os::Printer::log("Unsupported texture format", ELL_ERROR);
|
||||
break;
|
||||
}
|
||||
// Hack for iPhone SDK, which requires a different InternalFormat
|
||||
#ifdef _IRR_IPHONE_PLATFORM_
|
||||
if (InternalFormat==GL_BGRA)
|
||||
InternalFormat=GL_RGBA;
|
||||
#endif
|
||||
// make sure we don't change the internal format of existing matrices
|
||||
// make sure we don't change the internal format of existing images
|
||||
if (!newTexture)
|
||||
InternalFormat=oldInternalFormat;
|
||||
InternalFormat = oldInternalFormat;
|
||||
|
||||
Driver->setActiveTexture(0, this);
|
||||
|
||||
Driver->setActiveTexture(0, this);
|
||||
if (Driver->testGLError())
|
||||
os::Printer::log("Could not bind Texture", ELL_ERROR);
|
||||
|
||||
// mipmap handling for main texture
|
||||
if (!level && newTexture)
|
||||
{
|
||||
#ifndef DISABLE_MIPMAPPING
|
||||
if (HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
|
||||
// auto generate if possible and no mipmap data is given
|
||||
if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
|
||||
{
|
||||
// automatically generate and update mipmaps
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
|
||||
if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
|
||||
else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
|
||||
else
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
AutomaticMipmapUpdate=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AutomaticMipmapUpdate=false;
|
||||
regenerateMipMapLevels(mipmapData);
|
||||
}
|
||||
if (HasMipMaps) // might have changed in regenerateMipMapLevels
|
||||
{
|
||||
// enable bilinear mipmap filter
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
#else
|
||||
HasMipMaps=false;
|
||||
os::Printer::log("Did not create OGLES1 texture mip maps.", ELL_ERROR);
|
||||
#endif
|
||||
{
|
||||
// enable bilinear filter without mipmaps
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
// enable bilinear filter without mipmaps
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
}
|
||||
|
||||
// now get image data and upload to GPU
|
||||
|
||||
u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height);
|
||||
|
||||
void* source = image->lock();
|
||||
IImage* tmpImage=0;
|
||||
|
||||
IImage* tmpImage = 0;
|
||||
|
||||
if (convert)
|
||||
{
|
||||
tmpImage = new CImage(image->getColorFormat(), image->getDimension());
|
||||
|
@ -276,12 +413,30 @@ void COGLES1Texture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
image->unlock();
|
||||
source = dest;
|
||||
}
|
||||
|
||||
if (newTexture)
|
||||
glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width,
|
||||
image->getDimension().Height, 0, PixelFormat, PixelType, source);
|
||||
{
|
||||
if (IsCompressed)
|
||||
{
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width,
|
||||
image->getDimension().Height, 0, compressedImageSize, source);
|
||||
}
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width,
|
||||
image->getDimension().Height, 0, PixelFormat, PixelType, source);
|
||||
}
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
|
||||
image->getDimension().Height, PixelFormat, PixelType, source);
|
||||
{
|
||||
if (IsCompressed)
|
||||
{
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
|
||||
image->getDimension().Height, PixelFormat, compressedImageSize, source);
|
||||
}
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
|
||||
image->getDimension().Height, PixelFormat, PixelType, source);
|
||||
}
|
||||
|
||||
if (convert)
|
||||
{
|
||||
tmpImage->unlock();
|
||||
|
@ -290,6 +445,31 @@ void COGLES1Texture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
else
|
||||
image->unlock();
|
||||
|
||||
if (!level && newTexture)
|
||||
{
|
||||
if (IsCompressed && !mipmapData)
|
||||
{
|
||||
if (image->hasMipMaps())
|
||||
mipmapData = static_cast<u8*>(image->lock())+compressedImageSize;
|
||||
else
|
||||
HasMipMaps = false;
|
||||
}
|
||||
|
||||
regenerateMipMapLevels(mipmapData);
|
||||
|
||||
if (HasMipMaps) // might have changed in regenerateMipMapLevels
|
||||
{
|
||||
// enable bilinear mipmap filter
|
||||
GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST;
|
||||
|
||||
if (filtering != GL_LINEAR)
|
||||
filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST;
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps);
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
}
|
||||
}
|
||||
|
||||
if (Driver->testGLError())
|
||||
os::Printer::log("Could not glTexImage2D", ELL_ERROR);
|
||||
}
|
||||
|
@ -414,47 +594,70 @@ bool COGLES1Texture::hasMipMaps() const
|
|||
//! Regenerates the mip map levels of the texture.
|
||||
void COGLES1Texture::regenerateMipMapLevels(void* mipmapData)
|
||||
{
|
||||
if (AutomaticMipmapUpdate || !HasMipMaps || !Image)
|
||||
return;
|
||||
if ((Image->getDimension().Width==1) && (Image->getDimension().Height==1))
|
||||
// texture require mipmaps?
|
||||
if (!HasMipMaps || AutomaticMipmapUpdate)
|
||||
return;
|
||||
|
||||
// Manually create mipmaps
|
||||
// we don't use custom data for mipmaps.
|
||||
if (!mipmapData)
|
||||
{
|
||||
// compressed textures require custom data for prepare mipmaps.
|
||||
if (IsCompressed)
|
||||
return;
|
||||
|
||||
// hardware doesn't support generate mipmaps for certain texture but image data doesn't exist or is wrong.
|
||||
if (!Image || (Image && ((Image->getDimension().Width==1) && (Image->getDimension().Height==1))))
|
||||
return;
|
||||
}
|
||||
|
||||
// Manually create mipmaps or use prepared version
|
||||
u32 compressedImageSize = 0;
|
||||
u32 width=Image->getDimension().Width;
|
||||
u32 height=Image->getDimension().Height;
|
||||
u32 i=0;
|
||||
if (mipmapData)
|
||||
u8* target = static_cast<u8*>(mipmapData);
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
if (width>1)
|
||||
width>>=1;
|
||||
if (height>1)
|
||||
height>>=1;
|
||||
++i;
|
||||
glTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, height,
|
||||
0, PixelFormat, PixelType, mipmapData);
|
||||
mipmapData = ((u8*)mipmapData)+width*height*Image->getBytesPerPixel();
|
||||
}
|
||||
while (width!=1 || height!=1);
|
||||
}
|
||||
else
|
||||
{
|
||||
u8* target = new u8[Image->getImageDataSizeInBytes()];
|
||||
do
|
||||
{
|
||||
if (width>1)
|
||||
width>>=1;
|
||||
if (height>1)
|
||||
height>>=1;
|
||||
++i;
|
||||
if (width>1)
|
||||
width>>=1;
|
||||
if (height>1)
|
||||
height>>=1;
|
||||
|
||||
++i;
|
||||
|
||||
if (!target)
|
||||
target = new u8[width*height*Image->getBytesPerPixel()];
|
||||
|
||||
// create scaled version if no mipdata available
|
||||
if (!mipmapData)
|
||||
Image->copyToScaling(target, width, height, Image->getColorFormat());
|
||||
|
||||
if (IsCompressed)
|
||||
{
|
||||
compressedImageSize = IImage::getCompressedImageSize(ColorFormat, width, height);
|
||||
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width,
|
||||
height, 0, compressedImageSize, target);
|
||||
}
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, height,
|
||||
0, PixelFormat, PixelType, target);
|
||||
|
||||
// get next prepared mipmap data if available
|
||||
if (mipmapData)
|
||||
{
|
||||
if (IsCompressed)
|
||||
mipmapData = static_cast<u8*>(mipmapData)+compressedImageSize;
|
||||
else
|
||||
mipmapData = static_cast<u8*>(mipmapData)+width*height*Image->getBytesPerPixel();
|
||||
|
||||
target = static_cast<u8*>(mipmapData);
|
||||
}
|
||||
while (width!=1 || height!=1);
|
||||
delete [] target;
|
||||
}
|
||||
while (width!=1 || height!=1);
|
||||
// cleanup
|
||||
if (!mipmapData)
|
||||
delete [] target;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -90,6 +90,10 @@ protected:
|
|||
|
||||
//! get the desired color format based on texture creation flags and the input format.
|
||||
ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format);
|
||||
|
||||
//! Get the OpenGL color format parameters based on the given Irrlicht color format
|
||||
void getFormatParameters(ECOLOR_FORMAT format, GLint& internalFormat, GLint& filtering,
|
||||
GLenum& pixelFormat, GLenum& type, void(*&convert)(const void*, s32, void*));
|
||||
|
||||
//! convert the image into an internal image with better properties for this driver.
|
||||
void getImageValues(IImage* image);
|
||||
|
|
Loading…
Reference in New Issue