使用FBO RTT的OpenGL,在不应该的情况下进行混合

时间:2009-10-17 22:52:15

标签: c++ opengl blend fbo render-to-texture

这应该非常简单,但是耗费了我几个小时的时间,我不知道发生了什么。

我正在为纹理渲染一个平面彩色的全屏四边形,然后用glGetTexImage读回结果。它与GPGPU有关,所以我希望alpha值的行为就好像它是其他三个中的任何一个。我正在使用FBO,纹理格式GL_RGBA32F_ARB,MacBook Pro 10.5上的NVidia卡,如果重要的话。

如果我指定的alpha为1,我只会返回正确的颜色;使用任何其他值,它似乎与帧缓冲区中已有的值混合,即使我已明确禁用GL_BLEND。我也尝试过启用混合和使用glBlendFunc(GL_ONE, GL_ZERO),但最终结果是一样的。我可以在渲染之前将帧缓冲区清零,从而修复它,但我想了解为什么这是必要的。作为第二个测试,当我只想要原始的4通道颜色时,渲染两个重叠的四边形会产生混合结果。当然,纯色四边形应该完全覆盖帧缓冲区中的像素?我猜我误解了一些基本的东西。感谢。

 const size_t res = 16;
 GLuint tex;
 glGenTextures(1, &tex);
 glBindTexture(GL_TEXTURE_2D, tex);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB,
  res, res, 0, GL_RGBA, GL_FLOAT, 0);
 glBindTexture(GL_TEXTURE_2D, 0);

 GLuint fbo;
 glGenFramebuffersEXT(1, &fbo);
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
  GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0);
 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

 glViewport(0, 0, res, res);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glOrtho(0, res, 0, res, -1, 1);

 glClearColor(0,0,0,0);
 glClear(GL_COLOR_BUFFER_BIT);

 //glEnable(GL_BLEND);
 //glBlendFunc(GL_ONE, GL_ZERO);
 glDisable(GL_BLEND);
 glDisable(GL_DEPTH_TEST);

 glColor4f(0.2, 0.3, 0.4, 0.5);

 for (int i=0; i<2; ++i) {
  glBegin(GL_QUADS);
  glVertex2i(0,0);
  glVertex2i(res, 0);
  glVertex2i(res, res);
  glVertex2i(0, res);
  glEnd();
 }

 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

 std::vector<float> tmp(res*res*4);
 glBindTexture(GL_TEXTURE_2D, tex);
 glGetTexImage(GL_TEXTURE_2D, 0,
  GL_RGBA, GL_FLOAT, &tmp.front());
 const float * const x = &tmp.front();
 cerr << x[0] << " " << x[1] << " " << x[2] << " " << x[3] << endl;
 // prints 0.3 0.45 0.6 0.75

 glDeleteTextures(1, &tex);
 glDeleteFramebuffersEXT(1, &fbo);

1 个答案:

答案 0 :(得分:1)

不是一个好的答案,但有些事情需要注意:

  • 你所观察到的并不像混合。首先,你的后缓冲区最初是rgba = 0,所以对它进行alpha混合将给出0,而不是0.2 0.3 0.4 0.5,就像你可能观察到的那样。
  • 我倾向于你以某种方式设置与纹理 framebuffer附件相同的纹理缓冲区。这在规范(section 4.4.3)中未定义。在您提供的代码段中,您可以执行glBindTexture(GL_TEXTURE_2D, 0),但应该确保不是这种情况......如果您错过了,我会在这里放过它。