【问题标题】:Can't call glGenTextures on multithreaded android app无法在多线程 android 应用程序上调用 glGenTextures
【发布时间】:2010-08-20 02:57:39
【问题描述】:

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

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

当用户触摸屏幕时,应用需要更多纹理。为此,在 onTouchEvent() 中调用的 JNI 函数中调用 glGenTextures()。

问题在于线程 id(gettid() 返回的)似乎完全是任意的,并且并不总是与具有 OpenGL 上下文的线程 id 相同。

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

我可以这样做吗:

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

  • 让 onTouchEvent() 仅在一个具有 OpenGL 上下文的线程中被调用

  • 或任何我可以让它工作的东西

?

谢谢

【问题讨论】:

    标签: android opengl-es android-ndk textures


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • NDK 版本在这方面与 OpenGL 版本相同。
      【解决方案3】:

      我使用 GLSurfaceView.queueEvent() 让它工作。

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

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

      【讨论】:

        【解决方案4】:

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

        它应该与 NDK 非常相似。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-13
          • 2016-09-17
          • 2010-09-18
          • 1970-01-01
          • 2016-09-11
          • 2015-01-03
          • 1970-01-01
          相关资源
          最近更新 更多