(これは2013-05-11に書いた故OCNブログの記事を移植したものです)
以前書いた、「Effects11 for Windowsストア アプリ」の記事とは趣旨が逆行する話ですが、一応参考程度に書き残しておきます。デスクトップ アプリでは実行時コンパイルを使うこともできますが、いろいろ問題点(特にランタイム再配布に関するもの)があるので、極力実行時コンパイルは避けて、エフェクトやシェーダーのコンパイルには fxc.exe を使ってオフラインで行なうようにしておいたほうがいいです。
今回のサンプルは単純なコンソール アプリです。下記の環境で検証しています。
D3DEffectLoadTest.zip
- Visual Studio 2010 Pro SP1
- Visual Studio 2012 Pro Update2(プロジェクト ラウンド トリップ検証用)
- Windows SDK 7.1
- DirectX SDK June 2010
- Windows 7 Ultimate SP1 x64
- NVIDIA Quadro 600, Quadro 2000
- NVIDIA デスクトップ311.35グラフィックス ドライバー
昔(2010年頃)、Effects10を使っていたコードをEffects11に移行したときにハマったことがあったのですが、D3D10&D3DX10&Effects10と、D3D11&D3DX11&Effects11には細かい違いが結構あります。単純な置き換えでは済まない部分もあるし、紛らわしい部分もかなりあります。
Effects10 | Effects11 | |
---|---|---|
対応するDirect3D API | Direct3D 10.x | Direct3D 11.x |
使用可能なプロファイル名 | fx_4_0, fx_4_1 | fx_5_0 |
使用可能なテクニック | technique10 | technique10, technique11 |
外部ソースファイルからの直接生成 | D3DX10CreateEffectFromFile() | N/A |
メモリ上ソースファイルからの直接生成 | D3DX10CreateEffectFromMemory() | N/A |
ソースファイルのコンパイル | D3DX10CompileFromFile() | D3DX11CompileFromFile() |
コンパイル済みバイトコードからの生成 | D3D10CreateEffectFromMemory() | D3DX11CreateEffectFromMemory() |
特にまぎらわしいのが、下記2つです。
- D3DX10CreateEffectFromMemory()
- D3DX11CreateEffectFromMemory()
名前は似てますが、前者はメモリ上ソースファイルからのエフェクト生成、後者はメモリ上バイトコードからの生成であり、機能が全然違うので注意が必要です。
前者はFromSourceFileOnMemory()、後者はFromBytecodeOnMemory()にして欲しかった……
エフェクトのプロファイル名というのは、エフェクト ファイルをコンパイルするときに必要となるバージョンのようなもので、各シェーダーステージのプロファイル(vs_4_0やgs_5_0など)とは意味が異なります。fx_5_0を使っていても、vs_4_0_level_9_1などのダウンレベル プロファイルもきちんと使えます。
なお、D3DXはWindows SDK 8.0以降では廃止されていて、D3DCompilerランタイムもろともWindowsストア アプリ開発で使用できない(DLLをリンクするとストア アプリが起動できなくなる*1)ので、今後はできるかぎり使用を避けたほうが良いのですが、ディレクトリの優先順位を
Windows SDK 8.x>旧DirectX SDK June 2010
のように設定することで、Visual C++ 2012/2013コンパイラでもD3DXライブラリを補助的に使うことはできます。要するに、D3D9/D3D10.x/D3D11.xコア ライブラリはWindows SDK 8.xのものを使用して、D3DX9/D3DX10/D3DX11ライブラリは旧DXSDKのものを使うというわけです。これにより、デスクトップ アプリではD3D 11.1&D2D 1.1とD3DX11、もしくはD3D 11.2&D2D 1.2とD3DX11を共存させることも一応できます。
D3DX MathからDirectXMathへの移行は(演算子オーバーロードがなくなっていることを除いて)比較的簡単だと思います。DirectXTKのSimpleMathライブラリを使うとさらに簡単になるでしょう。D3DX TextureからDirectXTexへの移行も、互換機能がだいたい用意されているようなので、注意深く実装すれば大丈夫でしょう。しかし、D3DX Mesh/Sprite/EffectsなどからDirectXTKへの移行はかなり大変な作業になることが予想されます。代替機能がないものも多数あります。また、DirectXTKはD3D11専用で、D3D9/D3D10からは使用できません。実際にDirectXTex/DirectXTKへ移行するか、それともそれらに頼らずD3DXを自前のライブラリで置き換えるか、それを決めるまでの暫定的対処としてしばらくD3DXライブラリを使い続けるという手もあります。
ちなみにSMAAのソースに付属するDirect3D 10サンプルコードではEffects10を使っているのですが、FXLVM(Effects Language Virtual Machine?)が1か所だけ使用されています。Effects11はFXLVMをサポートしないので、移植しようとするとき変更が必要になります。
*1:D3DCompilerランタイムに関してはWindows 8.1ストア アプリにおいて制限付きながら利用できるようになりました。