android – 为什么OpenGL ES函数不能从另一个线程调用

前端之家收集整理的这篇文章主要介绍了android – 为什么OpenGL ES函数不能从另一个线程调用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用OpenGL ES为 Android编写一个小型游戏引擎.我创建了一个游戏线程,更新游戏对象和GLThread绘制场景.我已经读过,需要在GLSurfaceView的onSurfaceCreated方法中加载纹理.我正在关注,但为了一些调试目的,我试图从我的游戏线程加载纹理,而不是GLThread.我没有错误,纹理没有显示在屏幕上.我花了整整一天的时间来弄清楚问题,最后我读了下面的 here

“只要确保在主线程中只使用OpenGL.”很重要.您不能在游戏引擎(可能在另一个线程中)调用与gl线程不同步的纹理加载功能.设置一个标志来表示您的gl线程加载新的纹理(例如,您可以在OnDrawFrame(GL gl)中放置一个函数,该函数检查是否必须加载新的纹理.

我将修改我的代码,使纹理从GL线程加载.我只是不明白为什么会这样?为什么OpenGL功能不能从另一个线程工作?

我知道如何创建线程,但我不知道什么同步意味着.上面的提取提到,“你不能在你的游戏引擎(可能在另一个线程)中调用一个纹理加载函数,它与gl线程不同步.所以我猜我的游戏线程可能不会与GL线程同步.是否可以创建与GL Thread同步的另一个线程,以便可以从中调用GL函数?要了解这些概念,我应该学习什么?

解决方法

我认为quixoto的评论是最接近的. OpenGL上下文在几乎每一个平台上都是线程特定的传统原因是OpenGL严重依赖于状态,并且没有使一系列更改成为原子的语义.所以,例如,一个线程上的绘图操作可能是:
glVertexPointer(... supply vertex positions ...)
glTexCoordPointer(... provide texture positions ...)
/* and supply a few other pointers,maybe bind a texture */

glDrawArrays(... draw some geometry ...)

所以最后的调用仅在前面的调用的上下文中提供可预测的结果.如果您允许该位代码暂停,例如glVertexPointer,则另一个线程跳入并执行大致相同的序列来绘制其几何,然后该代码继续进行,它将绘制相当错误的几何,甚至可能导致如果某些替换的数组小于原始数据,则会限制存储器访问.

Android提供了EGL,它支持OpenGL共享组的通用概念(虽然隐含地提供了一个现有上下文,您希望新的上下文通过第七个参数到eglCreateContext).如果两个上下文在共享组中,那么它们中的每一个都具有独立状态,并且可以安全地仅从一个线程调用,但命名的对象(例如纹理或顶点缓冲对象)可用于每个线程.所以使用共享组可以同时在多个线程上执行OpenGL操作,以便能够将结果组合在一个线程上.

因此,将上下文绑定到单个线程不是一个问题.规划OpenGL本身的问题也将是一个非启动因素,因为OpenGL上下文的一个原因是以特定于操作系统的方式创建,管理和处理,因为某些操作系统需要以完全不同的方式处理这些内容给其他人或者通过暴露自己独特的解决方案能够提供更好的解决方案.

猜你在找的Android相关文章