转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2229

从Android SDK R17开始,模拟器就支持OpenGL ES 2。如果能让KlayGE在模拟器上跑起来,开发和测试就能方便许多。于是我装了最新的R21和Android 2.1的ARM v7a的镜像,经过几个小时的努力,终于成功执行了一些原来能在Android x86 2.3上跑的简单例子。途中发现了一些小陷阱,这里总结一下。

屏幕宽高

原先我的做法是通过ANativeWindow_lock获得buffer,再拿buffer的width和height。在ICS上,这么做会导致后面eglCreateWindowSurface失败。原因似乎是ANativeWindow_lock之后这个窗口就被连到2D API,那么在eglCreateWindowSurface的时候就会说那个窗口已经被别的API连接了。即便是ANativeWindow_unlockAndPost也没用。解决方法是改成用ANativeWindow_getWidth和ANativeWindow_getHeight。原先这两个函数总返回0,现在似乎好了,其实用起来更方便。

glDeleteShader

原先我的习惯都是在glAttachShader之后就立刻调用glDeleteShader,因为GLES的文档中有一句话:

If a shader object to be deleted is attached to a program object, it will be flagged for deletion, but it will not be deleted until it is no longer attached to any program object…

但模拟器的实现似乎没遵守这点。如果delete了,后面的glGetAttribLocation都会返回-1,所有attrib都不存在了。所以也得去掉glDeleteShader。

缺少wchar_t的完整支持

这是一直存在的问题。 Bonic 2.3对wchar_t的系列函数也没做到完整支持。最恶心的是mbstowcs和wcstombs,内部只是memcpy了一下,根本没有转码。。。原先一直用Crystax的NDK,没这个问题,转回官方的NDK以后直接悲剧了。