片段着色器多输出与FrameBuffer对象读取异常问题
问题原因与修复方案
核心原因
OpenGL默认仅会将片段着色器的输出写入GL_COLOR_ATTACHMENT0,当使用多颜色附件时,必须显式指定绘制缓冲区列表,否则第二个附件不会被写入任何数据,读取时自然返回初始值0。
修复步骤
1. 添加绘制缓冲区配置
在FBO绑定后、执行绘制操作前,添加以下代码,告知OpenGL要写入两个颜色附件:
FBO.Bind(); renderer.Clear(); // 添加这两行 GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); // 后续绘制操作 renderer.Draw(Circle_VAO, Circle_Shader, Circle_IB); renderer.Draw(Quad_VAO, Quad_Shader, Quad_IB);
2. 修正整数纹理的过滤设置
GL_R32I属于整数纹理格式,不支持GL_LINEAR线性过滤,会触发OpenGL错误(可能被你的GLerror宏捕获,但未处理)。需要将第二个附件的纹理过滤改为GL_NEAREST:
// 在创建第二个颜色附件时修改 GLerror(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GLerror(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
3. 验证坐标正确性
注意OpenGL的窗口坐标系原点在左下角,如果你传入的(450,360)是屏幕坐标系(原点在左上角)的坐标,需要转换y值:
// 假设窗口高度为720 int y = 720 - 360; std::cout << FBO.ReadPixels(450, y, 1) << std::endl;
内容的提问来源于stack exchange,提问作者newCoder
相关产品推荐
相关产品推荐

