Waterサンプルをビルドする

ふと水面のシミュレーションをしてみようを思い立ち、偶然にもちょうどいいサンプルがあるということを以下のページで発見した。
3D エフェクトのスクリプティング〜 Cutting Edge DX 8 - 第 2 回目 〜
DirectX 8のころのサンプルのようで、サンプルだけでも配布していないか探したところ、MSDN DirectX 9 サンプルの項にWaterサンプルがあるのを確認。
しかし、Directx 9.0c SDK (March 2008)には含まれていなかった。


その後調べた結果DirectX SDK ダウンロードページにある、DirectX 9.0b SDK (2002)に含まれていることがわかった。(さらに新しいバージョンに含まれているかも知れないが)


推測だけど、9.0のSDKから8時代のものを排除して、10へ置き換えていく過程でサンプルも整理したのかな。


今回はDirectX 9.0b SDK (2002)をインストールせずに、展開しただけの状態でビルドします。
Directx 9.0c SDK (March 2008)などそれ以降のバージョンでビルドするってことですね。

プロジェクトの変換とビルド

無事サンプルを発見することができたので、プロジェクトをVC++2008用に変換してビルドする。
ちなみにVisual C++ 2008 Express Editionです。
プロジェクトは6と7(.NET 2002?)が用意してあったので、7をVC++2008で開き、そのまま[完了]を押して変換を終了する。変換は問題なし。


続いてビルド。
今回Warningは無視。
エラーは大きく分けて5点ほどの修正で済むはずです。

  • error C2051: case 式は、整数型定数でなければなりません。 c:\development\sdk\temp\sdk (c++)\samples\c++\common\src\d3dapp.cpp 1582


筆者環境ではHRESULT_FROM_WIN32がインライン関数として定義されていたため、これをマクロに置き換えます。
SDK(C++)\Samples\C++\Common\Src\d3dapp.cpp 1582行


case HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ):

case __HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ):

  • fatal error C1083: include ファイルを開けません。'rmxfguid.h': No such file or directory c:\development\sdk\temp\sdk (c++)\samples\c++\common\src\d3dfile.cpp 14


インストールしたSDKには含まれないヘッダがあるので、それらのみ相対パスで指定してあげます。
SDK(C++)\Samples\C++\Common\Src\d3dfile.cpp


#include
#include

#include "..\..\..\..\Include\rmxfguid.h"
#include "..\..\..\..\Include\rmxftmpl.h"

  • fatal error LNK1104: ファイル 'd3dx9dt.lib' を開くことができません。 Water
  • error C2664: 'D3DXLoadMeshFromXof' : 1 番目の引数を 'LPDIRECTXFILEDATA' から 'LPD3DXFILEDATA' に変換できません。(新しい機能 ; ヘルプを参照) c:\development\sdk\temp\sdk (c++)\samples\c++\common\src\d3dfile.cpp 151


VisualC++でDirectX9は大変を参考にさせていただきました。


まず追加の依存ファイルのd3dx9dt.libをDebug(ソリューション構成)でd3dx9d.lib に置き換えてください。
Releaseはなにもしなくていいです。
次にSDK(C++)\Samples\C++\Common\Include\d3dfile.h にdxfile.hをインクルード
そしてSDK(C++)\Samples\C++\Common\Src\d3dfile.cpp CD3DMesh::Create内のpFileDataをLPD3DXFILEDATAにキャスト


d3dfile.h〜〜〜
#include
#include
〜〜〜


d3dfile.cpp〜〜〜
// Load the mesh from the DXFILEDATA object
if( FAILED( hr = D3DXLoadMeshFromXof( pFileData, D3DXMESH_SYSTEMMEM, pd3dDevice,
&pAdjacencyBuffer, &pMtrlBuffer, NULL,
&m_dwNumMaterials, &m_pSysMemMesh ) ) )
〜〜〜


d3dfile.h〜〜〜
#include
#include
#include
〜〜〜


d3dfile.cpp〜〜〜
// Load the mesh from the DXFILEDATA object
if( FAILED( hr = D3DXLoadMeshFromXof( (LPD3DXFILEDATA)pFileData, D3DXMESH_SYSTEMMEM, pd3dDevice,
&pAdjacencyBuffer, &pMtrlBuffer, NULL,
&m_dwNumMaterials, &m_pSysMemMesh ) ) )
〜〜〜

  • error C2039: 'Pass' : 'ID3DXEffect' のメンバではありません。 c:\development\sdk\temp\sdk (c++)\samples\c++\direct3d\water\water.cpp 748


DirectX9.0c Direct3D Tips 第1回「 頂点テクスチャによるディスプレースメントマッピング : Displacement Mapping」を参考にさせていただきました。
ID3DXEffectの9.0cでの変更について注目した記事です。


Water.cpp 748行


m_pEffect->Pass(uPass);
m_Water.DrawSurface();

m_pEffect->BeginPass(uPass);
m_Water.DrawSurface();
m_pEffect->EndPass();
あってるのかな?とりあえず動かすことが目標なのでいつか見直すとします。

  • fatal error CVT1100: duplicate resource. type:MANIFEST, name:1, language:0x0409 CVTRES
  • fatal error LNK1123: COFF への変換中に障害が発生しました: ファイルが無効であるか、または壊れています。 Water


http://forum.minidx.com/thread-8-1-1.htmlから引用

アプリケーションウィザードで"Add Common Control Manifest"のチェックを外す、
もしくはプロジェクトのプロパティ→構成プロパティ→マニフェストツール→入力と出力→埋め込みマニフェストを”いいえ”に設定すると解決出来ます。(−−)!

とのこと。
もしくは、
winmain.rcの27行目をコメントアウト


CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "Water.manifest"

//CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "Water.manifest"
リソースファイルと構成のプロパティ双方でマニフェストを埋め込む設定になっていたためですかね。
前者の場合は、Debug、Release双方の設定を変更する必要があります。


ビルドできたら実行ファイルをSDK (C++)\Samples\Mediaに持っていけば、ちゃんと走るはずです。
デバッガで起動したら起こられました。データが見えないんですね。