Framebuffer在移动时切出模型部分

时间:2018-01-31 16:03:25

标签: c++ opengl framebuffer post-processing

我遇到了为后期处理实现帧缓冲区的问题。到目前为止,我可以将所有内容绘制到纹理四边形并应用着色器来更改屏幕,因此在这方面它可以工作。

我的问题是,当我移动模型或相机时,模型开始渲染不正确,部分模型被“切断”。请参阅以下屏幕截图,因为很难解释。

Image 1 Image 2

为了避免放置代码的页面和页面,所有渲染在没有帧缓冲区的情况下工作正常,如果我不移动相机或模型,每个渲染都很好。

我设置了这样的帧缓冲区。

//Set up FBO
glGenFramebuffers(1, &m_FrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_FrameBuffer);

glActiveTexture(GL_TEXTURE2);
glGenTextures(1, &m_TexColorBuffer);
glBindTexture(GL_TEXTURE_2D, m_TexColorBuffer);


glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGB, 1280, 720, 0, GL_RGB, GL_UNSIGNED_BYTE, 0
);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glFramebufferTexture2D(
    GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_TexColorBuffer, 0
);

glGenRenderbuffers(1, &m_RBODepthStencil);
glBindRenderbuffer(GL_RENDERBUFFER, m_RBODepthStencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1280, 720);

glFramebufferRenderbuffer(
    GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_RBODepthStencil
);

glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_TexColorBuffer, 0);

GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    std::cout << "Frame Buffer: Contructor: Issue completing frame buffer" << std::endl;


//Set Up Shader
m_ScreenShader = new Shader("../Assets/Shaders/screen.vert", "../Assets/Shaders/screen.frag");

//Setup Quad VAO

glGenBuffers(1, &m_QuadVBO);
glBindBuffer(GL_ARRAY_BUFFER, m_QuadVBO);
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(float), points, GL_STATIC_DRAW);

glGenVertexArrays(1, &m_QuadVAO);
glBindVertexArray(m_QuadVAO);
//glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, m_QuadVBO);
//glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

GLint posAttrib = glGetAttribLocation(m_ScreenShader->getID(), "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);

GLint texAttrib = glGetAttribLocation(m_ScreenShader->getID(), "texcoord");
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));

然后在绘制场景(天空盒和模型)之前将其绑定,然后像这样绘制它。

Unbind();
glBindVertexArray(m_QuadVAO);
glDisable(GL_DEPTH_TEST);
m_ScreenShader->enable();
m_ScreenShader->setUniform1f("time", glfwGetTime());
GLint baseImageLoc = glGetUniformLocation(m_ScreenShader->getID(), "texFramebuffer");
glUniform1i(baseImageLoc, 2);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, m_TexColorBuffer);

glDrawArrays(GL_TRIANGLES, 0, 6);

感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

当渲染到具有深度缓冲区并且启用深度测试的帧缓冲区时,必须清除深度缓冲区。在绑定帧缓冲区之后和绘制到帧缓冲区之前,必须清除深度缓冲区:

gllBindFramebuffer( GL_FRAMEBUFFER, m_FrameBuffer );
glClear( GL_DEPTH_BUFFER_BIT );

注意,如果您不清除深度缓冲区,它会保留其内容。这导致深度测试可能在几何已经过去的位置处失败。因此,几何中缺少部件,如问题中的图像。