写入OpenGL多个渲染缓冲区失败

乔伊

不确定是什么问题,写入多个渲染缓冲区时无法读取像素。这是代码:

设置代码:

// gen framebuffer object
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// gen renderbuffer 0
glGenRenderbuffers(1, &rbo_color0);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_color0);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo_color0);

// gen renderbuffer 1
glGenRenderbuffers(1, &rbo_color1);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_color1);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RED_INTEGER, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbo_color1);

// gen depth buffer
glGenRenderbuffers(1, &rbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

渲染和读取像素代码:

// setup shader and uniforms...
// bind framebuffer and clear color/depth buffer
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glEnable(GL_DEPTH_TEST);
glClearColor(0.f, 0.f, 0.f, 0.1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

const GLuint buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, buffers);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, (void*)0);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, data);
glReadBuffer(GL_COLOR_ATTACHMENT1);
glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_INT, (int*)(data) + 4);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

我在着色器中为输出使用了布局限定符,那里应该没有任何问题。因此,我认为缓冲区设置或渲染代码可能有问题。当只有一个renderbuffer(rbo_color0)时,我已成功读取像素。主要区别在于:

  1. 没有renderbuffer1的生成代码;
  2. 渲染时使用glDrawBuffer(rbo_color0);
  3. rbo_color0的格式为GL_RGBA(仔细检查了相应的glRenderbufferStorage / glReadBuffer调用中的格式设置,这里没有问题);
  4. 没有rbo_color1的读取像素调用。

有帮助吗?

拉比德76

GL_RED_INTEGER不是正确的内部格式,因为它可以用于的第二个参数glRenderbufferStorage适用于内部格式的枚举器常量应为GL_R32I
请参阅OpenGL 4.6 API兼容性配置文件规范;8.26。纹理图像负载和存储;第334页

如果要检查OpenGL错误(glGetError),则会出现INVALID_ENUM错误。

更改渲染缓冲区存储规范,以解决此问题:

glRenderbufferStorage(GL_RENDERBUFFER, GL_R32I, w, h); 

注意,您应该通过glCheckFramebufferStatus以下方式检查帧缓冲区的完整性

GLenum fb_status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
if ( fb_status != GL_FRAMEBUFFER_COMPLETE )
{
  // error handling
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章