トップページ > 記事閲覧
ウィンドウモード切り換えについて
名前:Saucer 日時: 2014/08/27 09:33

いつもお世話になっております。 他ライブラリで作られたゲームで、実に簡単に、スムースに ウィンドウモードからフルスクリーンモードへの切り換えが 行われるものがありますが(逆も然り)、DXライブラリで同じ事を しようとすると画面が数秒間黒くなり、あまり速く行われません。 切り替えた後にウィンドウの位置が何故か変わっていることもあります。 DXライブラリで速く、簡単に、ウィンドウの位置を変えずに 切り換える方法はないでしょうか。 よろしくお願いいたします。
メンテ

Page: 1 |

Re: ウィンドウモード切り換えについて ( No.1 )
名前:Saucer 日時:2014/08/27 09:34

追記 参考プログラムです。 @ https://app.box.com/s/yay7xq3i7lrd8dz78k2e こちらは私が「GameMaker 8」という、DirectXを使用していると 思われるゲーム制作ツールで作ったプログラムです。 (解凍してください)(Delキーでプログラム終了) 切り替え機能の仕様は知りませんが、F4キーでパッパッパッと いくらでもウィンドウモードの切り替えが行えます。 また、参考として、ご存知かどうかは分かりませんが、最近海外で人気の 「Hearthstone」というゲームも(GameMakerとは関係ないですが) 切り替えが簡単に行えます。 A https://app.box.com/s/wgbj9yk7rbkybstf3bx4 こちらは私がDXライブラリで作ったプログラムです。 やはりF4キーで切り替えられます。 (解凍してください)(Delキーでプログラム終了) 切り替えようとすると、時間がかかり、私の環境ではフルスクリーンから ウィンドウモードに戻るとExplorerでたまたま開けていたフォルダの ウィンドウがすこしおかしくなったりで、スムースに切り替えられません。 注:キャラクター画像を再読み込みしていないのでウィンドウモードを 切り替えるとキャラクターが消えてしまいますが、デバッグテキストは 正常に動作しているようなので切り替え機能には関係ないと思います。 切り替える為のコードはこんな感じです: if (isWindowed) //ウィンドウに切り替える場合 { graphicsX = 0; graphicsY = 0; scaledGraphicsWidth = graphicsWidth * windowedScale; scaledGraphicsHeight = graphicsHeight * windowedScale; ChangeWindowMode(isWindowed); SetGraphMode(scaledGraphicsWidth, scaledGraphicsHeight, 32); } else //フルスクリーンに切り替える場合 { //この掲示板で教わった、描画画面を拡大してモニターの真ん中に描くという方法 //おそらく「SetFullScreenResolutionMode」の「DX_FSRESOLUTIONMODE_DESKTOP」モードに似たようなやり方です int desktopWidth, desktopHeight, xs, ys; DxLib::GetDefaultState(&desktopWidth, &desktopHeight, nullptr); xs = desktopWidth / graphicsWidth; ys = desktopHeight / graphicsHeight; //scaleInFullscreenMode = xs <= ys ? xs : ys; if (xs <= ys) { scaledGraphicsWidth = graphicsWidth * xs; scaledGraphicsHeight = graphicsHeight * xs; } else { scaledGraphicsWidth = graphicsWidth * ys; scaledGraphicsHeight = graphicsHeight * ys; } graphicsX = (desktopWidth - scaledGraphicsWidth) / 2; graphicsY = (desktopHeight - scaledGraphicsHeight) / 2; SetGraphMode(desktopWidth, desktopHeight, 32); ChangeWindowMode(isWindowed); } if (screenImageHandle != -1) screenImageHandle = MakeScreen(graphicsWidth, graphicsHeight, TRUE);
メンテ
Re: ウィンドウモード切り換えについて ( No.2 )
名前:管理人 日時:2014/08/28 01:22

