AndroidでのOpenGLES関係の質問

2,176 views
Skip to first unread message

まいむぞう

unread,
Aug 8, 2009, 3:59:23 AM8/8/09
to android-...@googlegroups.com
まいむぞうです。

OpenGLを使って遊んでおります。

主にOpenGLプログラミングガイド(赤本)を使って勉強しているところなんですが、
AndroidというかJava的なところや、OpenGLの内部構造の理解不足が原因で詰まっている状況です。
どなたかアドバイスいただけますでしょうか?

1) GL10.glTexImage2D()したときのメモリの扱い
例えば、Bitmapを作ってGLUtils.texImage2D()したときや、RGBA画像のByteBufferをGL10.glTexImage2D()したときなど、
メモリ有効利用のためすぐにBitmapやByteBufferを解放して良いのか、
それともテクスチャを使い終わるまで確保し続けなければならないのかは、どちらなのでしょう?

GLUtils.texImage2D()の場合はネイティブ内でARGBからRGBAに変換しているでしょうから、すぐ解放してもよさそうですが、
GL10.glTexImage2D()の場合はポインタを渡しているだけかも?と思ったので。


2) マルチスレッド下でのGL10.glBindTexture()
テクスチャをロードするときと、ロードしたテクスチャを描画するときにGL10.glBindTexture()を呼ぶ必要があると思いますが、
ネットワーク越しに画像を持ってくるような場合、マルチスレッドを使ってテクスチャを更新した方が楽かなぁと思います。

この場合、描画用ループのrenderスレッドと、画像取得・ロード用スレッドでそれぞれGL10.glBindTexture()すると、
干渉してしまうという理解で良いでしょうか?
取得した画像をキューに貯めてrenderスレッドでGLUtils.texImage2D()すると、その瞬間カクカクするかなぁと思ったのですが、どうでしょう?


--
------------------------------------------------------------------------------------------------------
大路裕介(おおみちゆうすけ)/まいむぞう
mail: mai...@gmail.com
skype: maimuzo
twitter: maimuzo
blog: http://fromnorth.blogspot.com/
service for rubyist: http://gemspec.info
for Android users: http://www.android-app.info/
------------------------------------------------------------------------------------------------------

Yukio Andoh

unread,
Aug 9, 2009, 11:05:02 PM8/9/09
to Android-SDK-Japan
まいむぞうさん、はじめまして。
安藤幸央と申します。

OpenGL 関連;

A1) GL10.glTexImage2D()したときのメモリの扱い

glTexImage2D() で指定したテクスチャ画像バッファは
glTexImage2D() の後、解放してもかまいません。
glTexImage2D() は本体メモリやファイルのバッファを指定して、
グラフィックスハードウェアのテクスチャのメモリへ送り込む命令です。

glTexImage2D() でグラフィックスハードウェア側に送り込んだ方の
テクスチャを明示的に解放したいとき(再利用しないことが明確な時)は
glDeleteTextures() で解放することができます。

(姑息なテクニックとしてはテクスチャを生成したらすぐに
 画面の見えないところに一度ダミー描画すると、
 ハードウェア全体のメモリ効率が良くなります)

A2) マルチスレッド下でのGL10.glBindTexture()

 OpenGL は関数によって様々な情報を定義する際、
 一つの流れしかありませんので「干渉してしまう」という理解で正しいです。
 異なるスレッド上で実行される glTexImage2D と glBindTexture が実行される
 タイミングによっては見かけ上、うまく動くような場合もあります。

--------
このあたり、OpenGL ES の技術情報や、テクニック、はまりどころ、
グラフィックスハードウェアの構造や仕組みなど、基本的なところを含め、何かの機会に
まとめてセミナーできたり、本にしたりできるといいな~とは思っているのですが.....

// Yukio Andoh * EXA Corporation






On 8月8日, 午後4:59, まいむぞう <maim...@gmail.com> wrote:
> まいむぞうです。
>
> OpenGLを使って遊んでおります。
>
> 主にOpenGLプログラミングガイド(赤本)を使って勉強しているところなんですが、
> AndroidというかJava的なところや、OpenGLの内部構造の理解不足が原因で詰まっている状況です。
> どなたかアドバイスいただけますでしょうか?
>
> 1) GL10.glTexImage2D()したときのメモリの扱い
> 例えば、Bitmapを作ってGLUtils.texImage2D()したときや、RGBA画像のByteBufferをGL10.glTexImage2D ()したときなど、
> メモリ有効利用のためすぐにBitmapやByteBufferを解放して良いのか、
> それともテクスチャを使い終わるまで確保し続けなければならないのかは、どちらなのでしょう?
>
> GLUtils.texImage2D()の場合はネイティブ内でARGBからRGBAに変換しているでしょうから、すぐ解放してもよさそうですが、
> GL10.glTexImage2D()の場合はポインタを渡しているだけかも?と思ったので。
>
> 2) マルチスレッド下でのGL10.glBindTexture()
> テクスチャをロードするときと、ロードしたテクスチャを描画するときにGL10.glBindTexture()を呼ぶ必要があると思いますが、
> ネットワーク越しに画像を持ってくるような場合、マルチスレッドを使ってテクスチャを更新した方が楽かなぁと思います。
>
> この場合、描画用ループのrenderスレッドと、画像取得・ロード用スレッドでそれぞれGL10.glBindTexture()すると、
> 干渉してしまうという理解で良いでしょうか?
> 取得した画像をキューに貯めてrenderスレッドでGLUtils.texImage2D()すると、その瞬間カクカクするかなぁと思ったのですが、どうでし ょう?
>
> --
> --------------------------------------------------------------------------- ---------------------------
> 大路裕介(おおみちゆうすけ)/まいむぞう
> mail: maim...@gmail.com

まいむぞう

unread,
Aug 10, 2009, 10:29:39 PM8/10/09
to android-...@googlegroups.com
まいむぞうです。

安藤さん、お返事ありがとうございます。

> A1) GL10.glTexImage2D()したときのメモリの扱い
> glTexImage2D() で指定したテクスチャ画像バッファは
> glTexImage2D() の後、解放してもかまいません。

おぉなるほど。
やはりそうなんですね。

> (姑息なテクニックとしてはテクスチャを生成したらすぐに
> 画面の見えないところに一度ダミー描画すると、
> ハードウェア全体のメモリ効率が良くなります)

これは、常駐テクスチャとなることでキャッシュが使えるから、ということでしょうか?

> A2) マルチスレッド下でのGL10.glBindTexture()
> OpenGL は関数によって様々な情報を定義する際、
> 一つの流れしかありませんので「干渉してしまう」という理解で正しいです。

こちらも、OpenGLのステートは1つだけ、ということですね。

GLSurfaceViewなどを使う場合で、別スレッドを使って画像などを取り込みたい場合は、
別スレッドで画像を取ってきて、どこか可視性を確保した場所に画像を置いておいて、
GLスレッド側のキューにアップデート用の処理を積んでおく感じでしょうか。


これに限らず、OpenGLは内部構造がどうなっているのか理解しないと取っ付きづらい感がありますね。
赤本などを熟読すれば理解できるんだと思うのですが、さすがに内容が濃くて
一読して済ませている事が多いです。

概念図などがわかりやすくまとまっているような資料があればいいんだけど。。。

この他に

Q3) SurfaceとSurfaceHolderとGL10などのインスタンスの関係

オライリーさんの「初めてのAndroid」でさらっと解説があるのですが、
いまいち感覚が掴めていません。このへんがキモだと思うのですが。。。

Surface ~ OpenGL ESで描画を行ったときに最終的な画像が入るGPU上のフレームバッファのこと?
SurfaceHolder ~ 実際にSurfaceHolderで保持している情報ってなに?
GL10などのインスタンス ~ GPU上のフレームバッファが壊れるから、その上で動いていたGL10などのインスタンスも壊れる、ってこと?

# そもそも自分の知識はPC9801のVRAMあたりで止まっているので、GPUが載ったときの動作を理解してないのが
# 最大の要因な気がしますorz
# GPU上のフレームバッファは、その時ディスプレイに見えている画像と同一と思っていいんでしょうか?

Activityのライフサイクル上から見た時、SurfaceとSurfaceHolderとGL10などのインスタンスがそれぞれ
どう動いているのかが理解できていないのが原因だと思うのですが、何か参考になる資料はありますでしょうか?


Q4) GL10のインスタンスの同一性

GLSurfaceViewではGL10のインスタンスは、描画ごとに渡されたインスタンスを使うような設計になっていますが、これはなぜでしょう?
別のActivityがフォアグラウンドになったときなどに、Surfaceと連動してGL10のインスタンスが壊れるから、
GLSurfaceViewが再度フォアグラウンドになったときに、GL10のインスタンスが再生成されるため、という理解で良いでしょうか?

この、再生生成されたGL10のインスタンスには、以前に登録されたテクスチャや各種パラメータは残っているんでしょうか?

たまにRendererのonDrawFrame()以外のタイミング(描画以外のタイミング)で
GL10のインスタンスを使いたいな(OpenGLに触りたいな)と思う時があるのですが、
onSurfaceCreated()などで渡ってきたGL10のインスタンスを保存しておくのではなく、
やはりこれはonDrawFrame()のタイミングまでぐっと我慢するべきなんでしょうか。


Q5) OpenGL ES関連処理の後片付けや、Activityライフサイクルとの連動

たとえばゲームなどでメニュー用Activityと、OpenGL ESを使うゲーム本体Activityが別になっている場合、
ゲームをやめてメニューに戻ってきた場合などに、OpenGL ES関連の後片付けは必要でしょうか?
(正確には後片付けが必要かどうかはそのアプリによるのでしょうが)

ゲーム本体Activityが完全に破棄された場合(onDestroy後)は自動的に後片付けされてしまうと思うのですが、
GLSurfaceViewなどを見ると、あまり後片付けの事は考慮されていないように見えます。
必要な人はonPause()やonResume()をうまくハンドリングしてキューに入れなさい、ということなんでしょうか。
(この場合でも、GLThreadのキューからはGL10のインスタンスを取れないので、やりたい事ができない事が多いような)


> このあたり、OpenGL ES の技術情報や、テクニック、はまりどころ、
> グラフィックスハードウェアの構造や仕組みなど、基本的なところを含め、何かの機会に
> まとめてセミナーできたり、本にしたりできるといいな~とは思っているのですが.....

これ、すごく欲しいです!!
Android関係のプログラミングの本は全部買ってるんですが、今の所OpenGL関係は扱ってなかったり、
扱っていてもページ数が少なくて初歩的な所までといった感じの本が多いので、
「AndroidでのOpenGL ES」という切り口の資料があると、とても助かります。
(NDK使ってネイティブで描画というのも、やっている人いるんでしょうか?)


------------------------------------------------------------------------------------------------------
大路裕介(おおみちゆうすけ)/まいむぞう
mail: mai...@gmail.com
skype: maimuzo
twitter: maimuzo
blog: http://fromnorth.blogspot.com/
service for rubyist: http://gemspec.info
for Android users: http://www.android-app.info/
------------------------------------------------------------------------------------------------------

2009/8/10 Yukio Andoh <yukio...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages