【问题标题】:glReadPixels from FBO fails with multisampling来自 FBO 的 glReadPixels 因多重采样而失败
【发布时间】:2010-10-20 09:48:41
【问题描述】:

我有一个带有颜色和深度附件的 FBO 对象,我使用glReadPixels() 对其进行渲染并从中读取,我正在尝试为其添加多重采样支持。
而不是glRenderbufferStorage(),我为颜色附件和深度附件调用glRenderbufferStorageMultisampleEXT()。帧缓冲区对象似乎已成功创建并报告为完成。
渲染后,我尝试使用glReadPixels() 读取它。当样本数为 0 时,即禁用多重采样时,它工作得很好,我得到了我想要的图像。当我将样本数设置为其他值时,例如 4,帧缓冲区仍然可以正常构建,但 glReadPixels() 失败并显示 INVALID_OPERATION

有人知道这里出了什么问题吗?

编辑:glReadPixels 的代码:

glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, ptr);

其中 ptr 指向宽度*高度单位的数组。

【问题讨论】:

  • 您能否发布您的 glReadPixels() 调用的完整行(格式、类型等)?

标签: opengl fbo multisampling


【解决方案1】:

我认为您不能使用 glReadPixels() 从多重采样 FBO 中读取数据。您需要从多重采样的 FBO 到普通 FBO,绑定普通 FBO,然后从普通 FBO 读取像素。

类似这样的:

// Bind the multisampled FBO for reading
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, my_multisample_fbo);
// Bind the normal FBO for drawing
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, my_fbo);
// Blit the multisampled FBO to the normal FBO
glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
//Bind the normal FBO for reading
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo);
// Read the pixels!
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

【讨论】:

【解决方案2】:

您不能直接使用 glReadPixels 读取多重采样缓冲区,因为它会引发 GL_INVALID_OPERATION 错误。您需要 blit 到另一个表面,以便 GPU 可以进行下采样。您可以对后台缓冲区进行 blit,但存在“像素所有者船舶测试”的问题。最好再做一个FBO。假设您制作了另一个 FBO,现在您想要 blit。这需要 GL_EXT_framebuffer_blit。通常,当您的驱动程序支持 GL_EXT_framebuffer_multisample 时,它​​也支持 GL_EXT_framebuffer_blit,例如 nVidia Geforce 8 系列。

 //Bind the MS FBO
 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, multisample_fboID);
 //Bind the standard FBO
 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboID);
 //Let's say I want to copy the entire surface
 //Let's say I only want to copy the color buffer only
 //Let's say I don't need the GPU to do filtering since both surfaces have the same dimension
 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
 //--------------------
 //Bind the standard FBO for reading
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
 glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels);

来源:GL EXT framebuffer multisample

【讨论】:

    猜你喜欢
    • 2017-01-13
    • 1970-01-01
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-27
    • 1970-01-01
    • 2019-06-03
    相关资源
    最近更新 更多