渲染第二遍会产生不同的结果

时间:2017-09-14 05:28:16

标签: c++ opengl glsl

目前我正在尝试在简单的OpenGL应用程序中使用不同的着色器渲染多个传递。这是我的(简化)代码:

void InitScene()
{
  glViewport(0, 0, mWindowWidth, mWindowHeight);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, mWindowWidth, mWindowHeight, 0, -1, 1);

  mFramebufferName = CreateFrameBuffer(mWindowWidth, mWindowHeight);
}


void DrawScene()
{
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();

  if(drawDirectlyToScreen)
  {
    // This works fine, image will fill the whole screen

    // Directly draw to the screen
    DrawFullScreenQuad();
  }
  else
  {
    // This does not work. The image from the first pass will only be a small quadrat

    // Draw to frame buffer instead of screen
    glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName); 
    DrawFullScreenQuad();
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // Get ready for second pass
    BindFrameBufferTextureAndActivateAnotherShader();

    // Now draw to the screen
    DrawFullScreenQuad();
  }

  glPopMatrix();
}

void DrawFullScreenQuad()
{
  glBegin(GL_QUADS);
  glTexCoord2f(0.0f, 1.0f);  glVertex3f(0.0f, mWindowHeight, 0.0f);
  glTexCoord2f(1.0f, 1.0f);  glVertex3f(mWindowWidth, mWindowHeight, 0.0f);
  glTexCoord2f(1.0f, 0.0f);  glVertex3f(mWindowWidth, 0.0f, 0.0f);
  glTexCoord2f(0.0f, 0.0f);  glVertex3f(0.0f, 0.0f, 0.0f);
  glEnd();
}

void CreateFrameBuffer(int width, int height)
{
  // Generate and bind the frame buffer
  mFramebufferName = 0;
  glGenFramebuffers(1, &mFramebufferName);
  glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);

  // Create and bind the render texture
  glGenTextures(1, &mSecondPassRenderTexture);
  glBindTexture(GL_TEXTURE_2D, mSecondPassRenderTexture);

  // Give an empty image to OpenGL ( the last "0" )
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

  // Set "mSecondPassRenderTexture" as colour attachement #0
  glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mSecondPassRenderTexture, 0);

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

当只渲染一遍时,一切都很好。图像覆盖整个屏幕。使用两次渲染渲染时,生成的图像将仅覆盖屏幕左上角的小方块区域(请参阅附图)。

Rendering with one pass Rendering a second pass

问题似乎来自第一遍。在该过程中创建的纹理已经错误(即图像仅在角落中,其余纹理为黑色)。然后第二遍正常工作(即破碎的纹理被正确地绘制到整个屏幕)。

所以我的问题是:为什么我对DrawFullScreenQuad()的调用会产生不同的结果

  1. 直接渲染到屏幕
  2. 渲染到帧缓冲区(与窗口大小相同)

0 个答案:

没有答案