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は、2つのカラーアタッチメントを使用したFBOの構築中、またはレンダリングプロセス中の任意の時点で、エラーをスローしません。

OSXの「OpenGLプロファイラー」の「トレース」ビューで何が起こっているかを調べると、このコード実行のドライバー側が次のように表示されます。

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

これはおそらく、何も書き込まれていなかった理由を説明してい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);

次に、統計ビューに次のように表示されます。

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

gl_FragColor[0]OpenGLはまだエラーをスローせず、シェーダーはとに書き込んでいても、両方のカラー添付ファイルにデータを正常に書き出しgl_FragColor[1]ます。

したがって、私のプログラムは現在機能していますが、これは機能しないはずです。そして、OpenGLを最終的な失敗に追いやることが教育的であることを期待して、これをどこまで推し進めることができるかを知りたいと思いました。だから私はこのコードでコンパイルしてみました:

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

これを実行すると、OpenGLプロファイラーの「トレース」ビューに実行中として表示されます。

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

そして今、OpenGLはあちこちに「無効なフレームバッファ操作」をスローしていますが、私のシェーダーはまだ両方のカラーアタッチメントポイントにカラーデータを正常に書き込んでいます。

これはすべて誰にとっても意味がありますか?私glDrawBuffersは、呼ばれることになっている方法を壊滅的に誤解しましたか?

OpenGL Profilerの「リソース」ビューによると、私のフレームバッファー(番号1)は正常に見えます。予想通り、2つのカラーアタッチメントが取り付けられています。

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

...そして、ほぼ1週間これに頭を悩ませた後、最終的に質問をStackOverflowに投稿してからわずか5分後にそれを理解しました. 他の OSX 関係者に影響を与える可能性があるヘッダーの問題と思われるため、私の解決策を投稿します。

なんらかの理由で、私の 64 ビット OSX ビルドでは、GLenum は 8 バイトの整数型として定義されていますが、OpenGL ドライバーは実際には glDrawBuffers に渡される配列内の 32 ビット値を必要としています。コードを次のように書き直すと:

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

その後、すべてが期待どおりに機能します。(GL_ZEROエントリの配置は、最終的にこの答えにつながるヒントでした)

于 2012-07-29T12:35:02.150 に答える