OpenGL帧缓冲缺少面

时间:2018-09-20 21:54:05

标签: opengl shader framebuffer

我在使用OpenGL实现多通道着色器以启用HDR时遇到问题。

第一遍将场景渲染到帧缓冲区。

第二遍使用具有颜色和深度的帧缓冲区渲染为四边形。

(我正在关注this tutorial。)


问题在于它无法渲染某些(正面,顶部和一侧)立方体面。

enter image description here

如果我在没有帧缓冲区的情况下进行渲染(不更改任何其他渲染代码),则它将按预期工作。

enter image description here


我尝试使用GL_CCW和GL_CW来更改面的缠绕,并将glDepthFunc更改为无效。

这是渲染器初始化的代码:

Renderer::Renderer(Window window): window(window) {
  this->materials = std::map<std::string, Material>();
  this->meshes = std::map<std::string, Mesh>();

  // glEnable(GL_BLEND);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_CULL_FACE);
  glEnable(GL_FRAMEBUFFER_SRGB);
  glViewport(0, 0, window.width, window.height);  
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  this->load_textures();
  this->load_materials();
  this->load_meshes();

  this->load_shader_programs();

  this->create_hdr(this->shader_programs.find("hdr")->second);
}

这将在第一个渲染之前生成帧缓冲区:

void Renderer::create_hdr(ShaderProgram sp_hdr) {
  glGenFramebuffers(1, &this->hdr_fbo);

  glGenTextures(1, &this->color_buffer);
  glBindTexture(GL_TEXTURE_2D, this->color_buffer);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, this->window.width, this->window.height, 0, GL_RGBA, GL_FLOAT, NULL);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  glGenRenderbuffers(1, &this->render_buffer);
  glBindRenderbuffer(GL_RENDERBUFFER, this->render_buffer);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, this->window.width, this->window.height);

  glBindFramebuffer(GL_FRAMEBUFFER, this->hdr_fbo);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->color_buffer, 0);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->depth_buffer);
  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    std::cout << "Framebuffer not complete!" << std::endl;
  }
  glBindFramebuffer(GL_FRAMEBUFFER, 0);

  glUseProgram(sp_hdr.id);
  glUniform1i(glGetUniformLocation(sp_hdr.id, "hdr_buffer"), 0);
}

这将通过两次渲染来渲染关卡:

void Renderer::render(Level level, Camera camera, std::vector<std::reference_wrapper<DirectionalLight>> d_lights, std::vector<PointLight> p_lights, std::vector<SpotLight> s_lights) {
  // 1. First Pass - HDR
  glBindFramebuffer(GL_FRAMEBUFFER, this->hdr_fbo);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  ShaderProgram sp_render = this->shader_programs.find("render")->second;
  glUseProgram(sp_render.id);

  attach_camera(camera, sp_render);
  attach_projection_matrix(camera, sp_render);
  attach_view_matrix(camera, sp_render);

  unsigned int d_light_num = 0;
  for (DirectionalLight d_light : d_lights) {
    attach_d_light(d_light, sp_render, d_light_num);
    d_light_num++;
  }  

  for (Block block : level.blocks) {
    attach_position(block.position, sp_render);

    Material material = this->materials.find(block.material_id)->second;
    attach_material(material, sp_render);

    Mesh mesh = this->meshes.find(block.mesh_id)->second;
    draw_mesh(mesh, sp_render); 
  }

  glBindFramebuffer(GL_FRAMEBUFFER, 0);

  // 2. Second Pass - Render to quad
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  ShaderProgram sp_hdr = this->shader_programs.find("hdr")->second;
  glUseProgram(sp_hdr.id);

  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, this->color_buffer);

  draw_mesh(this->meshes.find("quad")->second, sp_hdr);
}

1 个答案:

答案 0 :(得分:0)

我通过实际连接正确的深度渲染缓冲区来解决此问题:

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->depth_buffer);

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->render_buffer);