前回は NV_DX_interop 拡張で OpenGL と DirectX9 のリソース共有でした。
今回はその後続の拡張である NV_DX_interop2 を試してみたいと思います。
こちらは DirectX10 以降のリソースに対応しているようです。そこで DirectX11 と OpenGL でのリソース共有を実験してみます。
WGL_NV_DX_interop2
この WGL_NV_DX_interop2 拡張は名前の通り NVIDIA のベンダー拡張として定義されています。
詳しい説明は OpenGL Registry の https://www.opengl.org/registry/specs/NV/DX_interop2.txt を参照してください。
DirectXのリソースのうち ID3D11Texture1D/2D, ID3D11Buffer らについて OpenGL と共有が可能であるとなっています。
リソースの準備
DirectX9 の時に比べると若干簡単になっています。
DirectX11でのリソースと対応するOpenGL側での ID を用意して、 wglDXRegisterObjectNV を呼び出します。
テクスチャならば以下のようになります。
glGenTextures(1, &texId ); ID3D11Texture2D* pTextureD3D11; hSharedHandle = wglDXRegisterObjectNV(..., pTextureD3D11, texId, GL_TEXTURE_2D, WGL_ACCESS_READ_WRITE_NV);
DirectX11 側のレンダーターゲットを共有する場合でも ID3D11Texture2D* を設定することになる点が若干の注意でしょうか。
つい ID3D11RenderTargetView を設定しそうになりますが、あくまでテクスチャを共有です。
OpenGL でも FBO(FramebufferObject) を設定していないで、テクスチャのID を指定しているし、同じと言えば同じでしょうか。
描画
前回と同様、 DirectX11 で描画するフェーズ、 OpenGL で描画するフェーズの境目で、リソースにロックをかけて同期をとるような仕組みです。
DirectX11 の処理の末尾では Flush() を呼び出しておくことが必要となるようです。
// DirectX11 による描画処理 renderDX11(); wglDXLockObjectsNV( ..., hSharedHandles ); // OpenGL による描画処理 renderGL(); wglDXUnlockObjectsNV( ..., hSharedHandles );
以下に実験プログラムの結果を示します。最終的な画面描画は OpenGL で行ってみました。
中のキューブが回っている部分について DirectX11 でテクスチャにレンダリングしたものです。
回転しているポリゴン板は OpenGL で処理しています。
今回の動作環境は Windows10 (x64), GeForce 650 Ti のもので試しています。
まとめ
前回に引き続き OpenGL DirectX の Interop を実験してみました。
OpenGL と DirectX のリソース共有はなかなか面白いですね。
今回の NV_DX_interop2 は今のところ NVIDIA ボードでしかサポートしていないようなので、ちょっと残念ですね。