AndroidのOpenGLテクスチャでハマる
AndroidでOpenGLアプリを作っていたところ、glTexImage2DがGL_INVALID_VALUE (1281) というエラーになって動かない。よくよく調べると、テクスチャの寸法が768x768と、2のベキじゃない値になっている。元のPNGファイルは間違いなく512x512なのに。誰かが勝手に画像を拡大している!?
と、ここまで気づくのに2日間。
このテクスチャは、PNGをres/drawableに置いておき、BitmapFactory.decodeResource(Resources,int)で読み込んでいたのだが、このメソッドが勝手に拡大しているとしか思えない。
decodeResourceメソッドには、引数を3個取るバージョンがあって、第3引数にはBitmapFactory.Optionsというものを渡す。この説明をよーく読むと、Options.inScaledというパラメタがあって「ビットマップを読み込むときにターゲットの解像度に合わせてスケールする。デフォトはオンなので、ビットマップをスケールしないで読み込みたい場合はオフにしなさい。」みたいなことが書いてありました。それで、引数が2個の場合は、Optionsはすべてデフォルトとみなされる、と。
そこまでわかって改めて調べると、テストに使っていたデバイスのDisplayMetrics.densityは1.5だった。なるほどね。
つまり、こうすればよかったのだ。
BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = false; Bitmap texture = BitmapFactory.decodeResource(res, R.drawable.texture, options); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);
わかってしまえばどうということは無いのだが、ウェブで検索してもこのポイントの説明を見かけない。こんなことでハマるのは私だけなのかな?
追記
「わかってしまえば」と偉そうなことを書きましたが、実はまだわかっていませんでした。
res/drawable-nodpi というフォルダを作って、そこにファイルを置けば、BitmapFactory.Optionsなんていうものを持ち出さなくてもそのまま読み込めました。
つまり、Androidでのビットマップファイルの置き場というのは、
- res/drawable
- デバイス解像度に応じて適当に拡大縮小されたものを読み込む
- res/drawable-{l,m,h,xh}dpi
- デバイス解像度に応じたフォルダが選ばれ、画像自体は拡大縮小されない
- res/drawable-nodpi
- デバイス解像度によらず、拡大縮小されずに読み込まれる
という規約なのでしたよ。
…ということが、まとめて書いてあるドキュメントが存在しないのが、また、なんというか、アレだ。
« kyoto-client | トップページ | android.opengl.GLSurfaceView.Renderer »
« kyoto-client | トップページ | android.opengl.GLSurfaceView.Renderer »


コメント