OpenGL ES 2.0/3.0 GLKTextureLoader加載圖片/紋理錯誤 errorCode=12

image.png

這個(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];
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容