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/drawable,res/drawable-ldpi,res/drawable-hdpi,res/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。