Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/181.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android OpenGL ES 3.0 PBO代替glReadPixels()_Android_Glreadpixels_Opengl Es 3.0_Pbo - Fatal编程技术网

Android OpenGL ES 3.0 PBO代替glReadPixels()

Android OpenGL ES 3.0 PBO代替glReadPixels(),android,glreadpixels,opengl-es-3.0,pbo,Android,Glreadpixels,Opengl Es 3.0,Pbo,我想使用PBO(用于GLES 3设备)提高glReadPixels()性能,但在这段代码中遇到了一个问题: final ByteBuffer pboByteBuffer = ByteBuffer.allocateDirect(4 * mWidth * mHeight); pboByteBuffer.order(ByteOrder.nativeOrder()); //set framebuffer to read from GLES30.glReadBuffer(GLES30.GL_BACK);

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

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参数。如果您能就此问题提出任何建议,我将不胜感激

更新:似乎不可能仅使用Java API完成该任务。因此,我使用ndk添加了一个函数,该函数使用正确的最后一个参数(int offset)调用
glReadPixels()
现在,我的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);
}
#包括
#包括
#ifdef_uucplusplus
外部“C”{
JNIEXPORT void JNICALL Java_somepackage_GLES3PBOReadPixelsFix_glReadPixelsPBO(JNIEnv*env、jobject对象、jint x、jint y、jint宽度、jint高度、jint格式、jint类型、jint偏移量pbo);
};
#恩迪夫
JNIEXPORT void JNICALL Java_somepackage_GLES3PBOReadPixelsFix_glReadPixelsPBO(JNIEnv*env、jobject对象、jint x、jint y、jint宽度、jint高度、jint格式、jint类型、jint偏移量PBO)
{
glReadPixels(x、y、宽度、高度、格式、类型、偏移量PBO);
}
现在的问题是
glReadPixels()
调用比不使用PBO需要更多的时间,所以性能还没有提高。我将探究为什么会发生这种情况,并在我发现某些东西时进行更新

更新2 我忘了早些时候更新它,但事实上问题是我使用的是pbuffer surface,这就是为什么我没有性能提升。我比较了这个选项和不使用pbuffer surface的选项,性能得到了巨大的提高


因此,在屏幕外渲染和使用glReadPixels的情况下,在glReadPixels之后立即使用pbuffer surface映射PBO缓冲区总是会降低性能。当您请求映射时,GPU仍在工作。因此,glMapBufferRange等待gpu完成对PBO的像素读取。如果在glReadPixels之后继续渲染,并在某些帧之后进行映射,则将获得性能增益

更多信息请点击此处:
查看“映射PBO”部分。

奇怪。似乎缺少为
glReadPixels()
使用PBOs的Java入口点。如果真是这样的话,这已经不是安卓系统第一次出现这种情况了。使用本机代码始终是一种解决方案。也就是说,如果您立即等待结果,那么使用PBO可能对您帮助不大。整个想法是,
glReadPixels()
调用不会阻塞。如果你事后立即阻止,那不会有多大好处。@RetoKoradi谢谢你的反馈!在我的例子中,仍然是本机代码不是一个选项。唯一真正重要的是,与简单的glReadPixels()callI相比,我的代码块花费了多少时间。我在Android上也遇到过同样的问题,即使用PBO看不到性能提升。您能否解释一下,如何不在Android上使用pbuffer surface来实现快速和异步的glReadPixels到PBO?谢谢。更新了我的答案。我也看到了那篇文章和其他许多文章——不幸的是,当时我没有意识到发生了什么