代码之家  ›  专栏  ›  技术社区  ›  sdasdadas

OpenGL帧缓冲区缺少面

  •  0
  • sdasdadas  · 技术社区  · 6 年前

    我在使用OpenGL实现多过程着色器以启用HDR时遇到了一个问题。

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

    this tutorial .)


    问题是它不会渲染某些(正面、顶部和一侧)立方体面。

    enter image description here

    enter image description here


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

    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 回复  |  直到 6 年前
        1
  •  0
  •   sdasdadas    6 年前

    我通过实际连接正确的深度渲染缓冲区修复了此问题:

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

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