【问题标题】:Reading data using glReadPixel() with multisampling使用带有多重采样的 glReadPixel() 读取数据
【发布时间】:2011-10-15 17:20:51
【问题描述】:

目前我正在尝试从帧缓冲区中读取像素数据,以便在 IOS 中捕获屏幕。使用以下代码设置帧缓冲区时,GlreadPixels 命令可以正常工作:-

//buffers
// Create a depth buffer that has the same size as the color buffer.
glGenRenderbuffersOES(1, &m_depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT24_OES, width, height);

// Create the framebuffer object.

glGenFramebuffersOES(1, &framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
                             GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES,
                             GL_RENDERBUFFER_OES, m_depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);

但是当我使用深度缓冲区和颜色缓冲区进行多重采样时,glreadpixels() 不会像之前的代码那样捕获任何像素数据....对于多重采样,我使用以下代码:-

glGenFramebuffersOES(1, &sampleFramebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer);

//GLuint sampleColorRenderbuffer;
glGenRenderbuffersOES(1, &sampleColorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleColorRenderbuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_RGBA8_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, sampleColorRenderbuffer);

//glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_RGBA8_OES, width, height);
//glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, sampleColorRenderbuffer);

GLuint sampleDepthRenderbuffer;
glGenRenderbuffersOES(1, &sampleDepthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleDepthRenderbuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_DEPTH_COMPONENT24_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, sampleDepthRenderbuffer);
//glBindRenderbufferOES(GL_RENDERBUFFER_OES,sampleColorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer);

我使用以下代码读取像素数据:-

CGRect screenBounds = [[UIScreen mainScreen] bounds];

int backingWidth = screenBounds.size.width;
int backingHeight =screenBounds.size.height;

glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
NSInteger myDataLength = backingWidth * backingHeight * 4;

buffer= (GLuint *) malloc(myDataLength);
glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

知道如何使用多重采样技术捕获正确的像素数据......还是我做错了什么?请指导我正确的方向。 谢谢

【问题讨论】:

    标签: ios opengl-es framebuffer glreadpixels multisampling


    【解决方案1】:

    使用多重采样 FBO 时,您不能只读取采样缓冲区(因为它不包含简单像素)。您首先需要将样本缓冲区解析为单个缓冲区。

    您可以通过创建另一个非多重采样 FBO(我们称之为 resultFramebuffer)和您想要读取的必要渲染缓冲区存储然后调用:

    glBindFramebuffer(GL_READ_FRAMEBUFFER, sampleFramebuffer);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resultFramebuffer);
    glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
    

    然后你从结果缓冲区中读取(当然实际的常量和函数名可能包含 OES 或 APPLE)。如果您不需要最终的深度值,则结果缓冲区不需要深度渲染缓冲区。

    编辑:正如您在评论中所写以及我搜索的内容,您必须使用一个专用函数 glResolveMultisampleFramebufferAPPLE 而不是 glBlitFramebuffer。其余的保持不变。

    【讨论】:

    • 嘿,首先 glBlitFramebuffer() 在 OES 中不存在 ... glreadpixels() 仅从帧缓冲区读取数据...我发现 glreadbuffer() 用于读取非 fbo 但它也不是在 OES 中可用
    • @Tornado 首先,如果支持多重采样 FBO,则还需要支持 glBlitFramebuffer,否则多重采样 FBO 毫无用处,因为您无法像上面所说的那样解析采样缓冲区(也许这是一个APPLE 扩展,比如多重采样的 FBO?)。如果glReadPixels 无法从 FBO 读取,那么您的第一个代码示例如何工作?如果您不想从 FBO 阅读,那么问题出在哪里?如果您不想读取 FBO 的数据,您应该解释一下您的 FBO 的用途。
    • hmmm 我将再次检查苹果的 glBlitFramebuffer()..实际上是 OpenGl 部分的新手..关于 glreadpixels() 我说它只从 FBO 读取..我很担心关于从你的 resultFramebuffer 中读取像素数据......嘿,我会再次检查整个事情,很快就会告诉你......谢谢你的解释
    • @Tornado 您只需将resultFramebuffer(这是一个标准的非多重采样FBO,就像在您的第一个示例中一样)绑定为当前FBO(使用glBindFramebuffer),然后您可以阅读从中,就像您在第一个非多重采样示例中所做的那样。您唯一要做的就是将多重采样的 FBO 复制到另一个 FBO 并从中读取。
    • 发现有一个名为 glResolveMultisampleFramebufferAPPLE() 的函数用于 blitting 目的......我现在做的是创建一个名为 sampleframebuffer 的多采样 FBO,然后将其绑定为当前 FBO,然后我使用 glBindFramebufferOES (GL_READ_FRAMEBUFFER_APPLE,sampleFramebuffer); glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE,帧缓冲区); glResolveMultisampleFramebufferAPPLE(); glBindFramebufferOES(GL_FRAMEBUFFER_OES,帧缓冲区);代码
    猜你喜欢
    • 2013-07-29
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多