ページ 11

スレ立てるまでもない質問

Posted: 2010年10月26日(火) 20:26
by Ciel
こちらのスレッドにはスレッドを立てるほどでもないと思った、単純な質問を投稿して下さい。

その判断は個人に任せます。

【質問例】
Q.現在のDirectX SDKの最新バージョンって何ですか?
など。

Re: スレ立てるまでもない質問

Posted: 2010年12月31日(金) 06:41
by ホヅミ
ふと疑問に思ったので投稿させていただきます
DirectX9以降、DirectX10、DirectX11
今現在この中で一番多く使われているものって何でしょうか?
とくに9と10の使用はまったく別物だそうで(ネット情報の受け売り^^;
しかしXPユーザーもまだまだ生き残っているようです
参考までに聞かせてください

Re: スレ立てるまでもない質問

Posted: 2010年12月31日(金) 15:07
by あたっしゅ
ここで多く使われている DxLib が DirectX 9 対応なので、ここでは DirectX 9 が多く使われていますかね。

p.s. DxLib でつくってるゲームが Ubuntu 上の Wine で動いた。

Re: スレ立てるまでもない質問

Posted: 2011年1月01日(土) 17:47
by ああ
ネットに公開されてる情報は、DirectX9が多いですね。

ただしMicrosoftが旧バージョンのサポートをどんどんしなくなっているので、出来るだけ最新の物でやった方が良いと思われます、

自分も質問なんですが、DirectXで開発した場合、環境依存を解決して作品を公開するにはどうしたら良いんですかね?
ずっとWin32APIで作っていたんで、Releaseモードで吐き出せば良いやと思っていましたが、DirectXはそんな単純なものじゃないみたいですね^^;

Re: スレ立てるまでもない質問

Posted: 2011年1月01日(土) 18:13
by Ciel
>>NNKさん

作成したDirectXのバージョンを記載しておいて、ビデオカードもそのバージョン対応のものを
使ってくださいって書いておき、最新のラインタイムをインストールしておいてくださいって、
書いておけばよいのではないでしょうか?

ビデオカードの違いによる、細かなエラーを避けるには、事前のビデオカードの性能を調べておいて、
それぞれのビデオカードの性能に応じた処理をさせるしかないのではないでしょうか?

恐らくDirect9で開発していれば、最近のPCであればほぼ問題なく動くとは思いますけどねぇ。。。

Re: スレ立てるまでもない質問

Posted: 2011年1月01日(土) 18:25
by ああ
>>Ciel さん

自分の「最後に!」って日記のコメントを見て頂ければ解ると思いますが、なんとOSがVista以降のPCでも動作しない方が多くて・・・。
DirectX9で開発したんですけどね。
恐らくビデオカードの問題ではないと思いますが、もしからしたら自分のプログラムに問題があるかも知れませんが・・・。
もうちょっと調べてみます。

Re: スレ立てるまでもない質問

Posted: 2011年1月03日(月) 01:33
by ホヅミ
DirectX11まで出ているにもかかわらずDirectX9安定だったとは・・・
ありがとうございますー

Re: スレ立てるまでもない質問

Posted: 2011年1月03日(月) 01:58
by ISLe
梨丸かじり さんが書きました:DirectX11まで出ているにもかかわらずDirectX9安定だったとは・・・
10,11はVista以降でしか動きませんから、完全移行するとまだ60%以上いると言われるXPユーザーを切り捨てることになります。

Re: スレ立てるまでもない質問

Posted: 2012年2月18日(土) 11:11
by Fimbul
DirectX9のライブラリの
・d3dx9.lib (リリース版)
・d3dx9d.lib (デバッグ版)
この二つについて。

この組合せのライブラリは、バージョンを問わずありますよね。
それぞれ、リリース版、デバッグ版、だと聞いたのですが、何が違うんでしょうか。

また、前から気になっていた事でDirectXの「D3D」はDirect3Dの略だと思うんですが、「D3DX」は何の略なのでしょうか。
「D3DX」は拡張機能ライブラリだと聞いたので、「Direct3D eXtend」当りの略だと私は思ったのですが。

Re: スレ立てるまでもない質問

Posted: 2012年2月18日(土) 17:41
by ISLe
Fimbul さんが書きました:それぞれ、リリース版、デバッグ版、だと聞いたのですが、何が違うんでしょうか。
一般的な話になりますが、デバッグ版にはソースコードデバッグ用のシンボルが含まれていたり、診断用のトレースメッセージを出力するコードが含まれていたり、実行コードの最適化が行われていなかったりします。
なのでデバッグ版は問題箇所の発見に役立つ代わりに実行速度が遅いです。
Fimbul さんが書きました:「D3DX」は拡張機能ライブラリだと聞いたので、「Direct3D eXtend」当りの略だと私は思ったのですが。
公式の記述は無いみたいですがたぶんそうでしょうね。
ヘッダファイルにもD3DXとしか書かれてませんね…。

Re: スレ立てるまでもない質問

Posted: 2012年2月18日(土) 18:41
by Fimbul
ISLe さんが書きました:デバッグ版は問題箇所の発見に役立つ代わりに実行速度が遅いです。
普段はデバッグ版を用いて、リリースビルドの時にリリース版を用いるのが無難なのでしょうか。
ISLe さんが書きました:公式の記述は無いみたいですがたぶんそうでしょうね。
公式にも無いんですね。ですが、すっきりしました。

Re: スレ立てるまでもない質問

Posted: 2012年2月19日(日) 01:13
by ISLe
Fimbul さんが書きました:普段はデバッグ版を用いて、リリースビルドの時にリリース版を用いるのが無難なのでしょうか。
無難という言葉の意図が分からないですが。

マイクロソフトの開発製品(無償配布のSDK含む)はライセンス上、デバッグ版ライブラリの配布が許可されていません。
なので、デバッグビルドした実行形式を他人に渡すこともできません。

開発中は、デバッグ版でバグの原因究明して、リリース版でテストプレイします。繰り返しです。
配布するのはリリース版です。
というふうに使い分けるのが一般的だと思います。

Re: スレ立てるまでもない質問

Posted: 2012年2月19日(日) 10:27
by Fimbul
ISLe さんが書きました:マイクロソフトの開発製品(無償配布のSDK含む)はライセンス上、デバッグ版ライブラリの配布が許可されていません。
なので、デバッグビルドした実行形式を他人に渡すこともできません。
と言う事は、掲示板で質問等をする時にライブラリを一緒にアップ出来ないんですね・・・

Re: スレ立てるまでもない質問

Posted: 2012年2月19日(日) 17:28
by ISLe
Fimbul さんが書きました:
ISLe さんが書きました:マイクロソフトの開発製品(無償配布のSDK含む)はライセンス上、デバッグ版ライブラリの配布が許可されていません。
なので、デバッグビルドした実行形式を他人に渡すこともできません。
と言う事は、掲示板で質問等をする時にライブラリを一緒にアップ出来ないんですね・・・
本当はそうなんですよね。
SDK丸ごとなら再配布が許可されているものはありますけど、開発環境は相手側で用意してもらうことになります。

Re: スレ立てるまでもない質問

Posted: 2012年2月20日(月) 21:20
by Fimbul
ISLeさん返信ありがとうございました。
また、違う質問をさせてください。

3Dモデルの描画の話です。

1 モデルの描画をPeekMessageでメッセージ処理がない時に行う
2 モデルの描画をWM_TIMERやWM_PAINTで行う(PeekMessageでなくGetMessageを使う)

どちらがいいんでしょうか。

[追記]
WM_PAINTは無効領域が生じたら発行されると聞きました。
ですが、DirectXではウィンドウを隠したりWM_TIMERでInvalidateRect等を呼び出さなくても発行されている気がします。
モデルやカメラ、ライトを操作したりするとWM_PAINTが発行されるのでしょうか。

Re: スレ立てるまでもない質問

Posted: 2012年2月20日(月) 23:51
by ISLe
Fimbul さんが書きました:3Dモデルの描画の話です。

1 モデルの描画をPeekMessageでメッセージ処理がない時に行う
2 モデルの描画をWM_TIMERやWM_PAINTで行う(PeekMessageでなくGetMessageを使う)

どちらがいいんでしょうか。
3Dモデル描画とか関係なしに、精度の高いタイミング(正確なフレームレートとか)を得たいなら前者ですね。
精度が悪くても負荷を低くしたいならウィンドウメッセージを使うのもありだと思います。
Fimbul さんが書きました:WM_PAINTは無効領域が生じたら発行されると聞きました。
ですが、DirectXではウィンドウを隠したりWM_TIMERでInvalidateRect等を呼び出さなくても発行されている気がします。
モデルやカメラ、ライトを操作したりするとWM_PAINTが発行されるのでしょうか。
断言はできませんが、Direct3DのAPIで無効領域が発生することはないと思います。

ウィンドウプロシージャでWM_PAINTに対してBeginPaint,EndPaintを呼ばずにリターンすると無効領域がクリアされないままなのでWM_PAINTがいつまでも発行され続けますけど。
WM_PAINTに対してBeginPaint,EndPaintを呼び出して戻り値0でリターンするか、ハンドリングしないでDefWindowProcを呼び出してそのまま戻り値とするかどちらかが必須です。
Direct3Dを使うプログラムなら後者ですね。背景ブラシもNULLにして。

Re: スレ立てるまでもない質問

Posted: 2012年2月21日(火) 20:10
by Fimbul
ISLe さんが書きました:ウィンドウプロシージャでWM_PAINTに対してBeginPaint,EndPaintを呼ばずにリターンすると無効領域がクリアされないままなのでWM_PAINTがいつまでも発行され続けますけど。
WM_PAINTに対してBeginPaint,EndPaintを呼び出して戻り値0でリターンするか、ハンドリングしないでDefWindowProcを呼び出してそのまま戻り値とするかどちらかが必須です。
Direct3Dを使うプログラムなら後者ですね。背景ブラシもNULLにして。
DefWindowProc に処理を渡したら無事にWM_PAINTは発行されなくなりました。

背景ブラシもNULLにしましたが、これは何のためなんでしょうか。

また、ウィンドウを表示させて何もしなくてもなぜかWM_PAINTが発行されてました。
ウィンドウを表示した直後に無効領域が生じるか、WM_PAINTが発行されるようになっているのでしょうか。

Re: スレ立てるまでもない質問

Posted: 2012年2月22日(水) 02:17
by ISLe
Fimbul さんが書きました:背景ブラシもNULLにしましたが、これは何のためなんでしょうか。
Direct3Dを使って描画する場合はハメコミ合成状態なので、ウィンドウのクライアント領域は隠れています。
なのでGDIでクライアント領域に描画するのは無駄です。

WM_PAINTのハンドラでBeginPaintを呼ぶと、WM_ERASEBKGNDがSENDされて背景ブラシでクライアント領域が塗り潰されます。
ウィンドウの背景ブラシをNULLにすると(デフォルトの)塗り潰しが行われないので無駄を減らせるというわけです。

ちなみにWM_ERASEBKGNDをハンドリングして戻り値1でウィンドウプロシージャを抜けるようにすれば背景を好きなように描画できます。
Fimbul さんが書きました:また、ウィンドウを表示させて何もしなくてもなぜかWM_PAINTが発行されてました。
ウィンドウを表示した直後に無効領域が生じるか、WM_PAINTが発行されるようになっているのでしょうか。
ウィンドウアプリではWM_PAINTをハンドリングしてクライアント領域に対する描画を行います。
ウィンドウが最初に表示されるときにはもちろんクライアント領域が描画されなければならないので、最初はクライアント領域全体が無効領域です。
なのでクライアント領域が見えないからといってWM_PAINTを処理しないでおくとウィンドウを開いたときからずっと発行され続けることになります。

Re: スレ立てるまでもない質問

Posted: 2012年2月22日(水) 20:47
by Fimbul
ISLe さんが書きました:ウィンドウが最初に表示されるときにはもちろんクライアント領域が描画されなければならないので、最初はクライアント領域全体が無効領域です。
なのでクライアント領域が見えないからといってWM_PAINTを処理しないでおくとウィンドウを開いたときからずっと発行され続けることになります。
そういうことだったんですね。

新しい質問をさせてください。
BeginSceneとEndSceneについてです。

この二つは描画開始宣言と描画終了宣言であり、この間で描画を行わなければならないと良く聞きます。
また、BeginSceneとEndSceneの間は他のスレッドを停止させて描画に専念しているので、BeginSceneとEndSceneの間で処理に時間がかかる事を行ってはならないと聞きました。

ですが、FVFのDrawPrimitiveやメッシュのDrawSubsetをBeginSceneの前で行っても描画されます。
さらに、BeginSceneとEndSceneの間でモデルやカメラ、ライトの計算を行っているコードを良く見ますが、これもBeginSceneより前で行っても処理されます。
しかし、BeginSceneとEndSceneを消したら描画はされなくなりました。

ならば諸々の計算をした後、描画をして、BeginSceneとEndSceneはただ呼び出すだけで、この間は何もしない方がいいような気がします。

コード:

/*良く見る方法*/

//BeginScene

//モデルやカメラ、ライトの計算(移動とか)

//モデルの描画(DrawSubsetとか)

//EndScene

コード:

/*私が思った方法*/

//モデルやカメラ、ライトの計算(移動とか)

//モデルの描画(DrawSubsetとか)

//BeginScene

//EndScene

この二つの方法どちらが良いのでしょうか。
また、BeginSceneとEndSceneの本当の役割はなんでしょうか。
私が思った方法で描画がされるので、描画の開始終了宣言ではないと思うのですが・・・。

Re: スレ立てるまでもない質問

Posted: 2012年2月22日(水) 23:37
by ISLe
3Dの描画はGPUが行いますが、高速に処理するために、プログラムが発行した命令をそのまま実行するとは限りません。

BeginScene~EndSceneは一連の命令をGPUにプッシュするための指示です。
このあいだ描画に専念しているというのはまったくのデタラメですね。
EndSceneで締め切られた後、バッファがデバイス画面に表示されるまでのあいだに描画されます。

実際にどのように動作するかはGPU側の実装によりますが、GPU側にとっては命令がバラバラに送られるより、まとめて送られたほうが最適化しやすく、BeginScene/EndSceneはひとまとまりであることを示すための目印となります。

BeginScene~EndSceneのあいだにカメラやライトを変更すると最適化の邪魔になってパフォーマンスに少なからず悪影響を与えると思います。
実測しないと分からないですし環境によっても異なるでしょうが。

Re: スレ立てるまでもない質問

Posted: 2012年2月23日(木) 18:01
by Fimbul
ISLe さんが書きました:実際にどのように動作するかはGPU側の実装によりますが、GPU側にとっては命令がバラバラに送られるより、まとめて送られたほうが最適化しやすく、BeginScene/EndSceneはひとまとまりであることを示すための目印となります。
これからは、BeginSceneとEndSceneの間で描画する様にします。
ISLe さんが書きました:BeginScene~EndSceneのあいだにカメラやライトを変更すると最適化の邪魔になってパフォーマンスに少なからず悪影響を与えると思います。
前私が書いた方法ですが、複数のモデルの移動を考えていませんでした。
複数のモデルを動かそうとすると、モデルのワールド座標の計算はBeginSceneの前で行い、SetTransformでの設定はBeginSceneの間で行う事になりますよね。
ただ、マテリアルやテクスチャを変えたり、FVFで描画するためにライトを無効する処理はどうしても描画したいモデルの直前(BeginSceneとEndSceneの間)で行う必要があると思います。
これは、仕方がないのでしょうか。

あと、ポイントスプライトについて質問があります。
ポイントスプライトのサイズを0.3fぐらいに設定して、2つのポイントスプライトを描画して異なるテクスチャを貼りました。
しかし、ポイントスプライトのZ座標を大きくした時に、なぜか物体の見かけの大きさは変わりませんでした。
例えば、カメラの位置は(0, 0, -30)、注視点は原点、上向きベクトルはy方向だとして、(10, 0, 0)の位置の物体が奥に移動する(Z座標の値が大きくなる)と物体の見かけの位置が画面の中心によってきますが、これはポイントスプライトでも生じました。
なぜポイントスプライトの見かけの大きさが変わらないんでしょうか。

Re: スレ立てるまでもない質問

Posted: 2012年2月23日(木) 21:45
by ISLe
Fimbul さんが書きました:ただ、マテリアルやテクスチャを変えたり、FVFで描画するためにライトを無効する処理はどうしても描画したいモデルの直前(BeginSceneとEndSceneの間)で行う必要があると思います。
これは、仕方がないのでしょうか。
先の返信にも書きましたが、このあたりは実測をもとに試行錯誤するしかありません。
GPUメーカーもどんどん工夫を進めているので何が最適なのかは分かりませんし将来的に変化する可能性もあります。

もっと重要なのはEndSceneのあと、Presentでデバイス画面を更新するまでのあいだ上手にGPUのレンダリングと並行して処理を進めることです。
EndSceneの直後にPresentしたりするとレンダリングが完了するまで無駄に待つことになります。
Fimbul さんが書きました:なぜポイントスプライトの見かけの大きさが変わらないんでしょうか。
そういう仕様だからとしか言えないのですが…。
D3DRS_POINTSCALEENABLEをTRUEに設定すればカメラからの距離に応じたサイズに調整されるみたいですけど。
http://msdn.microsoft.com/ja-jp/library/cc373140.aspx

Re: スレ立てるまでもない質問

Posted: 2012年2月23日(木) 23:43
by Fimbul
ISLe さんが書きました:もっと重要なのはEndSceneのあと、Presentでデバイス画面を更新するまでのあいだ上手にGPUのレンダリングと並行して処理を進めることです。
EndSceneの直後にPresentしたりするとレンダリングが完了するまで無駄に待つことになります。
EndSceneの後、GPUがデータを受け取って描画を行い、バックバッファとフロントバッファを入れ替えるまでに、「GPUの描画処理時間以下の処理時間の処理」を行うと効率が良いと言う事でしょうか。
ISLe さんが書きました:そういう仕様だからとしか言えないのですが…。
D3DRS_POINTSCALEENABLEをTRUEに設定すればカメラからの距離に応じたサイズに調整されるみたいですけど。
trueにしてあるんですけどね・・・。
ポイントスプライトにテクスチャを貼ってビルボードの代わりに出来ないかと思ったのですが、「まあポイントスプライトはこういうものだ」と思って使うのは諦めます。

Re: スレ立てるまでもない質問

Posted: 2012年2月24日(金) 00:38
by ISLe
Fimbul さんが書きました:EndSceneの後、GPUがデータを受け取って描画を行い、バックバッファとフロントバッファを入れ替えるまでに、「GPUの描画処理時間以下の処理時間の処理」を行うと効率が良いと言う事でしょうか。
GPUが働いている時間以下の処理でなければならない理由はないですね。
GPUとプログラムの処理のどちらが先に終わるかではなくて、互いに相手の処理が終わるのを待っている無駄な時間を少なくすることに意味があるので。
ISLe さんが書きました:trueにしてあるんですけどね・・・。
ポイントスプライトにテクスチャを貼ってビルボードの代わりに出来ないかと思ったのですが、「まあポイントスプライトはこういうものだ」と思って使うのは諦めます。
ポイントスケール係数(D3DRS_POINTSCALE_A/D3DRS_POINTSCALE_B/D3DRS_POINTSCALE_C)を設定してないから大きさが変わらないとか。
どのみちポイントスプライトのサイズ計算は透視変換とは異なるのでビルボードの代わりにはならないですけどね。

Re: スレ立てるまでもない質問

Posted: 2012年2月25日(土) 18:50
by Fimbul
ISLe さんが書きました:GPUが働いている時間以下の処理でなければならない理由はないですね。
GPUとプログラムの処理のどちらが先に終わるかではなくて、互いに相手の処理が終わるのを待っている無駄な時間を少なくすることに意味があるので。
済みません。私が何か勘違いしている様で理解できません。
GPUが描画を完了したらバッファを入れ替えて表示をしますよね。
描画が完了した時に、別の処理をしていてすぐにバッファを入れ替えられないと無駄な時間が発生しませんか。
ISLe さんが書きました:ポイントスケール係数(D3DRS_POINTSCALE_A/D3DRS_POINTSCALE_B/D3DRS_POINTSCALE_C)を設定してないから大きさが変わらないとか。
どのみちポイントスプライトのサイズ計算は透視変換とは異なるのでビルボードの代わりにはならないですけどね。
ポイントスケール係数を設定したら見た目の大きさが変わりました。
ビルボードの代わりにならないのは残念です。

Re: スレ立てるまでもない質問

Posted: 2012年2月25日(土) 23:16
by ISLe
Fimbul さんが書きました:GPUが描画を完了したらバッファを入れ替えて表示をしますよね。
描画が完了した時に、別の処理をしていてすぐにバッファを入れ替えられないと無駄な時間が発生しませんか。
フレームレートを一定に保つため、レンダリングが完了してからバッファを入れ替えるまで時間が空きます。
そのあいだメインCPUを何もせず待たせるのはもったいないですよね。
フレーム落ちしなければどちらが後でもかまわないのですよ。

例えば背景のモブとか他のオブジェクトに影響与えないオブジェクトの内部処理を前のフレームから進めておいて、バッファを入れ替えたらすぐにシーンをプッシュ、レンダリングしている間にメインオブジェクトの内部処理を行いシーンをプッシュ…と交互に進めると並行処理を活用できます。

描画だけなら手前のオブジェクトから描画するほうが速かったりとかありますけど、並行処理を絡めると逆転することがいろいろあります。
負荷のバランスはゲームタイトルごとに、環境にも左右されるので試行錯誤です。
カプコンのMTフレームワークはそのあたりを自動化してるらしいですけど。

Re: スレ立てるまでもない質問

Posted: 2012年2月27日(月) 22:27
by Fimbul
ISLe さんが書きました:フレームレートを一定に保つため、レンダリングが完了してからバッファを入れ替えるまで時間が空きます。
そのあいだメインCPUを何もせず待たせるのはもったいないですよね。
フレーム落ちしなければどちらが後でもかまわないのですよ。

例えば背景のモブとか他のオブジェクトに影響与えないオブジェクトの内部処理を前のフレームから進めておいて、バッファを入れ替えたらすぐにシーンをプッシュ、レンダリングしている間にメインオブジェクトの内部処理を行いシーンをプッシュ…と交互に進めると並行処理を活用できます。

描画だけなら手前のオブジェクトから描画するほうが速かったりとかありますけど、並行処理を絡めると逆転することがいろいろあります。
負荷のバランスはゲームタイトルごとに、環境にも左右されるので試行錯誤です。
なんとなく分かった様な、難しいですね・・・。
こういう最適化は是非使いこなしたいですが。