Android上gl纹理资源路径的问题


问题描述:

GLSurfaceView中通过纹理绘制图形,纹理长宽为2的幂次(128*64)。资源放在res/drawable文件夹下面。发现在hdpi手机上图形为白色,还有同事手机上是黑色。

 

初步判断:

可能原因是纹理丢失。。导致绘制图形采用默认颜色绘制:白色或者黑色,结果随机。

为什么纹理丢失呢?我直接把问题归咎于奇葩的Android,感觉hdpi手机优先搜索drawable-hdpi文件夹,并没有搜索drawable目录??

 

问题排查:

步骤1:通过图片资源上传gl前,将图片保存到磁盘。结果发现图片确实被搜索到。否定了之前的猜测。

步骤2:图片上传gl时,打log输出图片尺寸。结果惊人地发现hdpi手机上图片大小变为192*96。。看来是因为图片尺寸不是2的幂次导致纹理创建失败。真的有文章。

步骤3:于是我将尺寸为128*64的资源拷贝到res/drawable-hdpi下,再次运行程序。结果发现纹理创建成功,图形绘制正确,输出图像尺寸正确为128*64。

原因定位:为什么前后两种情况图像尺寸会变化呢?计算了一下,恰好长宽相差1.5倍,想起了android的多分辨率规则:3:4:6:8。 正常分辨率手机为1,ldpi手机需要缩小为0.75,hdpi手机需要拉伸到1.5,xhdpi手机需要拉伸到2.0。对Android这个自作多情地隐式操作真无语

 

结论:

正常情况下图片资源需要放在res/drawableres/drawable-ldpires/drawable-hdpires/drawable-xhdpi,且不同分辨率文件夹下都需要放置一份。对于适配gles1.0特意制作的大小为2的幂次的资源,为了防止android隐式缩放,尤其需要在不同分辨率文件夹下放置一份相同的拷贝。然后通过资源加载原始bitmap:

Bitmap mMarkerBmp = BitmapFactory.decodeResource(mapView.getResources(), R.drawable.bus_subway);

对于不希望被拉伸地资源,更好地方式直接放在assets目录下,通过文件方式加载资源:

    protected Bitmap readBitmapFromAssets(String filename) {
        InputStream istr;
        try {
            istr = mapView.getContext().getAssets().open(filename);
        } catch (IOException e) {
            istr = null;
            return null;
        }

        return BitmapFactory.decodeStream(istr);
    }

想到了其他与本文无关的点,1.通过纹理坐标也可以DIY android 的9patch效果;2. png图像是LZW无损压缩算法,难怪android这么提倡使用png。

Ubuntu 13.04 安装 OpenGL

OpenGL三维球体数据生成与绘制【附源码】

Ubuntu下OpenGL编程基础解析

如何在Ubuntu使用eclipse for c++配置OpenGL

《OpenGL超级宝典》学习笔记

相关内容

    暂无相关文章