c++ - 帧缓冲区在移动时切掉模型的一部分

标签 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)));

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

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);

感谢任何帮助!

最佳答案

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

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

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

关于c++ - 帧缓冲区在移动时切掉模型的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48546444/

相关文章:

windows - 是否可以在上下文/线程之间共享 opengl 帧缓冲区对象?

c++ - OpenGL 缓冲区的状态如何在程序运行之间保持不变?

java - 将 C++ OpenGL 帧缓冲区代码移植到 LWJGL - 我使用什么类?

c++ - 使用 for 循环和 rand 生成 100 个随机数并打印出最小值和最大值

opengl - 说 OpenGL 3.2+ 核心配置文件基于 "retained mode"模式是否正确?

c++ - 如何在 OpenGL 中显示图像

c++ - "No definition of main in vertex shader"在 OpenGL 程序链接状态检查期间

c++ - 如何用eclipse cdt编译windows基础程序(使用VIsual Studio编译器)

c++ - 使用参数绑定(bind)通用回调 c++11

c++ - 使用C++模板编程提取任意结构的字段类型