私は、EGL コンテキストの損失と再作成の間にフレームバッファー オブジェクトのカラー バッファーをキャッシュして再描画するための Android コードに取り組んでいます。開発は、主に Honeycomm を実行している Xoom タブレットで行われています。とにかく、私がやろうとしているのは、FBO で glReadPixels() を呼び出した結果を直接 ByteBuffer に格納し、そのバッファを glTexImage2D() で使用して、(現在クリアされている) フレームバッファに戻すことです。これはすべて正常に動作しているようです — ByteBuffer には正しい値 (Java が符号なしバイトを理解できないため、ピクセルの [-1, 0, 0, -1] など) が含まれており、GlErrors はスローされていないようです。クワッドは画面の右側に描画されます (現在、テスト目的でフレーム バッファーの左上の 4 分の 1 です)。
ただし、何を試しても、 glTexImage2D() は常にプレーンな黒いテクスチャを出力します。私は以前にこれに関していくつかの問題を抱えていました — ビットマップを表示するとき、私は最終的にバッファで基本的な GLES20.glTexImage2D() を使用しようとすることをあきらめ、ビットマップを処理する GLUtils.glTexImage2D() を使用することにスキップしました。残念ながら、それはここでは選択肢が少ないため (実際に ByteBuffer を Bitmap に変換して、GLUtils を使用できるようにしましたが、あまり成功しませんでした)、本当にアイデアが尽きてしまいました。
glTexImage2D() が完全に良好な ByteBuffer を正しく処理しない原因となる可能性のあるものを誰か考えられますか? あらゆる提案を歓迎します。
ByteBuffer pixelBuffer;
void storePixels() {
try {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbuf);
pixelBuffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.nativeOrder());
GLES20.glReadPixels(0, 0, width, height, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, pixelBuffer);
GLES20.glBindFrameBuffer(GLES20.GL_FRAMEBUFFER, 0);
gfx.checkGlError("store Pixels");
}catch (OutOfMemoryError e) {
pixelBuffer = null;
}
}
void redrawPixels() {
GLES20.glBindFramebuffer(GL20.GL_FRAMEBUFFER, fbuf);
int[] texId = new int[1];
GLES20.glGenTextures(1, texId, 0);
int bufferTex = texId[0];
GLES20.glBindTexture(GL20.GL_TEXTURE_2D, bufferTex);
GLES20.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_LINEAR);
GLES20.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_LINEAR);
GLES20.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S, repeatX ? GL20.GL_REPEAT
: GL20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T, repeatY ? GL20.GL_REPEAT
: GL20.GL_CLAMP_TO_EDGE);
GLES20.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGBA, width, height, 0, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, pixelBuffer);
gfx.drawTexture(bufferTex, width, height, Transform.IDENTITY, width/2, height/2, false, false, 1);
GLES20.glDeleteTextures(1, IntBuffer.wrap(new int[] {bufferTex}));
pixelBuffer = null;
GLES20.glBindFrameBuffer(GLES20.GL_FRAMEBUFFER, 0);
}
ちなみに、gfx.drawTexture() はクワッドを構築し、現在バインドされているフレームバッファに描画します。このコードは、私のプロジェクトの他の部分で十分にテストされています。ここでは問題になりません。