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 offset)调用的函数现在我的 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 查看“映射 PBO”部分。

于 2015-05-26T08:04:42.433 回答