OpenGL では Draw Indirect 系が充実しているとの情報があったので、DirectXとどのように違うのかを調べてみました。
DirectX 11 では、 DrawInstancedIndirect(), DrawIndexedInstancedIndirect() の2つの関数が DrawIndirect系として使用可能です。DirectX10では DrawAuto() という関数が存在して、DirectX11ではこれを汎用化して上記の関数群となったようです。
上記の関数はインデックスバッファ有・無しの違いで分かれているだけで、インスタンス描画を考慮するもののそれ以上の機能は持っていないようです。
一方で OpenGL の Draw Indirect 系は次の関数が用意されています。
- glDrawArraysIndirect()
- glDrawElementsIndirect()
- glMultiDrawArraysIndirect()
- glMultiDrawElementsIndirect()
ちなみに、glMultiDrawArraysIndirect() は、複数回の glDrawInstancedIndirect() を1回の呼び出しとするようなものです。また glDrawArraysIndirect() が DrawInstancedIndirect() に相当するようです。Indirectのバッファの中には、インスタンス数を指定する項目も含まれるようです。
複数回の描画を束ねられる glMultiDrawArraysIndirect ですが、結局のところ CPU 側に描画数を通知しておく必要があります。そこが何ともうまくないところですが、ARB_indirect_parameters という拡張でこの対策がおこなわれているようです。
ARB_indirect_parameters では、インスタンス数を格納しておくためのバッファが追加サポートされるようになります。そのバッファが GL_PARAMETER_BUFFER というもので、GLsizei のデータを入れておく入れ物となっています。関数としては、glMultiDrawArraysIndirectCount, glMultiDrawElementsIndirectCount となっています。