在OS X下,glDrawBuffers用于多个渲染目标

Tre*_*ell 5 opengl

我的多重渲染目标代码中有一些非常奇怪的行为,并开始怀疑我是否会灾难性地误解了这应该起作用的方式.

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

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(2,buffers);  
Run Code Online (Sandbox Code Playgroud)

然后我的着色器将颜色数据写入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});
Run Code Online (Sandbox Code Playgroud)

这或许可以解释为什么没有写入GL_COLOR_ATTACHMENT1; 它似乎正在被GL_ZERO召唤中取代glDrawBuffers!

如果我将buffers[]数组中缓冲区的顺序切换为GL_COLOR_ATTACHMENT1_EXT第一个然后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);
Run Code Online (Sandbox Code Playgroud)

然后统计视图显示:

0.46 µs glDrawBuffersARB(3, {GL_COLOR_ATTACHMENT0, GL_ZERO, GL_COLOR_ATTACHMENT1});
Run Code Online (Sandbox Code Playgroud)

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

所以即使我的程序现在正在运行,在我看来这样做也不行.我很想知道我能推动多远,希望将OpenGL推向最终的失败将是有教育意义的.所以我尝试用这段代码编译:

GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(4, buffers);
Run Code Online (Sandbox Code Playgroud)

运行时,OpenGL Profiler"跟踪"视图显示正在执行:

4.26 µs glDrawBuffersARB(4, {GL_COLOR_ATTACHMENT0, GL_ZERO, GL_COLOR_ATTACHMENT1, GL_ZERO});
Run Code Online (Sandbox Code Playgroud)

而且现在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
  }
}
Run Code Online (Sandbox Code Playgroud)

Tre*_*ell 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);  
Run Code Online (Sandbox Code Playgroud)

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