OpenGL 帧缓冲区缺失面
Posted
技术标签:
【中文标题】OpenGL 帧缓冲区缺失面【英文标题】:OpenGL Framebuffer Missing Faces 【发布时间】:2018-09-20 21:54:04 【问题描述】:我在使用 OpenGL 实现多通道着色器以启用 HDR 时遇到问题。
第一遍将场景渲染到帧缓冲区。
第二遍使用带有颜色和深度的帧缓冲区来渲染到四边形。
(我关注this tutorial。)
问题在于它不会渲染某些(正面、顶部和一侧)立方体面。
如果我在没有帧缓冲区的情况下进行渲染(不更改任何其他渲染代码),它会正常工作。
我尝试使用 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】:我通过实际连接正确的深度渲染缓冲区来解决这个问题:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->depth_buffer);
到
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->render_buffer);
【讨论】:
以上是关于OpenGL 帧缓冲区缺失面的主要内容,如果未能解决你的问题,请参考以下文章