背景
最近在做Android/iOS + Native渲染工作,使用OpenGL在Native层或者Android上层进行渲染上屏,起初是在Native层创建的渲染线程并初始化OpenGL环境,Android通过启动Native层渲染环境并创建纹理后,设置和更新SurfaceTexture,在Native层的渲染线程进行渲染并直接上屏,一切都很正常,后来由于业务需要,Native层的处理需要接收输入纹理和输出纹理,由Android层创建维护渲染线程和GL环境,并调用Native进行图形处理,完成渲染工作。
但实际运行的时候,发现无法上屏(黑屏),也不会报错,于是开启漫长的找影响因素之路。
漫漫之路
Android上使用的是GLSurfaceView自带的GLThread进行环境初始化等,正常情况下,对于Program、Shader等,只需要初始化一次后,每一帧的渲染直接进行绘制即可,我也是这样做的,但发现运行后是黑屏-_-!!!
在一次一次验证尝试中发现一些规律:
- 在draw的loop中,使用局部变量进行绘制正常(Native引擎的原有实现就是局部变量)
- 将局部遍历提出为全局变量,绘制黑屏
- 使用全局变量,在每次都重新compile、link等工作,draw后释放,绘制正常
- (关键)进一步锁定,发现每次只有重新gen vao、bind vbo等,绘制正常
于是,大致有个猜测是可能vao失效了。
由于Native层自己维护环境去做渲染工作,完全正常,所以怀疑是Android层影响到了Native层的vao,我们知道vao是OpenGL 3.0才支持的,于是进行一系列检查:
- Android的GLSurfaceView的版本:setEGLContextClientVersion(3) ,没问题
- Android的渲染会将OES绘制到2D纹理并传入到Native,这里的绘制并没有使用vao(关键)
OpenGL3.0之后默认使用vao,将Android层的渲染修改为vao的方式后,native层也正常了,猜测之前不正常是默认当做兼容2.0的版本了。
于是问题解决。
一些备注
vbo、ebo、vao介绍和使用:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/
注意:
- 使用vao进行绑定vbo、ebo时,解绑vao之前,不要解绑vbo和ebo。
-
使用vbo后,GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false,
2 * 4, 0);最后一个参数要调用offset的方法