> DXライブラリで速く、簡単に、ウィンドウの位置を変えずに > 切り換える方法はないでしょうか。 DirectX で言うところの『フルスクリーンモード』について申し上げますと、 速く簡単に切り替える方法はありません @でアップしていただいたソフトですが、こちらは DirectX で言うところの 『ウインドウモード』のみを使用しているソフトです こちらのソフトではウインドウをデスクトップ画面と同じ大きさにすることで 擬似的にフルスクリーンモードを実現しています DXライブラリでも同様の方法で擬似的なフルスクリーンモードを使用することで 擬似フルスクリーンモードとウインドウモードを高速に切り替えられるようにすることができます サンプルを組んでみましたので、よろしければご覧ください #include "DxLib.h" #define SCREEN_SIZE_X 640 #define SCREEN_SIZE_Y 480 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int handle, x, add ; int WindowFullSize ; int WindowPosX ; int WindowPosY ; int DesktopSizeX ; int DesktopSizeY ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // 画像の読み込み handle = LoadGraph( "Test1.bmp" ) ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // デスクトップの解像度を取得 GetDefaultState( &DesktopSizeX, &DesktopSizeY, NULL ) ; // フルスクリーンモードかどうかのフラグを倒しておく WindowFullSize = FALSE ; // メインループ(何かキーが押されたらループを抜ける) x = 0 ; add = 8 ; while( ProcessMessage() == 0 ) { // スペースキーが押されたらウインドウのフルスクリーンモードと通常モードを切り替える if( GetInputChar( TRUE ) == ' ' ) { if( WindowFullSize ) { // フルスクリーンモードだった場合は通常モードに変更する WindowFullSize = FALSE ; // ウインドウスタイルを標準に変更 SetWindowStyleMode( 0 ) ; // ウインドウサイズを 640x480 に変更 SetWindowSize( SCREEN_SIZE_X, SCREEN_SIZE_Y ) ; // ウインドウを最大化前の座標に移動 SetWindowPosition( WindowPosX, WindowPosY ) ; } else { // 通常モードだった場合はフルスクリーンモードに変更する WindowFullSize = TRUE ; // 現在のウインドウの位置を取得しておく GetWindowPosition( &WindowPosX, &WindowPosY ) ; // ウインドウスタイルを枠なしに変更 SetWindowStyleMode( 4 ) ; // ウインドウのサイズをデスクトップと同じにする SetWindowSize( DesktopSizeX, DesktopSizeY ) ; // ウインドウの位置を画面左上に変更 SetWindowPosition( 0, 0 ) ; } } // 移動 x += add ; if( x < 0 || x > 640 ) add = -add ; // 画面のクリア ClearDrawScreen() ; // 画像の描画 DrawGraph( x, 0, handle, TRUE ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; } 画面の縦横比がデスクトップ画面の縦横比と異なる場合でも横に引き伸ばされたりしないようにする場合は、 以下のサンプルのように画面の解像度をデスクトップと同じにして、 フルスクリーン時のデスクトップ全体への拡大描画を自前で行うようにする必要があります #include "DxLib.h" #define SCREEN_SIZE_X 640 #define SCREEN_SIZE_Y 480 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int handle, x, add ; int SubScreen ; int WindowFullSize ; int WindowPosX ; int WindowPosY ; int DesktopSizeX ; int DesktopSizeY ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // デスクトップのサイズを取得する GetDefaultState( &DesktopSizeX, &DesktopSizeY, NULL ) ; // ウインドウのサイズが変化しても拡大しない設定にする SetWindowSizeChangeEnableFlag( FALSE, FALSE ) ; // 画面サイズをデスクトップサイズに設定 SetGraphMode( DesktopSizeX, DesktopSizeY, 32 ) ; // ウインドウの初期サイズは実際の処理用のサイズ SetWindowSize( SCREEN_SIZE_X, SCREEN_SIZE_Y ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // フルスクリーンモード時に使用する実際の処理用の解像度を持つ仮画面を作成 SubScreen = MakeScreen( SCREEN_SIZE_X, SCREEN_SIZE_Y ) ; // 画像の読み込み handle = LoadGraph( "Test1.bmp" ) ; // フルスクリーンモードかどうかのフラグを倒しておく WindowFullSize = FALSE ; // メインループ(何かキーが押されたらループを抜ける) x = 0 ; add = 8 ; while( ProcessMessage() == 0 ) { // スペースキーが押されたらウインドウのフルスクリーンモードと通常モードを切り替える if( GetInputChar( TRUE ) == ' ' ) { if( WindowFullSize ) { // フルスクリーンモードだった場合は通常モードに変更する WindowFullSize = FALSE ; // ウインドウスタイルを標準に変更 SetWindowStyleMode( 0 ) ; // ウインドウサイズを 640x480 に変更 SetWindowSize( SCREEN_SIZE_X, SCREEN_SIZE_Y ) ; // ウインドウを最大化前の座標に移動 SetWindowPosition( WindowPosX, WindowPosY ) ; } else { // 通常モードだった場合はフルスクリーンモードに変更する WindowFullSize = TRUE ; // 現在のウインドウの位置を取得しておく GetWindowPosition( &WindowPosX, &WindowPosY ) ; // ウインドウスタイルを枠なしに変更 SetWindowStyleMode( 4 ) ; // ウインドウのサイズをデスクトップと同じにする SetWindowSize( DesktopSizeX, DesktopSizeY ) ; // ウインドウの位置を画面左上に変更 SetWindowPosition( 0, 0 ) ; // 裏画面をクリア SetDrawScreen( DX_SCREEN_BACK ) ; ClearDrawScreen() ; } } // 移動 x += add ; if( x < 0 || x > 640 ) add = -add ; // フルスクリーンモードかどうかで処理を分岐 if( WindowFullSize ) { // フルスクリーンモードの場合 // 描画先を仮画面に変更 SetDrawScreen( SubScreen ) ; } else { // 通常モードの場合 // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; } // 画面のクリア ClearDrawScreen() ; // 画像の描画 DrawGraph( x, 0, handle, TRUE ) ; // フルスクリーンモードの場合のみ仮画面を拡大して裏画面に描画する処理を行う if( WindowFullSize ) { int DrawSizeX ; int DrawSizeY ; // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // 仮画面をデスクトップ画面の中心に拡大して描画する if( ( float )SCREEN_SIZE_X / SCREEN_SIZE_Y < ( float )DesktopSizeX / DesktopSizeY ) { DrawSizeX = DesktopSizeY * SCREEN_SIZE_X / SCREEN_SIZE_Y ; DrawSizeY = DesktopSizeY ; } else { DrawSizeX = DesktopSizeX ; DrawSizeY = DesktopSizeX * SCREEN_SIZE_Y / SCREEN_SIZE_X ; } DrawExtendGraph( ( DesktopSizeX - DrawSizeX ) / 2, ( DesktopSizeY - DrawSizeY ) / 2, DesktopSizeX - ( DesktopSizeX - DrawSizeX ) / 2, DesktopSizeY - ( DesktopSizeY - DrawSizeY ) / 2, SubScreen, FALSE ) ; } // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; } 因みにこの方式のフルスクリーンモードはウインドウモードとの切り替えが早い代わりに、 本来のフルスクリーンモードに比べて処理負荷が高いことと、本来のフルスクリーンモードでのみ 使用できるVSYNCを使用した表画面と裏画面の切り替えができないのでティアリングが発生するという 二つのデメリットがあります
メンテ
Re: ウィンドウモード切り換えについて ( No.3 )
名前:Saucer (解決) 日時:2014/08/28 01:52

なるほど、そういう仕組みでしたか。 自作ソフトでウィンドウを大きくすると処理落ちした 経験があり、他ライブラリのフルスクリーン時では 別にそんなことはなかったのでその可能性は薄いと思っていました。 ご教導いただき、まことに有難うございました。 書いて下さったソース、大変勉強になりました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存