opengl - glDrawBuffers 在 OS X 下用于多个渲染目标的用法

标签 opengl

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

我正在 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]

这本质上与this question中讨论的情况相同。 。但是,当我在 OS X 上运行此程序时,我的着色器仅输出到第一个渲染目标。无论是在构建具有两个颜色附件的 FBO 期间,还是在渲染过程中的任何时刻,OpenGL 都不会引发错误。

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

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

这也许可以解释为什么没有向GL_COLOR_ATTACHMENT1写入任何内容;它似乎在调用 glDrawBuffers 时被 GL_ZERO 取代!

如果我将 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);

然后统计 View 显示如下:

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“跟踪” View 将其显示为正在执行:

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

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

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

根据 OpenGL Profiler 的“资源” View ,我的帧缓冲区(编号 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
  }
}

最佳答案

...在我花了近一周的时间来解决这个问题后,我在最终将问题发布到 StackOverflow 上后仅五分钟就弄清楚了。发布我的解决方案,因为它似乎是一个可能会影响其他 OSX 用户的 header 问题。

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

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

然后一切都会按预期进行。 (GL_ZERO 条目的位置是最终引导我得出这个答案的提示)

关于opengl - glDrawBuffers 在 OS X 下用于多个渲染目标的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11709223/

相关文章:

c++ - OpenGL渲染黑色方 block

C++ switch 语句不起作用

java - Worldwind 自定义可渲染拾取问题

使用 GLEW、assimp、SDL2 和带有 CodeBlocks 的 CMake 的 C++ OpenGL 项目设置

opengl - 如何在opengl中渲染从一侧开始到另一侧的颜色渐变?

opengl - 什么是 OpenGL 中的阴影采样器以及它们的可能用途?

java - 计算模型照明的法线会导致模型不再渲染

c++ - opengl透明网格

c++ - 如何在 C++ 项目中编写着色器源代码?

c++ - 多个对象无法渲染?