トップページ > 過去ログ > 記事閲覧
SetUserWindowを使った場合の描画方法
名前:ryu 日時: 2011/05/10 07:44

SetUserWindowで自作ウィンドウを指定し SetDrawScreenでα付のバッファを指定 し、そこに絵を入れ UpdateLayerdWindowForSoftImageで更新したのですが 表示されません ウィンドウの指定が駄目なのでしょうか・・ #include <windows.h> #include "DxLib.h" char szClassNme[] = "ウィンドウクラス・ネーム"; LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { HWND hWnd; int WinX = 1024; int WinY = 768; WNDCLASSEX myProg; ZeroMemory(&myProg,sizeof(WNDCLASSEX)); myProg.cbSize = sizeof(WNDCLASSEX); myProg.style = CS_HREDRAW | CS_VREDRAW|CS_DBLCLKS; myProg.lpfnWndProc = WndProc; myProg.hInstance = hInstance; myProg.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH); myProg.lpszClassName= szClassNme; if (!RegisterClassEx(&myProg)) return FALSE; hWnd=CreateWindowEx( WS_EX_TOOLWINDOW , szClassNme, "Test", WS_POPUP, 0, 0, WinX, WinY, NULL, NULL, hInstance, NULL); ShowWindow( hWnd, nCmdShow ) ; UpdateWindow( hWnd ) ; SetUserWindow(hWnd); // ウインドウモードで起動 ChangeWindowMode( TRUE ); SetHookWinProc(WndProc); SetAlwaysRunFlag(true); //非アクティブでもウィンドウ動作 // ウインドウモードで起動 ChangeWindowMode( TRUE ); // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; SetTransColor( 0, 0, 255); //透明色設定 SetDrawValidAlphaChannelGraphCreateFlag( TRUE ); int ABufferScreen = MakeScreen( WinX, WinY ); // α付のバッファを作成 SetDrawValidAlphaChannelGraphCreateFlag( FALSE ); SetDrawScreen( ABufferScreen ); //描画する画面を設定 FillGraph( ABufferScreen, 255, 0, 0, 0 ); //指定色で塗りつぶし SetDrawScreen( ABufferScreen ); // BlendParam と画像のα値が乗算されますので、255を指定すれば // 画像のα値がそのまま描画先に書き込まれます SetDrawBlendMode( DX_BLENDMODE_SRCCOLOR, 255 ) ; int gh = LoadGraph( "sample.png" ); DrawGraph( 0, 0, gh, TRUE ); // α付のバッファにレンダリング DrawPixel( 320 , 240 , GetColor( 255,255,255 ) ) ; // 点を打つ DrawBox( 0, 0, 31, 31, GetColor( 255,255,255 ), TRUE ) ; // ブレンドモードを元に戻す SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0 ) ; //ソフトイメージ用画面を作成 int UpdataScreen = MakeARGB8ColorSoftImage( WinX, WinY ); int CaptureScreen = MakeARGB8ColorSoftImage( WinX, WinY ); GetDrawScreenSoftImage( 0, 0, WinX, WinY, CaptureScreen ); // レンダリング結果をソフトイメージに取得 FillSoftImage( UpdataScreen, 0, 0, 0, 0 ) ; //黒で塗りつぶし BltSoftImage( 0, 0, WinX, WinY, CaptureScreen, 0, 0, UpdataScreen ); // バッファを使って加工した画像を出力 //更新 UpdateLayerdWindowForSoftImage( UpdataScreen ); WaitKey(); return 0 ; } // メッセージ処理用関数 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_DESTROY : PostQuitMessage( 0 ) ; // QuitMessage = 1 ; break ; case WM_MBUTTONDOWN: // QuitMessage = 1 ; PostQuitMessage(0); break; case WM_LBUTTONDOWN: ReleaseCapture(); SendMessage(hWnd,WM_SYSCOMMAND,SC_MOVE|2,0); break; default : return DefWindowProc(hWnd, msg, wParam, lParam ) ; } return 0 ; }

Page: 1 |

Re: SetUserWindowを使った場合の描画方法 ( No.1 )
名前:いっち 日時:2011/05/11 19:33

どのようなことをなさりたいのでしょうか?
Re: SetUserWindowを使った場合の描画方法 ( No.2 )
名前:ryu 日時:2011/05/11 21:08

