eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

Galaxy NexusでETC1テクスチャを利用する場合の注意

ETC1とGalaxy Nexus

AndroidOpenGL ES実装はETC1をサポートするようになっています。

ETC1テクスチャは4x4のピクセルブロックを基本とした圧縮を行うため、利用するには次のような制限があります。

  • 縦横のピクセル数が4の倍数であること
    • そのため、Android SDK付属のetc1toolを利用すると4で割り切れるように画像末尾に詰め物を入れられる
  • GL_OES_compressed_ETC1_RGB8_textureエクステンション対応のGPUであること

この制限に従っていれば、Power Of Two(2のn乗)である必要はありません。

Galaxy NexusのGPUはスペック上はnpot(Non Power Of Two = 2のn乗以外)テクスチャも扱えますし、ETC1もサポートしています。

f:id:eaglesakura:20130317155132j:plain

f:id:eaglesakura:20130317155228j:plain

当然、次のコマンドも正常に行えますし、assertも通過します。

glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, image_bytes, image);
assert(glGetError() == GL_NO_ERROR);

その状態でテクスチャをbindしてレンダリングすると、問答無用でアプリが落ちます。OpenGLは基本的にエラーが発生したらエラーをセットするだけのため、異常な動作だと思われます。

解決方法としては「npotのETC1を使わない」という点ですが、でっかい背景画像とかnpotのETC1を使いたい場所はそこそこあるので、他の端末で同様の不具合が起きないことを祈るのみです。

その他

回避方法、もしくは「ここが間違ってる」という指摘があったらコメントお願いしますm(__)m

初めてのOpenGL ES

初めてのOpenGL ES

Android NDKで"Unknown Application ABI:" エラーが発生した場合の対症療法

Android NDKのデバッグは容易になった・・・はずなのに

Androidアプリは基本的にSDKを利用し、Java言語で記述します。ですが、Android NDKを利用することでC/C++言語でもアプリを記述できるのは周知のとおりです。

最初は「できるやつだけついてこい」的にほとんど整備されていなかったNDKの開発環境ですが、最近ではEclipseとの連携が可能になり、更にはコマンドラインベースだったデバッグEclipseを使ってGUI上でできるようになっています。

  1. Add Native Supportを設定する f:id:eaglesakura:20130317220540j:plain
  2. Debug As -> Native Application f:id:eaglesakura:20130317220640j:plain
  3. エディタ上でブレークポイントを設定 f:id:eaglesakura:20130317220728p:plain
  4. あとはステップ実行なり変数のウォッチなりが簡単にできる f:id:eaglesakura:20130317220755p:plain

そのおかげで、あんどろいどたん(Google Play)を始めとして最近の案件はAndroid NDKを多く利用していたわけですが、唐突に次のようなコンソールに出力されるようになり、デバッガが接続できなくなりました。

[2013-03-17 21:36:50 - アプリ名] Unknown Application ABI: 
[2013-03-17 21:36:50 - アプリ名] 
[2013-03-17 21:36:50 - アプリ名] Unable to detect application ABI's

対症療法

しばらくの間は「アルェ〜、ナンデナンデ!?」状態で仕方なくprintfデバッグをしてたわけですが、次の条件でデバッガが接続できることがわかりました。

無駄だったこと

  • 端末再起動
  • ndk-build -clean
  • キャッシュ的なファイルを全て削除
  • Eclipseを通常再起動
  • Eclipseの再インストール(再設定)
  • Eclipseの英語版を利用

効果的だったこと

  • eclipse -clean で起動する
    • ただしclean起動後も、通常起動したらまたデバッグできなくなる
    • つまりはデバッグしたくなる度にclean起動が必要

ですが、boost等の重いライブラリを利用していると、clean起動する度にインデクサーがガリガリと幾千のファイルをチェックしてしまうため、ストレスがマッハです。

デバッガが接続できるアプリ・できないアプリがあった

つい最近わかったことは、同一のEclipse環境・端末環境でもデバッグできるあぷり・できないアプリがあるということです。
チェックしてみると、比較的規模の大きな案件でビルドしたアプリは接続できず、小さいアプリは接続できるということでした。

原因

いろいろ調べた結果、(今のところ)理由は次の一点でした。

  • Android.mk/Application.mkで自分で作ったファイル(共通のmkファイル等)をincludeするとデバッガが接続できない
  • どちらか(もしくは両方)にincludeがあるとエラーが発生する
  • include先に書いてある内容をコピペして、includeしないようにすればおk
# ダメなApplication.mk

APP_MODULES := sample
include shared_application.mk

------
# shared_application.mkの中身

APP_STL:=gnustl_static
APP_ABI := armeabi-v7a
# 問題ないApplication.mk

APP_MODULES := sample
# コピペして持ってくれば大丈夫
APP_STL:=gnustl_static
APP_ABI := armeabi-v7a

反省

「本来includeは使わねーよwwww」とか、私が知らないだけでmakefileのルールに則ってないのかもしれませんが、共通部分をどっかにまとめとこう的なことはしばらく考えないほうがよさそうです。