DirectX一覧

DirectXのデバッグランタイム不具合

Windows7 (x64)の環境で、DirectX9を用いた開発を行おうとすると、
SDKのバージョンによっては問題を引き起こすことがわかった。検索しても海外でしか、同じ症状が発見されず、また解決法も不明だったので、
問題のあるバージョンを使用しない方法でしか解決が出来ないようだ。
それでも、別バージョンを使えばOKという点はまだ救いなのかもしれない。

問題

Windows7(x64)において、DirectX9のデバッグランタイムを有効にすると、
CreateDeviceで失敗する。
そのときのエラーメッセージは次の通り。

コメントもらったので修正
試したのは全て、Windows7(x64)環境下です。
x86環境では問題が起こらないのかもしれません。
どうやらx86,x64環境ともに発生するようです。

SDKバージョン 使用可否 Windows仕様
2008Nov 使用不可能 Win7(x64)
2009Mar 使用不可能 Win7(x64)
2009Aug 使用可能 Win7(x64)
2010Feb 使用可能 Win7(x64)

 

まとめ

このような結果になったので、Windows7環境でまともに使おうと思っても、
古すぎるSDKは使いにくい。2009Augがいいところだろうか。


R2VB

どうやら最近のNVIDIAドライバ+新しめのボードだと、
R2VB(Render To VB)は使えないようだ。チェックしてみてもNGとなってしまう。
これってGeForce6200とかで使えたという噂を聞いたけど、
そのくらい昔のハードでしか使えないってことなんだろうか。

※ R2VB使うくらいなら DirectX10以降のストリームアウト使えってことか

DirectX9で、ストリームアウトはあきらめろということで結論かも。
OpenGLならエクステンション駆使して何とかできるのかもしれない。


今日のトラブル

原因不明。IDIRECT3DDEVICE9のSetVertexShaderConstantF関数で設定した値が、シェーダーに送られてない。
一方で、D3DXのID3DXCONSTANTTABLEで設定すると値はきちんと送られている。

なぜだー。

これのせいで数時間もアルゴリズムの方が間違っているのかと悩んでた。

現在ダウンサンプリングを勉強中


SkinnedMeshで複数描画したい

DirectXのサンプルSkinnedMeshをいじって、
リソースは1つ、描画用インスタンスは複数なんてものを作成してみました。 

色々と、DirectXの仕様で躓く点が多かったように思います。

実現の為のポイント

  • AnimationControllerは単純にCloneで作成しても、ボーン構造(FRAME)は共有されてしまう
    • 独立させたいのは、マトリックスパレット.
    • 一緒にボーンオフセット行列もインスタンスごとに保持させてしまうと、楽にはなる。
  • マトリックスパレットは、MeshContainerが保持するのではなく、一段外に追いやってみる。
    • 自分では FRAMEの中に追い出しました。MeshContainerと並列して存在する感じに。

このような点から、
描画用のオブジェクト生成時には、

  • FRAME構造をコピー(別インスタンス作成)
  • AnimationControllerをcloneする
  • 上記でそれぞれ描画用のインスタンス用としてのデータができたので、関連づける.
    • D3DXFrameRegisterNamedMatrices()を使用する

これで画像のようにインスタンスごとにアニメーションデータを持った感じで
描画ができるようになりました。

面倒といえば面倒なので、要望があったらlib化してしまうかも。


DirectXのテクスチャについて

メモリ管理やUSAGEの組み合わせで気になったので調査.

生成時フラグ

D3DPOOL D3DUSAGE 結果
Default 0 OK
Default WRITEONLY NG
Default DYNAMIC OK
Managed DYNAMIC NG
SystemMem DYNAMIC OK
Default DYNAMIC RENDERTARGET OK
Default RENDERTARGET OK

ロック時フラグ

タイプ ロック手法 結果
Default&Dynamic&&RenderTarget 0 NG
Default&RenderTarget 0 NG
Default&RenderTarget D3DLOCK_READONLY NG
Default&Dynamic&&RenderTarget D3DLOCK_DISCARD NG
Default&RenderTarget D3DLOCK_DISCARD NG
Default&Dynamic D3DLOCK_READONLY OK
Default&Dynamic D3DLOCK_DISCARD OK
SystemMem&Dynamic D3DLOCK_READONLY OK
SystemMem&Dynamic D3DLOCK_DISCARD OK

感想

意外だったのは SystemMemでDynamicタイプを作れること。

それでもSystemMemでRenderTargetは無理でしたが(当たり前)。