マスコット+音を鳴らすアプリ を作成したくて 前に教えてもらった tp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=2220 にマルチスレッドのプログラムを足して動かしたのですがスレッドで音が鳴り続けなかったので CreateWindowExを作り、DrawGraph等で透過表示した かったのでウィンドウをDirectXにするため SetUserWindowでセットしたのですが 今度は絵が表示されなくなり・・・・とそこで 詰まっています。 今は絵が表示したいです。 このプログラムではスレッドの部分は削除しています
Re: SetUserWindowを使った場合の描画方法 ( No.3 )
名前:いっち 日時:2011/05/11 21:21

> マルチスレッドのプログラムを足して動かしたのですがスレッドで音が鳴り続けなかったので そのプログラムをなり続けるように修正するすることは出来ないのでしょうか? おそらくその路線のほうが良いと思います。 まだ検討が十分でないようでしたら、そのソースをご提供下さい。
Re: SetUserWindowを使った場合の描画方法 ( No.4 )
名前:ryu 日時:2011/05/12 09:42

確かにそのほういいですね、修正できる可能性を考えていませんでした・・ #include "DxLib.h" LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ; char szClassNme[] = "ウィンドウクラス・ネーム"; int QuitMessage = 0 ; DWORD DxLibThreadID; HINSTANCE GhInstance; // DXライブラリの処理をするスレッド DWORD WINAPI DxLibThread(LPVOID) { SetHookWinProc(WndProc); //使用するプロシージャを指定 ChangeWindowMode( TRUE ); // ウインドウモードで起動 SetUseBackBufferTransColorFlag( TRUE ); SetAlwaysRunFlag(true); //非アクティブでもウィンドウ動作 if ( DxLib_Init( ) == -1 ) return -1; int BGM = LoadSoundMem( "test.wav" ); int gh = LoadGraph( "AlphaCircle.png" ); int sh = LoadSoftImage( "AlphaCircle.png" ); SetDrawValidAlphaChannelGraphCreateFlag( TRUE ); int bgh = MakeScreen( 256, 256 ); // α付のバッファを作成 SetDrawValidAlphaChannelGraphCreateFlag( FALSE ); int bsh = MakeARGB8ColorSoftImage( 640, 480 ); int csh = MakeARGB8ColorSoftImage( 256, 256 ); SetTransColor( 0, 255, 0 ); SetDrawScreen( bgh ); FillGraph( bgh, 0, 0, 0, 0 ); // BlendParam と画像のα値が乗算されますので、255を指定すれば // 画像のα値がそのまま描画先に書き込まれます SetDrawBlendMode( DX_BLENDMODE_SRCCOLOR, 255 ) ; DrawGraph( 0, 0, gh, TRUE ); // α付のバッファにレンダリング // ブレンドモードを元に戻す SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0 ) ; GetDrawScreenSoftImage( 0, 0, 256, 256, csh ); // レンダリング結果をソフトイメージに取得 FillSoftImage( bsh, 0, 0, 0, 0 ) ; BltSoftImage( 0, 0, 256, 256, sh, 0, 0, bsh ); // ソフトイメージに読み込んだ画像を直接出力 BltSoftImage( 0, 0, 256, 256, csh, 0, 240, bsh ); // バッファを使って加工した画像を出力 // メッセージループ while( ProcessMessage() == 0 && QuitMessage == 0 ) { UpdateLayerdWindowForSoftImage( bsh ); if(CheckSoundMem(BGM) == 0) { PlaySoundMem( BGM , DX_PLAYTYPE_BACK ) ; } } // DXライブラリの後始末 DxLib_End(); return 0 ; } int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { MSG msg; // DXライブラリの処理をするスレッドの作成 CreateThread( NULL, 0, DxLibThread, NULL, 0, &DxLibThreadID ) ; // メッセージループ while( QuitMessage == 0 ) { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ) ; DispatchMessage( &msg ) ; } Sleep( 15 ) ; } return msg.wParam ; } // メッセージ処理用関数 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_DESTROY : PostQuitMessage( 0 ) ; QuitMessage = 1 ; break ; case WM_KEYDOWN: if(wParam==VK_ESCAPE) { PostQuitMessage( 0 ) ; QuitMessage = 1 ; } break; case WM_LBUTTONDOWN: ReleaseCapture(); SendMessage(hWnd,WM_SYSCOMMAND,SC_MOVE|2,0); break; default : return DefWindowProc(hWnd, msg, wParam, lParam ) ; } return 0 ; }
Re: SetUserWindowを使った場合の描画方法 ( No.5 )
名前:いっち 日時:2011/05/12 20:21

