【发布时间】:2017-04-21 19:49:48
【问题描述】:
我真的需要从 GPU 获取每个通道缓冲区的 RGB 8 字节。 我需要将它传递给经过训练的卷积神经网络,它只接受该格式的数据。 我无法在 CPU 上转换它,因为我受 CPU 严重限制而且速度很慢。
我目前有一个附加了渲染缓冲区的 FBO,它定义为:
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, bufferWidth, bufferHeight);
绑定、定义和渲染到缓冲区时没有错误。
但是当我使用
glReadPixels(0, 0, bufferWidth, bufferHeight, GL_RGB, GL_UNSIGNED_BYTE, rgbBufferRawName);
它给出了一个无效的枚举错误(0x0500)。当我通过 GL_RED_EXT 或 GL_RGBA 并生成正确的缓冲区时,它工作得很好(我已经通过将这些缓冲区上传到纹理并渲染它们来检查它,它们看起来是正确的)。
我尝试设置glPixelStorei(GL_PACK_ALIGNMENT, 1);,但没有任何区别。
我在 iOS10 和 iPhone 6 上。我在做 ES2.0,但现在尝试切换到 ES3.0,希望它能帮助我解决问题。它没有。
非常感谢以任何方式获得 RGB8 缓冲区的帮助, 谢谢。
【问题讨论】:
-
我建议不要使用带有渲染缓冲区的 FBO,而是使用带有颜色纹理附件的 FBO(如果需要深度缓冲区,还可以使用深度附件),然后使用 glGetTextureImage 从中读取数据。 glGetTextureImage 接受 GL_RGB 格式,而 glReadPixels 不接受。
-
@VB_overflow
glGetTextureImage在 OpenGL ES 3.0 上不可用 =( -
我的错,对不起。在这种情况下,我建议使用 here 中描述的 PBO。使用这种方法,您可以获得一个指向 RGBA 像素数据的 ptr,因此您可以执行一个仅复制 3 个字节 (RGB) 的循环,而不是像示例中那样执行 memcpy,跳过一个 (A) 并重复...这将不如 memcpy 快,但可能非常接近。结合一些双重或三重缓冲,这应该可以让您最终获得不错的执行速度。
-
@VB_overflow 是的,将 FBO 切换到 PBO 是值得的,因为 CPU 开销要少得多。您认为使用 SIMD 实现 RGBA -> RGB 是否值得?或者它纯粹是带宽限制,不会有任何区别?
-
我不是 IOS(Neon 指令集)上 SIMD 方面的专家,但乍一看,我会说你不会从简单的 RGBA 到 RGB“跨步 memcopy”中获得太多收益,因为编译器会可能已经很好地优化了循环(你用 64 位编译对吗?)。
标签: ios opengl-es-2.0 opengl-es-3.0