我正在使用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的线程中被调用
或任何我能使其发挥作用的事情
由于
答案 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非常相似。