帧缓冲就是我们自己可以使用的一个缓冲,在这个缓冲里面,我们可以写入颜色、深度和模板信息(color, depth and stencil)。
为了使用这个framebuffer,必须给它附加一个texture 或者 renderbuffer,相当于vao和vbo的关系,framebuffer管理它的 texture 和 renderbuffer,数据都存储在这两个上面。其中texture可以存储颜色、深度和模板信息,可以直接进行读写操作,而renderbuffer 一般用来存储深度和模板信息,不能直接读。
注意:两者是可以同时绑定的。
附件类型对比:
| 特性 | 纹理附件 (Texture) | 渲染缓冲 (Renderbuffer) |
|---|---|---|
| 存储用途 | 颜色/深度/模板均可 | 主要深度/模板 |
| CPU访问 | ✅ glReadPixels+着色器 | ✅ glReadPixels |
| 着色器访问 | ✅ 可被采样 | ❌ 无法绑定采样 |
| 性能特点 | Mipmap/Filter支持 | 硬件层优化(某些GPU更快) |
| 适合场景 | 后处理/屏幕特效 | 纯深度测试(如阴影生成) |
使用帧缓冲的步骤:
- 创建FBO
GLuint fbo;
glGenFramebuffer(1, &fbo);
- 为FBO创建
texture或者renderbuffer,用于存储信息
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// 这里我用来存储颜色信息
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); // 空纹理
// 设置纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 用来存储深度和模板信息
GLuint rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, backwardSceneDepthRBO);
// 分配内存 + 格式
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
- 为 fbo 绑定
texture和renderbuffer
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
// 检查 fbo 是否完整
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
// 常见失败原因
// 1. 尺寸不一致 2. 格式不支持 3. 无颜色附件
std::cout << "FBO is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- 渲染一遍场景,这次渲染主要是为了存储信息到自己的fbo中
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, width, height); // 必须匹配fbo尺寸
renderScene();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- 后续正常渲染,可以使用刚刚保存的信息
glViewport(0, 0, originwidth, originheight);
// 这里直接将刚刚渲染的场景当做纹理用了
glActiveTexture(GL_TEXTURE);
glBindTexture(GL_TEXTURE_2D, texture);
renderScene();
使用到的函数:
glBindFramebuffer(GLenume target, GLuint framebuffer)target:指定使用帧缓冲的目标类型GL_FRAMEBUFFER:同时绑定到读写帧缓冲(最常用)GL_READ_FRAMEBUFFER:仅绑定到读取操作(如 glReadPixels)GL_DRAW_FRAMEBUFFER:仅绑定到绘制操作(如渲染命令)
framebuffer:帧缓冲对象ID。0为默认窗口的系统帧缓冲(GLFW创建的)。
glRenderbufferStorage(GLenume target, GLenum internalformat, GLsizei width, GLsizei height):为当前绑定的渲染缓冲对象分配存储空间target:必须为GL_RENDERBUFFER,指定操作对象类型internalformat:存储格式 (如GL_DEPTH_COMPONENT24,GL_DEPTH24_STENCIL8)width:渲染缓冲宽度(像素)height:渲染缓冲高度(像素)
glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level):将2D纹理附加到帧缓冲的指定附件点target:帧缓冲目标 (GL_FRAMEBUFFER,GL_READ_FRAMEBUFFER)attachment:附件类型 (GL_COLOR_ATTACHMENT0,GL_DEPTH_ATTACHMENT等)textarget:纹理类型 (GL_TEXTURE_2D,GL_TEXTURE_CUBE_MAP_POSITIVE_X等)texture:纹理对象IDlevel:纹理mipmap级别 (通常为0)
glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer):将渲染缓冲附加到帧缓冲的指定附件点target:帧缓冲目标 (GL_FRAMEBUFFER,GL_READ_FRAMEBUFFER)attachment:附件类型 (GL_COLOR_ATTACHMENT0,GL_DEPTH_ATTACHMENT,GL_DEPTH_STENCIL_ATTACHMENT等)renderbuffertarget:必须为GL_RENDERBUFFERrenderbuffer:渲染缓冲对象ID
使用Framebuffer制作的效果:

3497

被折叠的 条评论
为什么被折叠?



