私は、特に Android で OpenGL を使用するための非常に基本的な知識を持っています。フルスクリーン画像を高速に切り替えるために OpenGL を使用するアプリを開発しています (通常の Android フレームワークでは遅すぎるため)。
私が見つけたのは、テクスチャをロードするには、次のようなことをする必要があるということです:
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
_gl = gl;
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), _imageResourceId);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
ここで、画像はフルスクリーンであることが意図されているため (1024x1024 と非常に大きい)、特に 5 つの画像を同時にロードする必要があるため、これには時間がかかります。
そのため、コードを改善するためのヒント、特に効率的な読み込み (ただし、可能であればメモリの使用量を減らすこと) についていくつか質問する必要があります。
RGB_565 形式を使用して透明ピクセルを持たないようにビットマップをデコードすると、イメージを OpenGL にロードする速度 (またはデコード フェーズ) が向上しますか?
入力ビットマップの幅と高さは 2 のべき乗である必要がありますか、それとも OpenGL に必要な部分だけを持たせることができますか?これにはこのルールがありますか?
texImage2D
つまり、ビットマップの一部だけを取得するコマンドを作成できますか?たぶん、最初からこの部分だけをデコードすることもできます(したがって、10000x10000の巨大な画像がある場合、その1024x1024部分だけをデコードしてOpenGLに渡すことができます)?
最初の画像だけをロードして表示し、バックグラウンドで残りをロードすることは可能ですか? ビットマップを処理するスレッド以外のスレッドでは、ビットマップを OpenGL に送信できないと聞いたことがあります。
onDrawFrame
のメソッドにGlRenderer
、たとえば 2 回目に呼び出されたときにそれらをロードするのは理にかなっていますか?複数の画像を 1 つの画像に (左から右に次々と) マージすると、デコード フェーズの速度が向上する可能性があるというヒントを聞いたことがあります。このテクニックの名前はわかりません。Android で OpenGL ES を使用することはまだ可能ですか?
Bitmap インスタンスの作成を回避し、よりネイティブな方法 (おそらく NDK ) でデコードを行うことは可能ですか? 私のテストによると、エミュレーターでサイズ 1024x1024 の PNG ファイルをデコードするには約 400ms ~ 700ms かかりますが、OpenGL に送信するには約 50ms ~ 70ms かかります。
Procrank を使用して、OpenGL が大量のメモリを消費する可能性があることを発見しました。使用するメモリを少なくすることは可能ですか? たぶん、より良いテクスチャタイプを使用しますか?
Android は多くの種類のデバイスで動作するため、メモリが少なすぎる人がアプリをインストールできないように、アプリの実行に必要なメモリ量の要件をマニフェストに入れることは可能ですか?
@マジッドマックス:
このようにデコードしてOpenGLに送信するだけで十分ですか、それともopenGLに送信するときに特別なものを設定する必要がありますか?
ビットマップの一部を取得するコマンドはありませんか?
つまり、ビットマップ全体ではなく、ファイルの一部のみをデコードしてビットマップに格納することはできますか?
私ができる唯一のことは、最初にすべてをロードしてから、すべてを使用することですか? どうしてですか?ゲームはそれをどのように処理しますか? つまり、OpenGL で生成されたプログレス バーのように見えても、ステージが次々と表示されます。これは非常に問題です。
私が説明していることは、ウェブでも入手できます。たとえば、複数の小さな画像を読み込む代わりに、Web ページには 1 つの画像が含まれ、そのどの部分をどこに表示するかをマップします。別名はスプライトです。例はこちら。
分かりました。もう使用されていないことがわかったら、glDeleteTextures も呼び出す必要があると思いますよね?
それ、どうやったら出来るの?コードの何を変更すればよいですか?
大量のメモリを使用するとどうなりますか? 空きRAMがない場合、仮想RAM(おそらく内部ストレージを使用)のようなものはありますか?Google IO ビデオで聞いたことがありますが、彼らもその答えについて確信が持てなかったようです。ここにリンクします。彼らは、そのようなことが起こったとき、より多くのクラッシュが予想されるとだけ言った.
@マジッドマックス:
1+2+3。?
これはうまくいくかもしれません。ビットマップをロードする新しいスレッドを作成し、テクスチャをビットマップにバインドする OpenGL スレッドに結果を送り返すということですか? おそらく、asyncTask に同様のアプローチを使用して、publishprogress を使用できます。
それも良いことです。それについて読むべきリンクはありますか?または、私のコードで変更するスニペットですか?
ありがとう。
なのでETC1が一番使いやすいと思います。ただし、透明度はまったくサポートされていないため、このリンクによると、そのためだけに別のテクスチャを使用する必要がありますが、これのサンプルが見つかりません。
使用できる使用可能なメモリについて何を想定できますか? たとえば、すべての Android デバイスが、OpenGL に使用できる 200MB のビデオ メモリを提供できると仮定できますか?