iOS OpenGL ES常见问题整理

众所周知,OpenGL的鲁棒性很强,ES也同样,一般不会crash,例如某些接口传的参数不是OpenGL预期的类型,也很少会发生crash。可是,一旦发生了crash或渲染异常,由于其本质上是一个状态机,就导致了错误会累计,发生crash的现场并非问题的源头,十分难定位。好比OpenGL会经常挂在drawcall上,然而很有可能是在前面的glBindTexture、glTexImage2D或glUniformMatrix等方法中出现了问题。故此,本文根据笔者遇到的OpenGL ES问题,包括crash或渲染异常,整理出一份OpenGL ES在iOS系统中的问题快速定位表单。

问题现象

根本原因及解决方法

界面图片出现花屏

对于jpg图片解码后,以RGBA格式传入GPU纹理,需要添加alpha通道

glReadPixels crash,堆栈栈顶包含gldReadFramebufferData特征

glReadPixels宽高参数大于实际宽高

使用OES_texture_half_float扩展时,发生渲染异常

OES_texture_half_float使用时,需要在texImage2D改变internalFormat为GL_RGBA16F

Fbo上有时有画面,有时黑屏

使用的纹理没有设置wrap_s和wrap_t参数

游戏画面背景闪烁

由于背景只画了一次,前景局部刷新,而2d游戏EAGLLayer的kEAGLDrawablePropertyRetainedBacking属性设置为false,导致没保留上一帧内容,而闪烁怀疑是iOS的双缓冲甚至三缓冲机制导致的

iOS9系统手机画面部分黑屏

iOS 9使用glStencilFunc函数有问题,导致部分纹理没通过模板测试而黑屏,需要在调用该方法前调用glClearStencil(0xff)和glClear(GL_STENCIL_BUFFER_BIT)

iOS9系统图片花屏

iOS 9上使用CGContextDrawImage解码图片时会带上上一次解码的残影,即使是一个新的CGContext也会,需要在draw前clearRect

glTexImage2D crash可能情况1

传入参数中宽高参数与pixels不对应,宽高大于pixels实际宽高时crash,小于时花屏

glTexImage2D crash可能情况2

之前调用glPixelStorei修改过GL_UNPACK_ALIGNMENT参数,假如GL_UNPACK_ALIGNMENT大小与glTexImage2D中pixels参数的单位像素字节数不符就会crash,这是很明显的累积错误引发的crash

两个context交互时发生闪屏

两个context渲染时机不同步,需要使用glSync方法进行同步

两个context交互时发生部分纹理黑屏

两个context创建时没有共享shareGroup,导致纹理不共享,只能先传到CPU,再传给另一个context

gldReadFramebufferData crash

除了上面提到glReadPixels出问题的可能外,在内存不足情况下也会发生该crash,注意纹理等资源的及时释放

以上便是笔者到目前为止积累的OpenGL ES在iOS系统中常见问题的整理,后面假如遇到奇葩问题也会继续更新,而Android系统由于同样可以用OpenGL ES,问题可能也会有所类似,希望对大家定位OpenGL问题有所帮助。

iOS OpenGL ES常见问题整理

上一篇:axios在vue中的简单封装及应用


下一篇:深入理解java虚拟机【类加载机制】