无法在多线程Android应用程序上调用glGenTextures

时间:2010-08-20 02:57:40

标签: android opengl-es android-ndk textures

我正在使用Android NDK制作一个OpenGLES Android应用程序,从android的gljni示例扩展,可以找到here

它正在使用GLSurfaceView。纹理在从GLSurfaceView.Renderer的onSurfaceChanged()调用的JNI函数中初始化

当用户触摸屏幕时,应用程序需要更多纹理。为了做到这一点,glGenTextures()在onTouchEvent()中调用的JNI函数中调用。

问题是线程id(gettid()返回)看起来完全是任意的,并且与具有OpenGL上下文的线程id不一样。

如果在同一个线程中调用JNI函数,它会加载并显示纹理,但如果它在另一个线程上则会失败。所以它的行为非常随意。

我可以这样做:

  • 分享OpenGL上下文,以便我可以在任何线程上成功调用glGenTextures()。

  • 使onTouchEvent()仅在一个具有OpenGl Context的线程中被调用

  • 或任何我能使其发挥作用的事情

由于

4 个答案:

答案 0 :(得分:2)

我没有使用过NDK和OpenGL。但是使用纯Java版本,您无法共享线程。 GLSurfaceView不喜欢在线程之间共享GL上下文。这个原因(从我能够分辨出来的)是在drawFrame()调用之后,上下文丢失了。如果您尝试在不在onSurfaceCreated,onSurfaceChanged或onDrawFrame()内部时使用该上下文,则您的GL方法将不起作用。因此,使用不同的线程很可能在其他线程执行时,GL线程已经完成了drawFrame()方法,使上下文无效。

答案 1 :(得分:2)

我使用GLSurfaceView.queueEvent()。

该文档说GLSurfaceView小心分离UI线程和渲染线程,

queueEvent()使代码在其渲染线程中运行。

答案 2 :(得分:2)

这不是随机行为,而是OpenGL与线程交互的方式。上下文仅在一个线程上是当前的,其他线程没有GL上下文,除非您为要与OpenGL一起使用的每个线程专门创建上下文。没有上下文,所有GL调用都会失败。

答案 3 :(得分:0)

我描述了一个仅用于java的解决方案,用于在单独的线程上上传纹理作为另一个问题的答案:Threading textures load process for android opengl game

它应该与NDK非常相似。