在显示窗口中使用的framebuffer,opengl渲染管线会自动创建一个颜色渲染区(color),一个深度渲染缓冲区(depth)和一个模板渲染缓冲区(stencil),开启glEnable(GL_DEPTH_TEST)就可以了。然而在离屏渲染自己创建的framebuffer中,这几个需要手动创建。需要哪个创建哪个。
之前在基于ffmpeg中添加的离屏渲染filter中只绑定了GL_COLOR_ATTACHMENT0,然后发现draw的时候后画的会覆盖先画的内容。查了下,发现需要手动创建renderbuffer,初始化大小,并且绑定GL_DEPTH_ATTACHMENT,这样才能通过glEnable(GL_DEPTH_TEST)来开启深度。(如果不创建这个buffer绑定,那么仅仅开启GL_DEPTH_TEST毫无效果,不会有深度测试)
这里笔记一下我使用的framebuffer初始化过程,使用的是multisample texture用于抗锯齿,创建了3个fbo分别用于YUV,所以每一个的texture只用到RED
1. 创建3个texture,并初始化多采样次数为4
glGenTextures(3, tex_serial);
for (int i=0; i<planes; i++)
{
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_serial[i]);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RED, width[i], height[i], GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
}
2. 创建3个renderbuffer
glGenRenderbuffers(3, fbo_depth);
for (int i=0; i<s->planes; i++)
{
glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth[i]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT, width[i], height[i]);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
3. 创建3个framebuffer,并且分别绑定对应的texture和renderbuffer
glGenFramebuffers(3, fbo_render);
for (int i=0; i<s->planes; i++)
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo_render[i]);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex_serial[i], 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
av_log(NULL, AV_LOG_ERROR, "Error code %x (in %s): Couldn't create frame buffer", status, __FUNCTION__);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
如果没有绑定depth buffer的话(也就是不做glFramebufferRenderbuffer),则深度信息在画图时没有体现,后画的会覆盖先画的,如下图:
如果绑定了depth并且开始了深度测试,则可以按我们预期的输出: