Android OpenGL ES 3.0 PBO而不是glReadPixels() [英] Android OpenGL ES 3.0 PBO instead of glReadPixels()

查看:632
本文介绍了Android OpenGL ES 3.0 PBO而不是glReadPixels()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用PBO(对于GLES 3设备)提高glReadPixels()性能,并且在这段代码中遇到了问题:

I want to improve glReadPixels() performance using PBO (for GLES 3 devices) and I ran into a problem in this piece of code:

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()方法.我发现这个 ,但是我无法发送零,因为它需要一个IntBuffer争论.非常感谢您对此问题的建议

At the moment it fails glReadPixels() method. I found this & this, but I'm unable to send a zero because it takes an IntBuffer argument. I would very appreciate any suggestions about the issue

更新:似乎不可能仅将Java API用于该任务.因此,我已经使用ndk添加了一个函数,该函数使用正确的最后一个参数(int offset)调用glReadPixels() 现在,我的所有GL调用都不会产生错误.

UPDATE: It seems to be impossible to only use Java API for that task. So I've used ndk to add a function that calls glReadPixels() with correct last argument(int offset) Now none of my GL calls produce an error.

那是我的jni c代码:

That's my jni c code:

#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);
}

现在的问题是,与没有PBO相比,glReadPixels()调用花费的时间甚至更多,因此还没有性能提升.我将探究为什么会发生这种情况,并在发现某些内容时进行更新.

Now problem is that glReadPixels() call takes even more time than without PBOs so there's no performance gain yet. I'm going to explore why that happens and update when I find something.

更新2 我忘了更早地更新它,但是实际上问题是我使用的是pbuffer表面,这就是为什么我没有性能提升的原因.我比较了该选项和不使用pbuffer表面的选项,并且性能提升很大.

UPDATE 2 I forgot to update it earlier, but in fact the problem was that I was using pbuffer surface that's why I had no performance gain. I compared that option and option of not using pbuffer surface and performance gain was huge.

因此,如果在屏幕外渲染并使用glReadPixels,则值得使用pbuffer表面

So in case rendering offscreen and using glReadPixels it's worth using pbuffer surface

推荐答案

在glReadPixels总是会降低性能之后立即映射PBO缓冲区.当您请求映射时,GPU仍在工作.因此,glMapBufferRange等待gpu完成向PBO读取像素.如果您在glReadPixels之后继续渲染,并且将在某些帧后进行映射,那么您将获得性能提升.

Mapping PBO buffer right after glReadPixels always kills performance. GPU is still working when you requested the mapping. Hence, glMapBufferRange waits gpu to complete reading pixels to the PBO. If you continue rendering after glReadPixels and will do the mapping after some frames then you will get performance gain.

此处的更多信息: http://www.songho.ca/opengl/gl_pbo.html 请查看映射PBO"部分.

More information here: http://www.songho.ca/opengl/gl_pbo.html Look "Mapping PBO" section.

这篇关于Android OpenGL ES 3.0 PBO而不是glReadPixels()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