DirectXの描画について
DirectXの描画について
DIrectXで描画したのですが、描画WM_PAINTのところにDirectXの描画関数を入れて実行したのですが、
それだと画面の外に移動してもちゃんと描画されたのですが、
while(1)
if(PeekMessage(...))
{
....
}
else
{
Render()
}
と言う風にそれを実行すると、外に画面を移すと描画されないで表示されるのですが。
描画WM_PAINTのところにDirectXの描画関数を入れる方法以外に外に画面を移すと描画されないで表示されることを回避する方法はないでしょうか?
上のソースのようにして、この外に画面を移すと描画されないで表示されるというようなことを起こさない方法はないのでしょうか?
それだと画面の外に移動してもちゃんと描画されたのですが、
while(1)
if(PeekMessage(...))
{
....
}
else
{
Render()
}
と言う風にそれを実行すると、外に画面を移すと描画されないで表示されるのですが。
描画WM_PAINTのところにDirectXの描画関数を入れる方法以外に外に画面を移すと描画されないで表示されることを回避する方法はないでしょうか?
上のソースのようにして、この外に画面を移すと描画されないで表示されるというようなことを起こさない方法はないのでしょうか?
Re:DirectXの描画について
回答ありがとうございます。
>画面を掴んでいる間は、ウィンドウプロシージャが処理中だからではないでしょうか?
FPS制御するときに支障はないのでしょうか?
他の方法はやっぱりないのでしょうか?
あと、
WNDCLASS wc;
.
.
.
wc.hbrBackground = NULL;
これを(HBRUSH)GetStockObject(WHITE_BRUSH)にするとチカチカするのですが、これは、
バックグラウンドが白になるため移動したりした時にバックグラウンドの白も再描画されてしまうためなのでしょうか?間違っていたらすみません。
質問ばかりですみません。よろしくお願いします。
>画面を掴んでいる間は、ウィンドウプロシージャが処理中だからではないでしょうか?
FPS制御するときに支障はないのでしょうか?
他の方法はやっぱりないのでしょうか?
あと、
WNDCLASS wc;
.
.
.
wc.hbrBackground = NULL;
これを(HBRUSH)GetStockObject(WHITE_BRUSH)にするとチカチカするのですが、これは、
バックグラウンドが白になるため移動したりした時にバックグラウンドの白も再描画されてしまうためなのでしょうか?間違っていたらすみません。
質問ばかりですみません。よろしくお願いします。
Re:DirectXの描画について
回答ありがとうございます。
描画は、下のようにしています。
g_D3DPP.BackBufferCountでバックバッファに描画してると思うのですが、違いますでしょうか?
描画は、下のようにしています。
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の描画について
スレッドでやってみましたが、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の描画について
私はバックグラウンドを白にして移動してもチカチカはしませんね。
画面の外にウィンドウを持っていったときは、その部分は白くなってしまいますが。
なので私はNULLにしています。
これが正しい方法かは分かりませんが、私はあまり気にしていませんので、そう対応しています。
>>PeekMessage()を一回ですることはできるのでしょうか?
え~なぜスレッドの処理でもpeekmessageを使ってるんですか?
二回使わなければいけないと思ってる理由を具体的にお答え下さい。
画面の外にウィンドウを持っていったときは、その部分は白くなってしまいますが。
なので私はNULLにしています。
これが正しい方法かは分かりませんが、私はあまり気にしていませんので、そう対応しています。
>>PeekMessage()を一回ですることはできるのでしょうか?
え~なぜスレッドの処理でもpeekmessageを使ってるんですか?
二回使わなければいけないと思ってる理由を具体的にお答え下さい。
Re:DirectXの描画について
すみません。スレッドに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]
みたいにする画面を外に移動するとその分だけいろんなものが重なって表示されるという現象が起きるのですがこれはしかたのないことなのでしょうか?
[/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の描画について
状況が良く分からないので、その上記二なったときの画面ショットを添付していただけると助かります。
それで、結局スレッドを使って描画するのはやめたのですか?
それで、結局スレッドを使って描画するのはやめたのですか?
Re:DirectXの描画について
返信ありがとうございます。いや、スレッド処理もやめていないです。ただ、先ほどの方法でできないのかと思い聞きました。この画像のようにならないようにすることはできるんでしょうか?
スレッドじゃない方法は、以下のとおりです。
スレッドじゃない方法は、以下のとおりです。
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の描画について
ん?メッセージループの中での描画だけで、画像のようになるんですか?
それともスレッドでの描画も同時に行うと画像のようになるんですか?
クリティカルセクションの意味分かってますか?
それと、Sleepを適度に入れないと、超高速ループになってしまうので、
入れるべきですよ。(これが原因かも)
それともスレッドでの描画も同時に行うと画像のようになるんですか?
クリティカルセクションの意味分かってますか?
それと、Sleepを適度に入れないと、超高速ループになってしまうので、
入れるべきですよ。(これが原因かも)
Re:DirectXの描画について
>メッセージループの中での描画だけで、画像のようになるんですか?
そうです。
クリティカルセッションならわかります。同期を取るんですよね。
Sleepやってみましたがだめでした。
そうです。
クリティカルセッションならわかります。同期を取るんですよね。
Sleepやってみましたがだめでした。
Re:DirectXの描画について
>画面を掴んでいる間は、ウィンドウプロシージャが処理中だからではないでしょうか?
とシエルさんも仰っていますが
描画はされないと思います。
とシエルさんも仰っていますが
while(1) if(PeekMessage(...)) { .... } else { Render() }の形式に固執する限りはずっとifの方の式が実行されて
描画はされないと思います。
Re:DirectXの描画について
返信誠にありがとうございます。ウィンドウプロシージャが処理をしているからと言うのは聞きました。やっぱり無理があるのでしょうか?
それだけが知りたいです。
それだけが知りたいです。
Re:DirectXの描画について
できないということで決着してしまったみたいですが…。
ウインドウ内部に引きずったあとが残るのは、WM_ERASEBKGNDメッセージに対してウインドウのクライアント領域の背景が消去されないからです。
WM_ERASEBKGNDメッセージはデフォルトでウインドウクラスに設定された背景ブラシでクライアント領域全体を塗りつぶします。
質問者さんは背景ブラシをNULLに設定しているので結果的に塗りつぶしが行われません。
対応としては、
・ウインドウのドラッグが開始されたらメインの描画を停止
・WM_ERASEBKGNDメッセージのイベント応答としてクライアント領域に描画
・ウインドウのドラッグが終了したらメインの描画を再開
というふうにします。
Direct3DデバイスからGDI下のクライアント領域には描画できないのでひと工夫してください。
#WM_PAINTで描画しても変わらないのは↑と同じ理由です。
ウインドウ内部に引きずったあとが残るのは、WM_ERASEBKGNDメッセージに対してウインドウのクライアント領域の背景が消去されないからです。
WM_ERASEBKGNDメッセージはデフォルトでウインドウクラスに設定された背景ブラシでクライアント領域全体を塗りつぶします。
質問者さんは背景ブラシをNULLに設定しているので結果的に塗りつぶしが行われません。
対応としては、
・ウインドウのドラッグが開始されたらメインの描画を停止
・WM_ERASEBKGNDメッセージのイベント応答としてクライアント領域に描画
・ウインドウのドラッグが終了したらメインの描画を再開
というふうにします。
Direct3DデバイスからGDI下のクライアント領域には描画できないのでひと工夫してください。
#WM_PAINTで描画しても変わらないのは↑と同じ理由です。
Re:DirectXの描画について
失礼しました。
WM_PAINTで描画すれば上手くいくと書いてありましたね。
消去を要求するためにWM_ERASEBKGNDメッセージ、描画を要求するためにWM_PAINTメッセージが飛んでくるので適切に対応するしかありません。
ウインドウメッセージが来ないときに描画するだけではウインドウメッセージに対応できません。
フルスクリーンモードではうまく行ってもウインドウモードではボロが出てしまいます。
システムのプロパティの視覚効果の『ドラッグ中にウインドウの内容を表示する』が有効かどうかで動作が変わります。
WM_PAINTで描画すれば上手くいくと書いてありましたね。
消去を要求するためにWM_ERASEBKGNDメッセージ、描画を要求するためにWM_PAINTメッセージが飛んでくるので適切に対応するしかありません。
ウインドウメッセージが来ないときに描画するだけではウインドウメッセージに対応できません。
フルスクリーンモードではうまく行ってもウインドウモードではボロが出てしまいます。
システムのプロパティの視覚効果の『ドラッグ中にウインドウの内容を表示する』が有効かどうかで動作が変わります。
Re:DirectXの描画について
レスありがとうございます。
やっぱりそうですか。。。
>システムのプロパティの視覚効果の『ドラッグ中にウインドウの内容を表示する』が有効かどうかで動作が変わります。
はどうやって設定すればよいのでしょうか?
やっぱりそうですか。。。
>システムのプロパティの視覚効果の『ドラッグ中にウインドウの内容を表示する』が有効かどうかで動作が変わります。
はどうやって設定すればよいのでしょうか?
Re:DirectXの描画について
> >システムのプロパティの視覚効果の『ドラッグ中にウインドウの内容を表示する』が有効かどうかで動作が変わります。
> はどうやって設定すればよいのでしょうか?
XPの場合、
マイコンピュータのプロパティ→詳細設定タブ→パフォーマンスの設定ボタン→
Vista/7の場合、
コンピュータのプロパティ→システムの詳細設定→パフォーマンスの設定ボタン→
ラジオボタンでカスタムにして『ドラッグ中にウインドウの内容を表示する』のチェックを外す
ウインドウのドラッグ中は枠だけが表示されるようになります。
スレッドで描画するとどこに表示されるのか確認したことなかったです。
画面は更新されなくなるかも。
> はどうやって設定すればよいのでしょうか?
XPの場合、
マイコンピュータのプロパティ→詳細設定タブ→パフォーマンスの設定ボタン→
Vista/7の場合、
コンピュータのプロパティ→システムの詳細設定→パフォーマンスの設定ボタン→
ラジオボタンでカスタムにして『ドラッグ中にウインドウの内容を表示する』のチェックを外す
ウインドウのドラッグ中は枠だけが表示されるようになります。
スレッドで描画するとどこに表示されるのか確認したことなかったです。
画面は更新されなくなるかも。
Re:DirectXの描画について
レスありがとうございます。
>スレッドで描画するとどこに表示されるのか確認したことなかったです。
画面は更新されなくなるかも。
スレッドでやりましたが描画はちゃんとされていました。
>スレッドで描画するとどこに表示されるのか確認したことなかったです。
画面は更新されなくなるかも。
スレッドでやりましたが描画はちゃんとされていました。