OpenGL 只渲染第一帧然后渲染黑色
OpenGL only renders the first frame then blackness
我使用 OpenGL 创建了一个延迟渲染器,它似乎只对一帧工作得很好。然后它只呈现黑色。对于下面的代码,我已经将渲染的架构扁平化了很多,但我认为所有相关的东西都包括在内。如果需要更多上下文,您可以查看 here.
第一段是 运行 在程序初始化时:
// corresponds to deferredRenderer.Bind();
glViewport(0, 0, display.GetWidth(), display.GetHeight());
glClearColor(0, 0, 0, 1);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glDepthFunc(GL_LEQUAL);
然后循环开始。首先,渲染器绑定 object/material pass:
// corresponds to deferredRenderer.BindForObjectPass();
gBuffer.BindAsDrawFrameBuffer();
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
然后这段代码是 运行 每个对象(每个对象都有自己的着色器):
materialShader.Bind();
diffuseTexture->Bind(0);
shader.SetUniform("u_diffuse", 0);
glm::mat4 modelViewMatrix = camera.GetViewMatrix() * transform.GetModelMatrix();
glm::mat4 projectionMatrix = camera.GetProjectionMatrix();
materialShader.SetUniform("u_model_view_matrix", modelViewMatrix);
materialShader.SetUniform("u_projection_matrix", projectionMatrix);
glBindVertexArray(vertexArray);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
渲染完所有对象后,光通道开始。在开发的这个阶段,它只是一个带有硬编码光的着色器:
// corresponds to deferredRenderer.RenderLightPass();
display.BindAsDrawFrameBuffer();
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
screenSpaceShader.Bind();
gBuffer.GetAlbedoTexture().Bind(10);
screenSpaceShader.SetUniform("u_albedo", 10);
gBuffer.GetNormalTexture().Bind(11);
screenSpaceShader.SetUniform("u_normals", 11);
glBindVertexArray(vertexArray);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
glBindVertexArray(0);
最后将后台缓冲区切换到前台:
SDL_GL_SwapWindow(window);
在此之后,渲染器再次绑定对象传递并继续循环。
请注意,第一帧完全按照应有的方式呈现,因此我认为可以安全地假设它至少在某种程度上是正确的。它在一个完整帧后发生变化的事实也告诉我,这可能与第一次循环后 gl 状态处于奇怪状态有关。我还确保 gBuffer 渲染缓冲区是完整的,所以 不应该 是 a/the 问题
我使用一些调试工具修复了它,这些工具告诉我是什么 gl-calls 导致了错误。
问题是着色器一构造就被意外销毁,因为我在初始化列表中的堆栈上对其进行初始化。不过,问题中的所有代码都应该可以正常工作。
我使用 OpenGL 创建了一个延迟渲染器,它似乎只对一帧工作得很好。然后它只呈现黑色。对于下面的代码,我已经将渲染的架构扁平化了很多,但我认为所有相关的东西都包括在内。如果需要更多上下文,您可以查看 here.
第一段是 运行 在程序初始化时:
// corresponds to deferredRenderer.Bind();
glViewport(0, 0, display.GetWidth(), display.GetHeight());
glClearColor(0, 0, 0, 1);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glDepthFunc(GL_LEQUAL);
然后循环开始。首先,渲染器绑定 object/material pass:
// corresponds to deferredRenderer.BindForObjectPass();
gBuffer.BindAsDrawFrameBuffer();
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
然后这段代码是 运行 每个对象(每个对象都有自己的着色器):
materialShader.Bind();
diffuseTexture->Bind(0);
shader.SetUniform("u_diffuse", 0);
glm::mat4 modelViewMatrix = camera.GetViewMatrix() * transform.GetModelMatrix();
glm::mat4 projectionMatrix = camera.GetProjectionMatrix();
materialShader.SetUniform("u_model_view_matrix", modelViewMatrix);
materialShader.SetUniform("u_projection_matrix", projectionMatrix);
glBindVertexArray(vertexArray);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
渲染完所有对象后,光通道开始。在开发的这个阶段,它只是一个带有硬编码光的着色器:
// corresponds to deferredRenderer.RenderLightPass();
display.BindAsDrawFrameBuffer();
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
screenSpaceShader.Bind();
gBuffer.GetAlbedoTexture().Bind(10);
screenSpaceShader.SetUniform("u_albedo", 10);
gBuffer.GetNormalTexture().Bind(11);
screenSpaceShader.SetUniform("u_normals", 11);
glBindVertexArray(vertexArray);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
glBindVertexArray(0);
最后将后台缓冲区切换到前台:
SDL_GL_SwapWindow(window);
在此之后,渲染器再次绑定对象传递并继续循环。
请注意,第一帧完全按照应有的方式呈现,因此我认为可以安全地假设它至少在某种程度上是正确的。它在一个完整帧后发生变化的事实也告诉我,这可能与第一次循环后 gl 状态处于奇怪状态有关。我还确保 gBuffer 渲染缓冲区是完整的,所以 不应该 是 a/the 问题
我使用一些调试工具修复了它,这些工具告诉我是什么 gl-calls 导致了错误。
问题是着色器一构造就被意外销毁,因为我在初始化列表中的堆栈上对其进行初始化。不过,问题中的所有代码都应该可以正常工作。