やってみました。 音は止まらないようになったと思います。 DXライブラリに画面描画を任せる場合、システムメニューを操作しているときに描画がとまるのはどうにもならない気がします。 それと、テストコードの範囲内では問題ないようでしたが、もしかしたら、クリティカルセクションか何かで ProcessMessage と SoundThread内の処理の同期を取る必要があるかもしれません。 できるかぎりDXライブラリで完結したほうが良いと思ったのでウィンドウプロシージャは削りました。 //- 以下、テストコード ("test.wav"と"AlphaCircle.png"を使用) -// #include <process.h> #include "DxLib.h" bool quit_thread; unsigned int WINAPI SoundThread( void *p ) { int BGM = LoadSoundMem( "test.wav" ); while ( 1 ) { if ( CheckSoundMem( BGM ) == 0 ) { PlaySoundMem( BGM, DX_PLAYTYPE_BACK ); } if ( quit_thread == true ) break; Sleep( 0 ); } DeleteSoundMem( BGM ); _endthreadex( 0 ); return 0; } int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { ChangeWindowMode( TRUE ); SetUseBackBufferTransColorFlag( TRUE ); SetAlwaysRunFlag( TRUE ); if ( DxLib_Init( ) == -1 ) return -1; SetCreateSoundDataType( DX_SOUNDDATATYPE_FILE ); int gh = LoadGraph( "AlphaCircle.png" ); int sh = LoadSoftImage( "AlphaCircle.png" ); int red = GetColor( 255, 0, 0 ); SetDrawValidAlphaChannelGraphCreateFlag( TRUE ); int bgh = MakeScreen( 256, 256 ); SetDrawValidAlphaChannelGraphCreateFlag( FALSE ); int bsh = MakeARGB8ColorSoftImage( 640, 480 ); int csh = MakeARGB8ColorSoftImage( 256, 256 ); SetTransColor( 0, 255, 0 ); SetDrawScreen( bgh ); unsigned int thread_id1; HANDLE thread_handle1 = (HANDLE)_beginthreadex( NULL, 0, &SoundThread, 0, 0, &thread_id1 ); POINT mpold = {}, mpnew = {}; int mold = 0, mnew = 0; int wx = 0, wy = 0; int alpha = 1, step = 1; while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { if ( GetActiveFlag( ) ) { mnew = GetMouseInput( ); if ( mnew & MOUSE_INPUT_LEFT ) { GetCursorPos( &mpnew ); int mxdiff = mpnew.x - mpold.x, mydiff = mpnew.y - mpold.y; if ( (mold & MOUSE_INPUT_LEFT) && (mxdiff || mydiff) ) { GetWindowPosition( &wx, &wy ); SetWindowPosition( wx + mxdiff, wy + mydiff ); } mpold = mpnew; } mold = mnew; } FillGraph( bgh, 0, 0, 0, 0 ); SetDrawBlendMode( DX_BLENDMODE_SRCCOLOR, alpha ); DrawGraph( 0, 0, gh, TRUE ); SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0 ); DrawFormatString( 0, 0, red, "Test %d %d %d", alpha, wx, wy ); GetDrawScreenSoftImage( 0, 0, 256, 256, csh ); FillSoftImage( bsh, 0, 0, 0, 0 ) ; BltSoftImage( 0, 0, 256, 256, sh, 0, 0, bsh ); BltSoftImage( 0, 0, 256, 256, csh, 0, 240, bsh ); UpdateLayerdWindowForSoftImage( bsh ); if ( !(alpha % 256) ) step = -step; alpha += step; } quit_thread = true; WaitForSingleObject( thread_handle1, INFINITE ); CloseHandle( thread_handle1 ); DxLib_End( ); return 0; }
Re: SetUserWindowを使った場合の描画方法 ( No.6 )
名前:ryu(解決) 日時:2011/05/13 17:07

SetUseBackBufferTransColorFlagで消してないから ウィンドウに邪魔されていたんですね・・・ 処理の前後関係をちゃんと把握しないと 駄目ですね、いっちさんありがとうございました。

Page: 1 |