ページ 1 / 1
DirectXの描画について
Posted: 2010年7月06日(火) 23:15
by たろう
DIrectXで描画したのですが、描画WM_PAINTのところにDirectXの描画関数を入れて実行したのですが、
それだと画面の外に移動してもちゃんと描画されたのですが、
while(1)
if(PeekMessage(...))
{
....
}
else
{
Render()
}
と言う風にそれを実行すると、外に画面を移すと描画されないで表示されるのですが。
描画WM_PAINTのところにDirectXの描画関数を入れる方法以外に外に画面を移すと描画されないで表示されることを回避する方法はないでしょうか?
上のソースのようにして、この外に画面を移すと描画されないで表示されるというようなことを起こさない方法はないのでしょうか?
Re:DirectXの描画について
Posted: 2010年7月06日(火) 23:18
by シエル
画面を掴んでいる間は、ウィンドウプロシージャが処理中だからではないでしょうか?
Re:DirectXの描画について
Posted: 2010年7月06日(火) 23:57
by Justy
スレッドで描画。
Re:DirectXの描画について
Posted: 2010年7月06日(火) 23:59
by シエル
私はストリーミング再生のためだけに、スレッドを作って常に読み込ますようにしてます。。。
Re:DirectXの描画について
Posted: 2010年7月07日(水) 00:01
by たろう
回答ありがとうございます。
>画面を掴んでいる間は、ウィンドウプロシージャが処理中だからではないでしょうか?
FPS制御するときに支障はないのでしょうか?
他の方法はやっぱりないのでしょうか?
あと、
WNDCLASS wc;
.
.
.
wc.hbrBackground = NULL;
これを(HBRUSH)GetStockObject(WHITE_BRUSH)にするとチカチカするのですが、これは、
バックグラウンドが白になるため移動したりした時にバックグラウンドの白も再描画されてしまうためなのでしょうか?間違っていたらすみません。
質問ばかりですみません。よろしくお願いします。
Re:DirectXの描画について
Posted: 2010年7月07日(水) 00:04
by シエル
描画はどのような方法で行ってますか?
バックバッファに描画してから、メイン画面へ反映へする方法はとっていないのですか?
Re:DirectXの描画について
Posted: 2010年7月07日(水) 00:35
by たろう
回答ありがとうございます。
描画は、下のようにしています。
g_D3DPP.BackBufferCountでバックバッファに描画してると思うのですが、違いますでしょうか?
HRESULT Initialize(HWND hwnd,bool fullScreen,int Hieght,int Width)
{
D3DDISPLAYMODE d3dMode;
//Direct3D9のオブジェクトの作成
if((g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))==0)
{
return E_FAIL;
}
//現在のディスプレイモードを取得
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3dMode)))
{
return E_FAIL;
}
//デバイスのプレゼンテーションパラメータを初期化
ZeroMemory(&g_D3DPP,sizeof(D3DPRESENT_PARAMETERS));
g_D3DPP.BackBufferCount=1;
if(fullScreen)//フルスクリーンかどうか?
{
g_D3DPP.Windowed=FALSE;
g_D3DPP.BackBufferHeight=Hieght;
g_D3DPP.BackBufferWidth=Width;
}
else
{
g_D3DPP.Windowed=TRUE;
}
g_D3DPP.BackBufferFormat=d3dMode.Format; //カラーモードの指定
g_D3DPP.SwapEffect=D3DSWAPEFFECT_DISCARD; //どの方法でモニター画面に転送するか指定
g_D3DPP.EnableAutoDepthStencil=TRUE; //エラー対策
g_D3DPP.AutoDepthStencilFormat=D3DFMT_D16; //エラー対策
//ディスプレイアダプタを表すためのデバイスを作成
//描画と頂点処理をハードウェアで行う
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&g_D3DPP,&g_pD3DDevice))){
//描画はハードウェアで行い頂点処理はCPUが行う
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&g_D3DPP,&g_pD3DDevice))){
//描画と頂点処理はCPUで行う
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_REF,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&g_D3DPP,&g_pD3DDevice))){
g_pD3D->Release();
return E_FAIL;
}
}
}
メインの描画は下にあるとおりです。
void RenderScene(void)
{
// ビューポートと深度バッファのクリアとステンシルバッファの削除
if(FAILED(g_pD3DDevice->Clear(0,NULL, // クリアする領域は全面
D3DCLEAR_TARGET | // バックバッファを指定
D3DCLEAR_ZBUFFER, // 深度バッファ(Zバッファ)を指定
D3DCOLOR_XRGB(0,0,0), // クリアする色
1.0f, // クリアする深度バッファ(Zバッファ)の値
0))) { // クリアするステンシルバッファの値
return;
}
// 描画開始宣言
if(SUCCEEDED(g_pD3DDevice->BeginScene())) {
// モデルなどの描画
Draw();
// 描画終了宣言
g_pD3DDevice->EndScene();
}
// 描画結果の転送
if(FAILED(g_pD3DDevice->Present( 0, 0, 0, 0 ))) {
// デバイス消失から復帰
g_pD3DDevice->Reset(&g_D3DPP);
}
}
Re:DirectXの描画について
Posted: 2010年7月07日(水) 00:50
by シエル
チカチカするのは常にチカチカするんですか?移動したときだけですか?
Re:DirectXの描画について
Posted: 2010年7月07日(水) 00:51
by たろう
返信ありがとうございます。はい。そうです。
Re:DirectXの描画について
Posted: 2010年7月07日(水) 00:52
by たろう
すみません。移動したときだけです。
Re:DirectXの描画について
Posted: 2010年7月07日(水) 05:18
by たろう
スレッドでやってみましたが、peekMessageを二つ使わないとできないのですが、一つでやるにはどうしたらいいでしょうか?できないのでしょうか?ソース載せます。
.
.
.
// メイン メッセージ ループ:
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sub,NULL,0,&ThreadId_0);
int flag;
do{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if((flag=GetMessage(&msg,NULL,0,0))==0||flag==-1)
{
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}while(1);
return 0;
DWORD WINAPI sub(void)
{
EnterCriticalSection( &Critical_Se );// クリティカルセッション開始
int bit;
MSG msg = {0};
do{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if((bit=GetMessage(&msg,NULL,0,0))==0||bit==-1)
{
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
RenderScene(); // Do some rendering
}
}while( WM_QUIT != msg.message );
LeaveCriticalSection( &Critical_Se );//クリティカルセッション終了
return 0;
}
とやらなくてはいけないのですがこれをPeekMessage()を一回ですることはできるのでしょうか?
よろしくお願いします。
Re:DirectXの描画について
Posted: 2010年7月07日(水) 08:35
by シエル
私はバックグラウンドを白にして移動してもチカチカはしませんね。
画面の外にウィンドウを持っていったときは、その部分は白くなってしまいますが。
なので私はNULLにしています。
これが正しい方法かは分かりませんが、私はあまり気にしていませんので、そう対応しています。
>>PeekMessage()を一回ですることはできるのでしょうか?
え~なぜスレッドの処理でもpeekmessageを使ってるんですか?
二回使わなければいけないと思ってる理由を具体的にお答え下さい。
Re:DirectXの描画について
Posted: 2010年7月07日(水) 15:28
by たろう
すみません。スレッドにPeekMessage()を使わなくてもできました。
[/pre]do{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if((flag=GetMessage(&msg,NULL,0,0))==0||flag==-1)
{
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Recnder()
}
}while(1);[/pre]
みたいにする画面を外に移動するとその分だけいろんなものが重なって表示されるという現象が起きるのですがこれはしかたのないことなのでしょうか?
Re:DirectXの描画について
Posted: 2010年7月07日(水) 18:59
by シエル
状況が良く分からないので、その上記二なったときの画面ショットを添付していただけると助かります。
それで、結局スレッドを使って描画するのはやめたのですか?
Re:DirectXの描画について
Posted: 2010年7月07日(水) 19:17
by たろう
返信ありがとうございます。いや、スレッド処理もやめていないです。ただ、先ほどの方法でできないのかと思い聞きました。この画像のようにならないようにすることはできるんでしょうか?
スレッドじゃない方法は、以下のとおりです。
do{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if((flag=GetMessage(&msg,NULL,0,0))==0||flag==-1)
{
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
RenderScene();
}
}while(1);
それで、スレッドの処理は以下のとおりです。
DWORD WINAPI sub(void)
{
EnterCriticalSection( &Critical_Se );// クリティカルセッション開始
int flag;
MSG msg = {0};
do{
RenderScene();
}while( 1);
LeaveCriticalSection( &Critical_Se );//クリティカルセッション終了
return 0;
}
です。それとスレッドはこれでも大丈夫でしょうか?
Re:DirectXの描画について
Posted: 2010年7月07日(水) 19:34
by シエル
ん?メッセージループの中での描画だけで、画像のようになるんですか?
それともスレッドでの描画も同時に行うと画像のようになるんですか?
クリティカルセクションの意味分かってますか?
それと、Sleepを適度に入れないと、超高速ループになってしまうので、
入れるべきですよ。(これが原因かも)
Re:DirectXの描画について
Posted: 2010年7月07日(水) 20:07
by たろう
>メッセージループの中での描画だけで、画像のようになるんですか?
そうです。
クリティカルセッションならわかります。同期を取るんですよね。
Sleepやってみましたがだめでした。
Re:DirectXの描画について
Posted: 2010年7月08日(木) 07:46
by たろう
while(1)
if(PeekMessage(...))
{
....
}
else
{
Render()
}
ではできないのでしょうか?
Re:DirectXの描画について
Posted: 2010年7月08日(木) 07:58
by たろう
わかるかたいらしたらよろしくご教授お願いします。
Re:DirectXの描画について
Posted: 2010年7月08日(木) 17:49
by たろう
やっぱりできないのでしょうか・・・
Re:DirectXの描画について
Posted: 2010年7月08日(木) 18:25
by ideyan
>画面を掴んでいる間は、ウィンドウプロシージャが処理中だからではないでしょうか?
とシエルさんも仰っていますが
while(1)
if(PeekMessage(...))
{
....
}
else
{
Render()
}
の形式に固執する限りはずっとifの方の式が実行されて
描画はされないと思います。
Re:DirectXの描画について
Posted: 2010年7月08日(木) 18:35
by たろう
返信誠にありがとうございます。ウィンドウプロシージャが処理をしているからと言うのは聞きました。やっぱり無理があるのでしょうか?
それだけが知りたいです。
Re:DirectXの描画について
Posted: 2010年7月08日(木) 18:37
by シエル
いや、ですので、スレッドでの描画を提案したのですが?
Re:DirectXの描画について
Posted: 2010年7月08日(木) 18:40
by たろう
そうなんですか(汗)できないということでいいんですね!すっきりしました。回答してくださた方誠にありがとうございました。
Re:DirectXの描画について
Posted: 2010年7月08日(木) 18:41
by たろう
解決しました。
Re:DirectXの描画について
Posted: 2010年7月08日(木) 22:27
by ISLe
できないということで決着してしまったみたいですが…。
ウインドウ内部に引きずったあとが残るのは、WM_ERASEBKGNDメッセージに対してウインドウのクライアント領域の背景が消去されないからです。
WM_ERASEBKGNDメッセージはデフォルトでウインドウクラスに設定された背景ブラシでクライアント領域全体を塗りつぶします。
質問者さんは背景ブラシをNULLに設定しているので結果的に塗りつぶしが行われません。
対応としては、
・ウインドウのドラッグが開始されたらメインの描画を停止
・WM_ERASEBKGNDメッセージのイベント応答としてクライアント領域に描画
・ウインドウのドラッグが終了したらメインの描画を再開
というふうにします。
Direct3DデバイスからGDI下のクライアント領域には描画できないのでひと工夫してください。
#WM_PAINTで描画しても変わらないのは↑と同じ理由です。
Re:DirectXの描画について
Posted: 2010年7月08日(木) 22:55
by ISLe
失礼しました。
WM_PAINTで描画すれば上手くいくと書いてありましたね。
消去を要求するためにWM_ERASEBKGNDメッセージ、描画を要求するためにWM_PAINTメッセージが飛んでくるので適切に対応するしかありません。
ウインドウメッセージが来ないときに描画するだけではウインドウメッセージに対応できません。
フルスクリーンモードではうまく行ってもウインドウモードではボロが出てしまいます。
システムのプロパティの視覚効果の『ドラッグ中にウインドウの内容を表示する』が有効かどうかで動作が変わります。
Re:DirectXの描画について
Posted: 2010年7月10日(土) 20:52
by たろう
レスありがとうございます。
やっぱりそうですか。。。
>システムのプロパティの視覚効果の『ドラッグ中にウインドウの内容を表示する』が有効かどうかで動作が変わります。
はどうやって設定すればよいのでしょうか?
Re:DirectXの描画について
Posted: 2010年7月10日(土) 22:05
by ISLe
> >システムのプロパティの視覚効果の『ドラッグ中にウインドウの内容を表示する』が有効かどうかで動作が変わります。
> はどうやって設定すればよいのでしょうか?
XPの場合、
マイコンピュータのプロパティ→詳細設定タブ→パフォーマンスの設定ボタン→
Vista/7の場合、
コンピュータのプロパティ→システムの詳細設定→パフォーマンスの設定ボタン→
ラジオボタンでカスタムにして『ドラッグ中にウインドウの内容を表示する』のチェックを外す
ウインドウのドラッグ中は枠だけが表示されるようになります。
スレッドで描画するとどこに表示されるのか確認したことなかったです。
画面は更新されなくなるかも。
Re:DirectXの描画について
Posted: 2010年7月10日(土) 22:55
by たろう
レスありがとうございます。
>スレッドで描画するとどこに表示されるのか確認したことなかったです。
画面は更新されなくなるかも。
スレッドでやりましたが描画はちゃんとされていました。