インターフェース変更

DirectXのヘッダを見ていて気付いたこと。
同名のIIDで、値だけ違うってまずいんじゃないだろうか。

DEFINE_GUID(IID_ID3DXEffect,
0xd165ccb1, 0x62b0, 0x4a33, 0xb3, 0xfa, 0xa9, 0x23, 0x0, 0x30, 0x5a, 0x11);

DEFINE_GUID(IID_ID3DXEffect,
0xf6ceb4b3, 0x4e4c, 0x40dd, 0xb8, 0x83, 0x8d, 0x8d, 0xe5, 0xea, 0xc, 0xd5);

確かにメソッドの数が違うから新しいIIDにするのは納得がいくのだけども、こんなことして、平気なのかな?と思う。もしや、こういう強引なことを出来るようになったのも、対応するd3dx_**.dllが分かっているから、なのか?

だれか情報知っていたら教えて欲しいです。

 


D3DXCreateEffectについて – CompileEffect

マクロで有効・無効のブロックを切り替えるにはどうしたらいいんだーということで調べてました。
ピクセルシェーダーコードでは、以下のようにして挙動をチェックしていました。

[code lang=”cpp”]
#ifdef _TEST_
return float4(1,1,1,1);
#else
return float4(0,0,1,1);
#endif
[/code]

これをEffectでやるのにネックだったのは、マクロ定義変数の部分でした。

解決策はこう。

[code lang=”cpp”]
D3DXMACRO d3dxMacros[2] = { //マクロ マクロ名
"_TEST_","", <– ここで定義する部分を設定して
0, 0 <– ここで終端を示すようにヌルターミネートしておく
};
[/code]

通りでマクロの設定長を示す引数がないわけだ。

探してみてもこの辺でつまずく人はいないのか、記述が見あたらず。
また、ほとんどの場合このマクロ設定部分NULLにしちゃうし、使う状況ってないのかなぁ。

自分では多用していこうと思っていますが。


スキニング問題

前からやっていたスキニング、前回までの結果ではうまくできないことが判明し、もがいてます。

出来ないのは下記の理由により。

  •  SkinedMeshサンプルではマトリックスパレットに設定している値そのものがワールドになっている。
  •  結果、ライト位置をモデル空間に変換しただけではNG (全てをワールドでやればOKでしょうが…)

というわけで、スキンメッシュの表示方法そのものを変更しようかと。
点光源にチャレンジしていなかったら、上記の問題点に気付かずに放置していただろうなーと思うと運が良かったのかな。

 


DirectXのロックの謎

DirectX9のLockについて、調べてみたことをメモしておきます。

Textureのロックには、範囲指定があるが、Lockは複数回できるのか?

まずは推測から。
範囲指定がわざわざあるということは、部分1でLockし、部分2でLockしても問題なさそうである。また、領域が重なった場合は多重ロックになりNGとなる。と予想。

結果は・・・領域が被っていようが、別部分であろうがNGでした。どうやら、範囲指定はパフォーマンスをあげるためのダーティー判断くらいでしかなさそう。ただし、異なるミップマップについては同時Lockは可能のようです。

 

VertexBufferのロックはどうだろうか?

テクスチャが上記のような結果になったのだから、やはり多重ロックは失敗するだろうと予想。あるいはNO_OVERWRITEフラグなんかあるし、領域さえ違えば成功するのかも知れない。

結果は・・・領域が被っていようが、別であろうが、多重ロックは成功する。多重ロック後は、正しくUnlock呼ばないといけないそうです。

このロックの挙動の違いは問題になりそう…。そもそも多重ロックを許可しない方針でプログラムを作っていくべきかも知れません。

上記を試したのは、DirectX9.0cで、GeForce7600GT on Vista(x64)です。他のメーカーのカードでは異なる結果となるかも知れません。 次は、OpenGLのMapBufferとか調べてみる?!

 


XSI ModToolからスキニングメッシュ出力

スキニングメッシュとして、円柱にボーンを仕込んだものを作ってみました。

適当に曲げてみて、それを独自形式変換して表示できるかやってみたのですが、失敗してしまい、 tiny.xからの作った場合には正常に表示できているのですが。

うまく出す方法判明

いくつか試してようやく解法がわかりました。
DirectXのエクスポーターの設定で CompressMeshにチェックが入っているとダメのようです。

また、Trianglateにチェックを入れても豪快に崩れました。
このことから、素直に .xを作り、やるならその後最適化をするという流れをとった方が良さそうです。