OpenGL Framebuffer Missing Faces - PullRequest
       10

OpenGL Framebuffer Missing Faces

0 голосов
/ 21 сентября 2018

У меня проблема с использованием OpenGL для реализации многопроходных шейдеров, чтобы включить HDR.

Первый проход переводит сцену в кадровый буфер.

Второй проход использует кадровый буфер сцвет и глубина рендеринга в квад.

(я следую этого урока .)


Проблема в том, что он не рендерит определенным образом (спереди,верхняя и одна стороны) граней куба.

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 голосов
/ 21 сентября 2018

Я исправил это, фактически подключив правильный буфер рендеринга глубины:

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

в

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