2012-01-06 38 views
2

我想在Android ICS上制作基于NDK的游戏。它在Honeycomb和姜饼上效果很好。eglCreateWindowSurface在ICS上,并从2D切换到3D

游戏使用一些2D渲染,一些3D渲染,在执行的各个阶段在两者之间切换。 (由于第三方代码,这是不可协商的。)我们对于2D渲染使用ANativeWindow_lock()/ANativeWindow_unlockAndPost(),对于3D渲染我们使用eglCreateWindowSurface()/gl*()/eglSwapBuffers()

对蜂窝和姜饼这一切工作正常。在ICS,eglCreateWindowSurface()失败,并在日志中以下消息:

E/SurfaceTexture(1765): [com.fnord/com.fnord.MyActivity] connect: already connected (cur=2, req=1) 
E/libEGL (5466): EGLNativeWindowType 0x29e9b8 already connected to another API 
E/libEGL (5466): eglCreateWindowSurface:374 error 300b (EGL_BAD_NATIVE_WINDOW) 
E/libEGL (5466): call to OpenGL ES API with no current context (logged once per thread) 

看着似乎很明显,eglCreateWindowSurface()失败,因为东西的有开放的2D渲染的本地窗口的源代码,它不会让我将其更改为3D而不以某种方式首先释放表面。然而,ANativeWindow API似乎没有任何明显的方法来做到这一点。

有没有其他人遇到过这种情况,有什么解决办法?

更新

所以我已经重写我的2D渲染代码使用OpenGL原语,而不是(上传后备缓冲到纹理,通过一对三角形,swapbuffers渲染纹理)。这工作到一定程度。 现在发生什么事是2D渲染工作正常;然后我摧毁表面,为3D渲染做好准备,第二次调用eglCreateWindowSurface()失败。这一次,有:

E/SurfaceTexture(1869): [com.fnord/com.fnord.MyActivity] connect: already connected (cur=1, req=1) 

...它抛出的AEGL_BAD_NATIVE_WINDOW的EGL错误。

请注意,新表面的创建与的创建完全相同,属性与原来的完全相同。我甚至试图确保在拨打eglCreateWindowSurface()的两个电话之间拨打eglTerminate()/eglInitialize()

这种情况下,我可以精确地使用每个ANativeWindow一次吗?如果是这样,这是否会导致Khronos的EGL一致性测试失败?有没有办法让NativeActivity重新创建窗口呢?

更新更新

原来那最后的问题是由我没有破坏环境和表面之前调用eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)造成的。这导致破坏被延迟,直到线程解开上下文和表面(当然不是这样),从而导致eglCreateWindowSurface()的调用合法失败(在同一本机窗口中不能有两个窗口表面)。

这是一个 bit违反直觉,因为人们会认为调用eglTerminate()会销毁所有EGL资源,但规格允许。被警告!

回答

1

这不是支持的用例。它以前的工作对你来说只是运气,在某些设备上可能会失败。您可以通过在另一个窗口中渲染2D或3D内容来解决这个问题,或者在用作GL纹理的位图中渲染2D内容等。

+0

您是否有链接供参考?即什么功能被保证支持? – 2012-01-06 19:40:13

+0

我重写了我的代码,通过OpenGL进行2D渲染 - 但它仍然无法工作。详细的身体。感谢您的建议... – 2012-01-09 16:33:08

+0

您能否显示您的代码?销毁/重新创建窗口表面正是硬件渲染器经常做的事情。你为什么摧毁你的表面btw? – 2012-01-09 19:20:35

0

您可以从OpenGL图像切换到CPU渲染(ANativeWindow_lock),反之亦然,但你需要释放使用SurfaceSurface.release()并创建你的SurfaceTexture为其他API一个新的。

Example app