
這個(gè) Bug 是在將工程的 Deployment Target 從 8.0 升級到 9.0 后出現(xiàn)的, 錯誤代碼如下:
NSDictionary *optionDict = @{GLKTextureLoaderOriginBottomLeft:@(YES)};
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:procImgRef options:optionDict error:&error];
錯誤信息:
ErrorDomain=GLKTextureLoaderErrorDomain errorCode=12
同樣的代碼在 Deployment Target = 8.0 時(shí)沒有問題...
過程:
升級OpenGL ES 2.0 -> 3.0 遇到同樣錯誤.
查看OpenGL ES 3.0 新功能和改動, 并無紋理加載的相關(guān)的改動.
嘗試更換加載API:
// 失敗
+ (nullable GLKTextureInfo *)textureWithContentsOfFile:(NSString *)path /* File path of image. */
options:(nullable NSDictionary<NSString*, NSNumber*> *)options /* Options that control how the image is loaded. */
error:(NSError * __nullable * __nullable)outError; /* Error description. */
// 通過 UIImagePNGRepresentation 轉(zhuǎn)換成 Data 后加載成功, 但是 Alpha 通道數(shù)據(jù)異常
+ (nullable GLKTextureInfo *)textureWithContentsOfData:(NSData *)data /* NSData containing image contents. */
options:(nullable NSDictionary<NSString*, NSNumber*> *)options /* Options that control how the image is loaded. */
error:(NSError * __nullable * __nullable)outError; /* Error description. */
嘗試轉(zhuǎn)成JPEG后加載, 丟失透明通道, 但是加載成功.
以為是格式問題, 代碼創(chuàng)建Bitmap上下文并重新渲染, 生成了各種格式的圖片, 發(fā)現(xiàn)只有 CGImageAlphaInfo = kCGImageAlphaNone 的圖片能加載成功.
大致判斷錯誤應(yīng)該是在Alpha通道上, 仔細(xì)查看 Texture Loading Options 參數(shù), 發(fā)現(xiàn)一個(gè)選項(xiàng):
/*
Dictionary keys for texture loader properties
*/
/*
GLKTextureLoaderApplyPremultiplication - A boolean NSNumber.
Non-alpha channels are premultiplied by corresponding alpha channel values.
For compressed formats, this option must be omitted, or false.
False by default.
*/
GLK_EXTERN NSString *const GLKTextureLoaderApplyPremultiplication NS_AVAILABLE(10_8, 5_0);
即應(yīng)用自左乘.
添加參數(shù) GLKTextureLoaderApplyPremultiplication 并設(shè)置成 YES, 加載成功!
CGImageAlphaInfo 有如下幾種:
typedef CF_ENUM(uint32_t, CGImageAlphaInfo) {
kCGImageAlphaNone, /* For example, RGB. */
kCGImageAlphaPremultipliedLast, /* For example, premultiplied RGBA */
kCGImageAlphaPremultipliedFirst, /* For example, premultiplied ARGB */
kCGImageAlphaLast, /* For example, non-premultiplied RGBA */
kCGImageAlphaFirst, /* For example, non-premultiplied ARGB */
kCGImageAlphaNoneSkipLast, /* For example, RBGX. */
kCGImageAlphaNoneSkipFirst, /* For example, XRGB. */
kCGImageAlphaOnly /* No color data, alpha data only */
};
后來查了一下我的 CGImageAlphaInfo 是 kCGImageAlphaPremultipliedLast.
按理說這個(gè)參數(shù)一直都要設(shè)置成YES才行.
很奇怪的是 這個(gè)問題在 8.0 的時(shí)候沒有問題, 怎么到 9.0 就崩潰了....
解決辦法:
optionDict 添加配置參數(shù) GLKTextureLoaderApplyPremultiplication 并設(shè)置為 YES 并更換 API
NSDictionary *optionDict = @{GLKTextureLoaderOriginBottomLeft:@(YES), GLKTextureLoaderApplyPremultiplication:@(YES)};
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfData:UIImagePNGRepresentation(procImg) options:optionDict error:&error];