使用带有多重采样的glReadPixel()读取数据

时间:2011-07-29 06:46:52

标签: ios opengl-es framebuffer glreadpixels multisampling

目前我正在尝试从帧缓冲区读取像素数据,以便在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);

任何想法如何使用多采样技术捕获正确的像素数据....或者我做错了什么?请指导我正确的方向。 感谢

1 个答案:

答案 0 :(得分:5)

使用多重采样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。其余的保持不变。