5

我的多渲染目标代码出现了一些非常奇怪的行为,并且开始怀疑我是否严重误解了它应该工作的方式。

我在 2.1 版本的上下文中运行。这是我正在执行的渲染设置代码的核心部分:

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(2,buffers);  

然后我的着色器将颜色数据写入gl_FragColor[0]glFragColor[1]

这与此问题中讨论的情况基本相同。但是,当我在 OS X 上运行它时,我的着色器只输出到第一个渲染目标。OpenGL 不会抛出错误,无论是在构建带有两个颜色附件的 FBO 期间,还是在渲染过程中的任何时候。

当我通过 OSX 的“OpenGL Profiler”“跟踪”视图检查发生的情况时,它显示此代码执行的驱动程序方面为:

2.86 µs glBindFramebufferEXT(GL_FRAMEBUFFER, 1);
3.48 µs glDrawBuffersARB(2, {GL_COLOR_ATTACHMENT0, GL_ZERO});

这也许可以解释为什么没有写入任何内容GL_COLOR_ATTACHMENT1GL_ZERO它似乎在调用中被替换为glDrawBuffers!

buffers[]如果我将数组中缓冲区的顺序切换为GL_COLOR_ATTACHMENT1_EXTfirst 然后GL_COLOR_ATTACHMENT0_EXT,那么我的着色器只写入GL_COLOR_ATTACHMENT1_EXT,并且GL_COLOR_ATTACHMENT0_EXT似乎被替换为GL_ZERO

这就是它变得奇怪的地方。如果我使用代码:

GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(3, buffers);

然后统计视图显示:

0.46 µs glDrawBuffersARB(3, {GL_COLOR_ATTACHMENT0, GL_ZERO, GL_COLOR_ATTACHMENT1});

OpenGL 仍然没有抛出任何错误,并且我的着色器成功地将数据写入两个颜色附件,即使它正在写入gl_FragColor[0]gl_FragColor[1].

因此,即使我的程序现在正在运行,但在我看来这不应该起作用。我很想知道我能把它推到多远,希望把 OpenGL 推向最终的失败是有教育意义的。所以我尝试用这段代码编译:

GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(4, buffers);

运行它时,OpenGL Profiler“跟踪”视图将其显示为正在执行:

4.26 µs glDrawBuffersARB(4, {GL_COLOR_ATTACHMENT0, GL_ZERO, GL_COLOR_ATTACHMENT1, GL_ZERO});

现在 OpenGL 到处抛出“无效的帧缓冲操作”,但我的着色器仍然成功地将颜色数据写入两个颜色连接点。

这一切对任何人都有意义吗?我是否灾难性地误解了glDrawBuffers应该调用的方式?

根据 OpenGL Profiler 的“资源”视图,我的帧缓冲区(编号 1)看起来不错;正如预期的那样,它确实附有两个颜色附件。

Attached Objects:
{
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_COLOR_ATTACHMENT0
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_TEXTURE
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT: 1
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT: 0
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT: 0
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT: 0
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_COLOR_ATTACHMENT1
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_TEXTURE
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT: 2
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT: 0
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT: 0
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT: 0
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_COLOR_ATTACHMENT2
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_NONE
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_COLOR_ATTACHMENT3
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_NONE
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_COLOR_ATTACHMENT4
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_NONE
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_COLOR_ATTACHMENT5
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_NONE
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_COLOR_ATTACHMENT6
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_NONE
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_COLOR_ATTACHMENT7
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_NONE
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_DEPTH_ATTACHMENT
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_TEXTURE
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT: 3
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT: 0
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT: 0
    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT: 0
  }
  {
    GL_FRAMEBUFFER_ATTACHMENT: GL_STENCIL_ATTACHMENT
    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: GL_NONE
  }
}
4

1 回答 1

6

...在我为此苦苦挣扎了将近一周之后,我终于在 StackOverflow 上发布了这个问题后仅五分钟就想通了。发布我的解决方案,因为它似乎是一个可能会影响其他 OSX 人员的标题问题。

无论出于何种原因,在我的 64 位 OSX 构建中,GLenum 被定义为 8 字节整数类型,而 OpenGL 驱动程序实际上希望将数组中的 32 位值传递给 glDrawBuffers。如果我将代码重写为:

uint32_t buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(2,(GLenum*)buffers);  

然后一切都按预期工作。(GL_ZERO 条目的位置是最终导致我得到这个答案的提示)

于 2012-07-29T12:35:02.150 回答