4

glReadPixels()PBO (GLES 3 デバイス用) を使用してパフォーマンスを向上させたいのですが、次のコードで問題が発生しました。

final ByteBuffer pboByteBuffer = ByteBuffer.allocateDirect(4 * mWidth * mHeight);
pboByteBuffer.order(ByteOrder.nativeOrder());

//set framebuffer to read from
GLES30.glReadBuffer(GLES30.GL_BACK);

// bind pbo
GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, mPboHandleContainer[0]);

// read pixels(should be instant)
GLES30.glReadPixels(0, 0, mWidth, mHeight, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, pboByteBuffer);

// map pbo to bb
ByteBuffer byteBuffer =
        ((ByteBuffer) GLES30.glMapBufferRange(GLES30.GL_PIXEL_PACK_BUFFER, 0, 4 * mWidth * mHeight,
                                              GLES30.GL_MAP_READ_BIT)).order(ByteOrder.nativeOrder());

// unmap pbo
GLES30.glUnmapBuffer(GLES30.GL_PIXEL_PACK_BUFFER);

// unbind pbo
GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, 0);

現時点では、glReadPixels()メソッドは失敗します。this & thisを見つけましたが、IntBuffer 引数を取るため、ゼロを送信できません。この問題に関する提案をいただければ幸いです

更新:そのタスクに Java API のみを使用することは不可能のようです。そのため、ndk を使用してglReadPixels()、正しい最後の引数 (int オフセット) で呼び出す関数を追加しました。現在、GL 呼び出しでエラーが発生することはありません。

それが私のjni cコードです:

#include <jni.h>

#include <GLES3/gl3.h>

#ifdef __cplusplus
extern "C" {
    JNIEXPORT void JNICALL Java_somepackage_GLES3PBOReadPixelsFix_glReadPixelsPBO(JNIEnv * env, jobject obj, jint x, jint y, jint width, jint height, jint format, jint type, jint offsetPBO);
};
#endif

JNIEXPORT void JNICALL Java_somepackage_GLES3PBOReadPixelsFix_glReadPixelsPBO(JNIEnv * env, jobject obj, jint x, jint y, jint width, jint height, jint format, jint type, jint offsetPBO)
{
    glReadPixels(x, y, width, height, format, type, offsetPBO);
}

ここでの問題は、glReadPixels()PBO がない場合よりも呼び出しにさらに時間がかかるため、パフォーマンスの向上がまだないことです。なぜそうなったのかを調べて、何か見つけたら更新します。

更新 2 以前に更新するのを忘れていましたが、実際には pbuffer サーフェスを使用していたため、パフォーマンスが向上しなかったことが問題でした。そのオプションと、pbuffer サーフェスを使用しないオプションを比較したところ、パフォーマンスが大幅に向上しました。

したがって、オフスクリーンでレンダリングして glReadPixels を使用する場合は、pbuffer サーフェスを使用する価値があります

4

1 に答える 1

2

glReadPixels の直後に PBO バッファをマッピングすると、常にパフォーマンスが低下します。マッピングを要求したとき、GPU はまだ動作しています。したがって、glMapBufferRange は gpu が PBO へのピクセルの読み取りを完了するのを待ちます。glReadPixels の後にレンダリングを続け、いくつかのフレームの後にマッピングを行うと、パフォーマンスが向上します。

詳細はこちら: http://www.songho.ca/opengl/gl_pbo.html 「Mapping PBO」セクションを参照してください。

于 2015-05-26T08:04:42.433 に答える