【问题标题】:Using a single FBO to draw a single scene from multiple viewpoints into multiple textures (1 per viewpoint) yields only one valid texture使用单个 FBO 将单个场景从多个视点绘制到多个纹理中(每个视点 1 个)仅产生一个有效纹理
【发布时间】:2013-11-26 04:53:07
【问题描述】:

我目前正在处理一项任务,该任务要求我们生成用于环境映射的立方体贴图(不使用任何内置的 OpenGL 立方体映射功能)。目前只有最后渲染的图像是有效的。其余的全是黑色的,不管我设置了什么清晰的颜色。

似乎从 FBO 中分离纹理会使其无效(将其清除为黑色)。如果我绘制到一个纹理,然后通过调用glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0) 将纹理从 fbo 中分离出来,我刚刚写入的纹理是黑色的。


伪代码:

bind FBO

for each viewpoint to be rendered (+- each axis, 6 total)
  calculate transformation matrices needed for viewpoint
  attach next texture to FBO at GL_COLOR_ATTACHMENT0
  clear color and depth
  render scene

unbind FBO

这是将同一场景渲染到多个纹理的合理方法,还是应该使用多个 FBO? 推荐的方法是什么(再次,避免使用 OpenGL 立方体贴图功能)?


C++ 代码:

初始化 FBO

// Setup FBO
glGenFramebuffers(1, &_env_map_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _env_map_fbo);

// Setup depth buffer
glGenTextures(1, &_env_map_depth);
glBindTexture(GL_TEXTURE_2D, _env_map_depth);

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0); // unbind depth texture

// Attach depth buffer to FBO
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, _env_map_depth, 0);

// Configure FBO
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glReadBuffer(GL_NONE);

glViewport(0, 0, 512, 512);

// Verify framebuffer is complete
GLenum fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);(void)fb_status;
pcerror_if(fb_status != GL_FRAMEBUFFER_COMPLETE, "Error setting up FBO!");

初始化纹理

glGenTextures(6, _tex_ids);

for(uint i = 0; i < 6; ++i)  
{
  glBindTexture(GL_TEXTURE_2D, _tex_ids[i]);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0, GL_RGB, GL_FLOAT, nullptr);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
}

glBindTexture(GL_TEXTURE_2D, 0);

内部渲染循环

// Bind frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, _env_map_fbo);    
glDrawBuffer(GL_COLOR_ATTACHMENT0);

// Calculate transformation matrices for viewpoint 1
// ...

glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _tex_ids[0], 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_graphics.render(); // Render entire scene using the same code I normally use.

// Calculate transformation matrices for viewpoint 2
// ...

glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _tex_ids[1], 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_graphics.render();

// Etc. for each viewpoint

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);

// Draw scene as normal

如果有用,请提供更多信息:

  • 我正在使用 gDEBugger 检查渲染结果。
  • 纹理在此处使用时不应绑定到其他任何地方。

【问题讨论】:

    标签: opengl fbo render-to-texture


    【解决方案1】:

    看来我的方法确实有效。我对 gDEBugger 过于信任了。将纹理绘制到 HUD 我看到了我期望的输出。

    我的结果 gDEBugger

    【讨论】:

      【解决方案2】:

      您没有完全初始化纹理。在调用glTexImage…glTexStorage… 之前,纹理对象不会完全初始化。在将纹理的层/面绑定到 FBO 之前,您必须这样做。同样对于渲染到立方体贴图,您需要创建一个立方体贴图纹理,并且只将其每个面依次绑定到 FBO。

      【讨论】:

      • 我为所有纹理调用 glTexImage2D:glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0, GL_RGB, GL_FLOAT, nullptr); // Color attachments, glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); // Depth buffer
      • 就立方体贴图部分而言,我确实声明我正在处理的任务要求我们“不使用任何内置的 OpenGL 立方体贴图功能”,即我们必须制作 6 种不同的纹理,然后选择我们要在片段着色器中使用哪一种(效率不高,仅用于学习目的)。
      猜你喜欢
      • 1970-01-01
      • 2018-04-08
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      • 2014-02-18
      相关资源
      最近更新 更多