我的多重渲染目标代码中有一些非常奇怪的行为,并开始怀疑我是否会灾难性地误解了这应该起作用的方式.
我正在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)
...在对付了这个将近一个星期之后,我终于在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条目的位置是最终导致我得到这个答案的提示)