Android中使用OpenGL ES的一二事

By | 2011/08/22

这个世界,不来点3D感觉都对不起祖宗历代啊,如火如荼的Android上,没有一点3D开发,怎么能说的过去呢?俗气的试了一回……然后发现还真有不少问题,记录一下。

初学者遇到的最大问题,就是贴图在模拟器上跑的好好的,在真机上就是一片片的雪白(如果你的默认渲染色是白色的话),然后崩溃啊吐血啊,调试来调试去,恨不得把手中的破手机摔了再买一个(很容易怀疑到自己的手机上),不过在你这么做之前,先看一下有没有很好的按照下面的要求正确的配置了。

模拟器正常真机贴图丢失里最可能的原因就是图片资源的位置,如果你是使用drawable机制的方法,最好(事实上应该是必须)将图片放到drawable-nodpi文件夹中,这样OpenGL ES才能无障碍的读取到。其他的ldpi, mdpi, hdpi神马的都是浮云……

上面基本就是99%这类问题的原因了,不过我在实际使用中出现了一次别的种类问题,整了个把小时才搞定。说起来可能是我自己写的代码不是那么标准,并没有对每一个贴图进行glTexParameteri设置,不过在模拟器上跑的还是很正常,自己的G2(用的是阿兴2.1的ROM)手机上就不行了,白花花的看得都晃眼。

折寿十年后才发现了这个问题,还是在快要放弃开始洗澡的时候想到的。所以说拼命考虑一个问题没有思路的时候,应该转而做一些其他的事情,没准就有灵感了。不过是模拟器的健壮性比较好么?或者是我手机还不行?后者可能性比较大,因为后面还发现问题……

还有一个要注意的事情,一般OpenGL贴图的(0, 0)是在图片的左下角,而Android中(0, 0)则到了左上角,上下颠倒了一下,我们可以使用Matrix翻转一下:

Matrix matrix = new Matrix();
matrix.setScale (1.0,-1.0);
matrix.postTraslate(0, fHeight);
// 更复杂的矩阵翻转方法已经还给老师了……

不过翻转毕竟是需要CPU时间的,在移植的时候用这个吧,从零开始的话,感觉还是用Android的坐标系统比较好。

另外,在做动态壁纸的时候,发现Android的动态壁纸Service不支持OpenGL,这可真是让我震惊了一下,看到有那么多动态壁纸明显就是用了3D效果(说实话,看到的动态壁纸大多都是“美女”啥的,真是——无趣啊),否则要是用2D模拟出来的话,就太神了。

请教了Google大大以后,原来是有牛人重写了一个GLWallpaperService,就可以在动态壁纸里使用OpenGL ES了,生活在一个牛人辈出的时代真是好啊。这里是链接,好好学习吧~

不过这个东西在我的手机上不是那么好用,设置了动态壁纸之后,只要一锁屏,再开出来就恢复原来的壁纸了。研究来研究去,似乎是ROM不完善的缘故,下一次找一个好用的再试试~

最后,提供一个小脚本,在图像处理的时候,需要把黑色的背景全部变为透明,然后越接近黑色越透明,越亮越不透明,在Photoshop里整了半天搞不定,还是PIL好用啊……(因为我的图片只有红绿两色分量,就用这两个颜色来做Alpha分量,具体情况自己改)

import sys, os
import Image
 
for fn in sys.argv[1:]:
    img = Image.open(fn)
    nimg = Image.new("RGBA", img.size)
    for i in xrange(img.size[0]):
        for j in xrange(img.size[1]):
            rgba = img.getpixel((i,j))
            r = rgba[0]
            g = rgba[1]
            b = rgba[2]
            if r + g + b == 0:
                a = 0
            else:
                a = int(1.5 * (r /2 + g / 2 ))
            nimg.putpixel((i, j), (r, g, b, r/2 + g/2))
 
    nfn = os.path.join(os.path.dirname(fn), "out_" + os.path.basename(fn))
    nimg.save(nfn)

哦,最后付一个超棒的Android的OpenGL ES入门教程

发表评论

您的电子邮箱地址不会被公开。