我很难使用OpenGL函数glBlitFramebuffer。在文档中,它表示它支持blitting颜色和深度缓冲区。但是,在实践中却没有。我在Macbook AIR 13英寸,Intel HD Graphics 5000 1536 MB。
我需要从http://ake.in.th/2013/04/02/offscreening-and-multisampling-with-opengl/
进行多重采样我的多重采样级别是4(AA_LEVEL = 4),我的OpenGL版本是:3.2核心配置文件。这就是我在做的事情:
创建多样本AA帧缓冲区。
glGenFramebuffers( 1, &_offscreenBufferHandle );
glBindFramebuffer( GL_FRAMEBUFFER, _offscreenBufferHandle );
glGenRenderbuffers(1, &_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, AA_LEVEL, GL_DEPTH_COMPONENT16, srcWidth_, srcHeight_);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenRenderbuffers(1, &_aaColorbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _aaColorbuffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, AA_LEVEL, GL_RGBA, srcWidth_, srcHeight_);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
创建目标帧缓冲区
glGenFramebuffers( 1, &_outputBufferHandle );
glBindFramebuffer( GL_FRAMEBUFFER, _outputBufferHandle );
glGenRenderbuffers(1, &_outputColorbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _outputColorbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, srcWidth_, srcHeight_);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenRenderbuffers(1, &_outputDepthbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _outputDepthbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, srcWidth_, srcHeight_);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
使用颜色和深度缓冲区绘制内容
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, _offscreenBufferHandle );
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _aaColorbuffer);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
//next
DrawStuff();
将多样本AA帧缓冲区blit到目标帧缓冲区中。
glBindFramebuffer( GL_READ_FRAMEBUFFER, _offscreenBufferHandle );
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _aaColorbuffer);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, _outputBufferHandle );
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _outputColorbuffer);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _outputDepthbuffer);
if( glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE &&
glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE ) {
//do blitting here
glBlitFramebuffer(0, 0, srcWidth_, srcHeight_, 0, 0, srcWidth_, srcHeight_, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST);
}
从目标帧缓冲区中读取像素并进行一些后期处理
//then blit it to pixels buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, _outputBufferHandle);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _outputColorbuffer);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _outputDepthbuffer);
readParam("temp");
GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if( framebufferStatus == GL_FRAMEBUFFER_COMPLETE ) {
glReadBuffer(GL_COLOR_ATTACHMENT0);
//getGLErr("GL_COLOR_ATTACHMENT0");
glReadPixels(0, 0, srcWidth_, srcHeight_, GL_BGR, GL_UNSIGNED_BYTE, pixels);
}
然而结果只有颜色缓冲液成功印迹,没有深度缓冲。
如果我禁用多重采样,通过更改我的AA_LEVEL = 0,并替换删除步骤4,用以下代码替换步骤5直接从_offscreenBufferHandle读取,结果看起来正确。
glBindFramebuffer(GL_READ_FRAMEBUFFER, _offscreenBufferHandle);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _aaColorbuffer);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
GLenum framebufferStatus = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
if( framebufferStatus == GL_FRAMEBUFFER_COMPLETE ) {
glReadPixels(0, 0, srcWidth_, srcHeight_, GL_BGR, GL_UNSIGNED_BYTE, pixels);
}
很多帖子都指向类似的问题,我很困惑这是一个图形卡问题,还是我一直在做的事情是错误的。
https://gamedev.stackexchange.com/questions/68290/fbo-blit-depth-buffer-to-screen
https://www.opengl.org/discussion_boards/showthread.php/176317-Framebuffer-not-bliting-depth-buffer
在这些文章中,这意味着我需要绘制纹理四边形,而不是从读取缓冲区到绘制缓冲区执行blit。那太麻烦了。