在iOS上从OpenGL ES 3.0读取RGB8缓冲区?

在iOS上从OpenGL ES 3.0读取RGB8缓冲区?,ios,opengl-es-2.0,opengl-es-3.0,Ios,Opengl Es 2.0,Opengl Es 3.0,我真的需要得到一个RGB8字节每个通道缓冲区从GPU。 我需要它传递给一个经过训练的卷积神经网络,它只接受这种格式的数据。 我不能在CPU上转换它,因为我的CPU占用量很大,而且速度很慢 我目前有一个附加了renderbuffer的FBO,其定义如下: glRenderbufferStorage(GL_RENDERBUFFER、GL_RGB8_OES、缓冲区宽度、缓冲区高度); 绑定、定义和渲染缓冲区时没有错误 但是当我使用 glReadPixels(0,0,缓冲宽度,缓冲高度,GL_RG

我真的需要得到一个RGB8字节每个通道缓冲区从GPU。 我需要它传递给一个经过训练的卷积神经网络,它只接受这种格式的数据。 我不能在CPU上转换它,因为我的CPU占用量很大,而且速度很慢

我目前有一个附加了renderbuffer的FBO,其定义如下:

glRenderbufferStorage(GL_RENDERBUFFER、GL_RGB8_OES、缓冲区宽度、缓冲区高度);
绑定、定义和渲染缓冲区时没有错误

但是当我使用

glReadPixels(0,0,缓冲宽度,缓冲高度,GL_RGB,GL_无符号字节,rgbBufferRawName);
它给出了一个无效的枚举错误(0x0500)。当我通过
GL_RED_EXT
GL_RGBA
并生成正确的缓冲区(我通过将这些缓冲区上传到纹理并渲染它们进行了检查,它们看起来是正确的),它就可以正常工作

我尝试设置
glPixelStorei(GL\u PACK\u对齐,1)但这没有什么区别

我使用的是iOS10和iphone6。我以前在做ES2.0,但现在尝试切换到ES3.0,希望它能帮助我解决这个问题。事实并非如此

我非常感谢您以任何方式帮助我获取RGB8缓冲区,
谢谢。

根据OpenGL 3.0规范,GL_RGB不是有效的格式值


您可能希望在检索GL_RGBA格式的缓冲区后将其转换为RGB,或者调整算法以补偿RGBA。

我建议您使用带有颜色纹理附件(如果需要深度缓冲区,则使用深度附件)的FBO,而不是带有渲染缓冲区的FBO,然后使用glGetTextureImage从中读取数据。glGetTextureImage接受GL_RGB格式,而glReadPixels不接受。@VB_overflow
glGetTextureImage
在OpenGL ES 3.0上不可用=(我的错,对不起。在这种情况下,我建议使用如上所述的PBO。使用这种方法,您可以获得RGBA像素数据的ptr,因此,与示例中的memcpy不同,您可以执行仅复制3个字节(RGB)的循环,跳过一个(a)重复一下……这不会像memcpy那么快,但可能非常接近。再加上一些双缓冲或三缓冲,这最终会让你有一个不错的执行速度。@VB\u溢出是的,将FBO切换到PBO是值得的,因为这样可以减少CPU开销。你认为用SIMDs实现RGBA->RGB是否值得r这纯粹是带宽限制,不会有什么区别?我不是IOS(Neon指令集)上SIMD的专家,但乍一看,我想说,对于简单的RGBA到RGB“跨步memcopy”,你不会从中获得太多好处,因为编译器可能已经很好地优化了循环(你是用64位编译的吧?).所以,在GPU上没有办法做到这一点?我不确定你的算法是如何工作的,但如果你打算完全在GPU上使用GLSL,你可以分两次进行。在第一次过程中,你可以将场景渲染为纹理,在第二次过程中运行你的算法。输出可以是到屏幕上,并使用glReadPixels读取值s、 或者你可以写一个统一的变量,然后在它运行后从着色器中读取它。我说的是获取GL_RGB8缓冲区…也许如果我切换到Metal会有一种方法。在iOS上,像GL_RED这样奇异的东西可以很好地工作,但GL_RGB不能。但我想我的用例是非常独特的。我想我只能破解神经网络了努力接受RGBA并跳过alpha,但这将是非常难看的,而且hackyIt听起来像是在寻找CPU解决方案(glReadPixels或同等产品),而不是GPU解决方案(着色器)。如果像素的格式有问题,我建议您查看OpenCV。您可以使用GL_RGBA获取缓冲区,并快速轻松地将其转换为RGB图像。祝您好运!