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 导致了错误。

问题是着色器一构造就被意外销毁,因为我在初始化列表中的堆栈上对其进行初始化。不过,问题中的所有代码都应该可以正常工作。