--- irrlicht/source/Irrlicht/COGLESTexture.cpp.orig 2014-06-22 17:01:13.266568869 +0200 +++ irrlicht/source/Irrlicht/COGLESTexture.cpp 2014-06-22 17:03:59.298572810 +0200 @@ -366,112 +366,140 @@ void(*convert)(const void*, s32, void*) = 0; getFormatParameters(ColorFormat, InternalFormat, filtering, PixelFormat, PixelType, convert); - // make sure we don't change the internal format of existing images - if (!newTexture) - InternalFormat = oldInternalFormat; - - Driver->setActiveTexture(0, this); - - if (Driver->testGLError()) - os::Printer::log("Could not bind Texture", ELL_ERROR); - - // mipmap handling for main texture - if (!level && newTexture) - { - // auto generate if possible and no mipmap data is given - if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) - { - 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); + bool retry = false; + + do { + if (retry) { + InternalFormat = GL_RGBA; + PixelFormat = GL_RGBA; + convert = CColorConverter::convert_A8R8G8B8toA8B8G8R8; + } + // make sure we don't change the internal format of existing images + if (!newTexture) + InternalFormat = oldInternalFormat; - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - AutomaticMipmapUpdate=true; - } + Driver->setActiveTexture(0, this); - // enable bilinear filter without mipmaps - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); - } + if (Driver->testGLError()) + os::Printer::log("Could not bind Texture", ELL_ERROR); - // now get image data and upload to GPU + // mipmap handling for main texture + if (!level && newTexture) + { + // auto generate if possible and no mipmap data is given + if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) + { + 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; + } + + // enable bilinear filter without mipmaps + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); + } - u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height); + // now get image data and upload to GPU - void* source = image->lock(); + u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height); - IImage* tmpImage = 0; + void* source = image->lock(); - if (convert) - { - tmpImage = new CImage(image->getColorFormat(), image->getDimension()); - void* dest = tmpImage->lock(); - convert(source, image->getDimension().getArea(), dest); - image->unlock(); - source = dest; - } + IImage* tmpImage = 0; - if (newTexture) - { - if (IsCompressed) + if (convert) { - glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width, - image->getDimension().Height, 0, compressedImageSize, source); + tmpImage = new CImage(image->getColorFormat(), image->getDimension()); + void* dest = tmpImage->lock(); + convert(source, image->getDimension().getArea(), dest); + image->unlock(); + source = dest; } - else - glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width, - image->getDimension().Height, 0, PixelFormat, PixelType, source); - } - else - { - if (IsCompressed) + + if (newTexture) { - glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, - image->getDimension().Height, PixelFormat, compressedImageSize, 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 (convert) - { - tmpImage->unlock(); - tmpImage->drop(); - } - else - image->unlock(); - - if (!level && newTexture) - { - if (IsCompressed && !mipmapData) { - if (image->hasMipMaps()) - mipmapData = static_cast<u8*>(image->lock())+compressedImageSize; + if (IsCompressed) + { + glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, + image->getDimension().Height, PixelFormat, compressedImageSize, source); + } else - HasMipMaps = false; + glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, + image->getDimension().Height, PixelFormat, PixelType, source); } - regenerateMipMapLevels(mipmapData); - - if (HasMipMaps) // might have changed in regenerateMipMapLevels + if (convert) { - // enable bilinear mipmap filter - GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST; - - if (filtering != GL_LINEAR) - filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST; + tmpImage->unlock(); + tmpImage->drop(); + } + else + image->unlock(); + + if (glGetError() != GL_NO_ERROR) { + static bool warned = false; + if ((!retry) && (ColorFormat == ECF_A8R8G8B8)) { + + if (!warned) { + os::Printer::log("Your driver claims to support GL_BGRA but fails on trying to upload a texture, converting to GL_RGBA and trying again", ELL_ERROR); + warned = true; + } + } + else if (retry) { + os::Printer::log("Neither uploading texture as GL_BGRA nor, converted one using GL_RGBA succeeded", ELL_ERROR); + } + retry = !retry; + continue; + } else { + retry = false; + } - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); + 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); + if (Driver->testGLError()) + os::Printer::log("Could not glTexImage2D", ELL_ERROR); + } + while(retry); } --- irrlicht/source/Irrlicht/COGLESTexture.cpp.orig 2014-06-25 00:28:50.820501856 +0200 +++ irrlicht/source/Irrlicht/COGLESTexture.cpp 2014-06-25 00:08:37.712544692 +0200 @@ -422,6 +422,9 @@ source = dest; } + //clear old error + glGetError(); + if (newTexture) { if (IsCompressed)