DirectX 9 フルスクリーンモードについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Waon

DirectX 9 フルスクリーンモードについて

#1

投稿記事 by Waon » 6年前

こんにちは。
Direct3D 9 で、フルスクリーン表示しようとしたのですが、うまくいきません。

開発環境は、Visual Studio 2017 Community の C++言語です。
パソコンは、Windows 10です。(実装メモリ 4GB、64ビットオペレーティングシステム)

ウィンドウモードではうまくいきますが、
フルスクリーンモードの場合、Direct3D 9 デバイスの作成に失敗します。
▼以下、コードです。

コード:

#pragma comment( lib, "d3d9.lib" )
#pragma comment( lib, "d3dx9.lib" )

#include < d3d9.h >
#include < d3dx9.h >
#include < windows.h >
#include < tchar.h >


//グローバル
LPDIRECT3D9 g_pD3D;
LPDIRECT3DDEVICE9 g_pD3DDev;

//ウィンドウハンドル
HWND g_hWnd;
const UINT g_kBackBufferWidth = 800;
const UINT g_kBackBufferHeight = 600;

//タイトル名
TCHAR g_title_name[100] = _T("Test");
//ウィンドウモード
bool g_window_style = false;

//コールバック関数
LRESULT CALLBACK WndProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam)
{
	if (mes == WM_DESTROY)
	{
		//解放
		g_pD3DDev->Release();
		g_pD3D->Release();
		PostQuitMessage(0);
		return 0;
	}

	//デフォルトウィンドウ状態
	return DefWindowProc(hWnd, mes, wParam, lParam);
}

/*
メイン開始
*/
int WINAPI WinMain(HINSTANCE _h_instans, HINSTANCE _h_prev_instans, LPSTR _cmd_lint, int n_show_cmd)
{
	//ウィンドウ情報初期化
	WNDCLASSEX wcex;
	ZeroMemory(&wcex, sizeof(wcex));
	wcex.lpfnWndProc = WndProc;
	wcex.hInstance = _h_instans;
	wcex.lpszClassName = (TCHAR*)g_title_name;
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpszMenuName = (TCHAR*)g_title_name;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

	//ウィンドウ登録失敗
	if (!RegisterClassEx(&wcex))
	{
		return 0;
	}

	//ウィンドウ生成
	g_hWnd = CreateWindow(g_title_name, g_title_name, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
						  NULL, NULL, _h_instans, NULL);

	//作成判定
	if (!g_hWnd)
	{
		MessageBox(NULL, _T("ウィンドウ生成に失敗"), _T(""), MB_OK);
		//失敗
		return 0;
	}

	// Direct3Dの初期化
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	//作成判定
	if (!g_pD3D)
	{
		MessageBox(NULL, _T("Direct3D 9 の初期化に失敗"), _T(""), MB_OK);
		return 0;
	}

	//プレゼンパラメータ
	D3DPRESENT_PARAMETERS window_parameter;
	ZeroMemory(&window_parameter, sizeof(window_parameter));

	//バックバッファ設定
	window_parameter.BackBufferHeight = g_kBackBufferHeight;	// バックバッファの高さ
	window_parameter.BackBufferWidth = g_kBackBufferWidth;		// バックバッファの幅
																//ウィンドウ特有
	window_parameter.BackBufferFormat = D3DFMT_UNKNOWN;		// フォーマットは今の画面モードに従う	
	window_parameter.Windowed = g_window_style;			// ウィンドウモード
														//共通パラメータ
	window_parameter.BackBufferCount = 1;					// バックバッファの数
	window_parameter.MultiSampleType = D3DMULTISAMPLE_NONE;	// マルチサンプリングは行わない
	window_parameter.MultiSampleQuality = 0;					// マルチサンプリングは行わないので0
	window_parameter.SwapEffect = D3DSWAPEFFECT_DISCARD;// Direct3Dにスワップエフェクトを任せる
	window_parameter.EnableAutoDepthStencil = TRUE;					// Direct3Dに深度バッファの管理を任せる
	window_parameter.AutoDepthStencilFormat = D3DFMT_D16;			// 深度バッファのフォーマット(通常はこの値で問題ない)
	window_parameter.hDeviceWindow = g_hWnd;					// デバイスウィンドウ
	window_parameter.Flags = 0;
	if (g_window_style == true) {
		window_parameter.FullScreen_RefreshRateInHz = 0;//ウィンドウモードの時は0
	}
	else {
		window_parameter.FullScreen_RefreshRateInHz = 60;
	}
	window_parameter.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;	// モニタの垂直回帰を待つ

	//デバイス作成
	HRESULT Hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
									  D3DCREATE_SOFTWARE_VERTEXPROCESSING, &window_parameter, &g_pD3DDev);
	//★ここです★//
	if (FAILED(Hr))
	{
		if (Hr == D3DERR_INVALIDCALL)
		{
			MessageBox(NULL, _T("D3DERR_INVALIDCALL"), _T(""), MB_OK);
		}
		if (Hr == D3DERR_NOTAVAILABLE)
		{
			MessageBox(NULL, _T("D3DERR_NOTAVAILABLE"), _T(""), MB_OK);
		}
		if (Hr == D3DERR_OUTOFVIDEOMEMORY)
		{
			MessageBox(NULL, _T("D3DERR_OUTOFVIDEOMEMORY"), _T(""), MB_OK);
		}
		MessageBox(NULL, _T("Direct3D 9 のデバイス作成に失敗"), _T(""), MB_OK);
		g_pD3D->Release();
		return 0;
	}

	//ウィンドウ作成
	ShowWindow(g_hWnd, n_show_cmd);

	// メッセージ ループ
	MSG msg;
	do
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			DispatchMessage(&msg);
		}
		else
		{
			// Direct3Dの処理
			g_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 128), 1.0f, 0);
			g_pD3DDev->BeginScene();
			// 描画
			g_pD3DDev->EndScene();
			g_pD3DDev->Present(NULL, NULL, NULL, NULL);
		}

	} while (msg.message != WM_QUIT);

	//終了
	return 0;
}
CreateDeviceの戻り値を確認してみると、
「D3DERR_INVALIDCALL」が返ってきていました。

D3DERR_INVALIDCALLはMSDNによると、

「メソッドの呼び出しが無効である。たとえば、メソッドのパラメータに無効な値が設定されている場合などである。」

だそうです。

プレゼントパラメータ(window_parameter)の値の中で、
なにかフルスクリーンモードではだめなものを指定しているんじゃないかと思って
色々といじってみたものの、結局だめでした。

どうすれば、フルスクリーンモードに変更できるのでしょうか?
教えてください・・・。

アバター
V30
記事: 21
登録日時: 9年前
住所: 岡山県

Re: DirectX 9 フルスクリーンモードについて

#2

投稿記事 by V30 » 6年前

D3DFMT_UNKNOWNは、ウィンドウモード時のみ有効です。

コード:

window_parameter.BackBufferFormat = D3DFMT_UNKNOWN;
を、

コード:

window_parameter.BackBufferFormat = D3DFMT_A8R8G8B8;
のように変更すれば、INVALIDCALLは出ないかと思います。
但し、D3DFMT_A8R8G8B8が、必ずしも有効であるとは限りません。

フルスクリーンモードで使用可能なフォーマットは、
IDirect3D9::CheckDeviceTypeメソッドで検証します。

[参考]
https://msdn.microsoft.com/ja-jp/library/cc323931.aspx
https://msdn.microsoft.com/ja-jp/library/cc324297.aspx
https://msdn.microsoft.com/ja-jp/library/cc324320.aspx
オフトピック
あと、当該コードを実行の際は、
コールバック関数に

コード:

	if (mes == WM_LBUTTONDOWN)
	{
		PostQuitMessage(0);
		return 0;
	}
のような、フルスクリーンアプリ終了手段を付加することをお奨めします。
素人的な質問は、素人に聞こう!

危ない危ない。
ちゃんとした人に質問しましょう。
ちなみに私は、ちゃんとしていない素人です。

アバター
V30
記事: 21
登録日時: 9年前
住所: 岡山県

Re: DirectX 9 フルスクリーンモードについて

#3

投稿記事 by V30 » 6年前

あっ!
V30 さんが書きました:
オフトピック
あと、当該コードを実行の際は、
コールバック関数に

コード:

	if (mes == WM_LBUTTONDOWN)
	{
		PostQuitMessage(0);
		return 0;
	}
のような、フルスクリーンアプリ終了手段を付加することをお奨めします。
↑上記コードをそのままご使用の場合は、

コード:

	if (g_pD3DDev) g_pD3DDev->Release();
	if (g_pD3D) g_pD3D->Release();
を然るべき所へ挿入し、メモリリーク防止しをお忘れなく。

スマポの使いすぎで、解放作業を忘れていました。m(_ _)m
素人的な質問は、素人に聞こう!

危ない危ない。
ちゃんとした人に質問しましょう。
ちなみに私は、ちゃんとしていない素人です。

Waon

Re: DirectX 9 フルスクリーンモードについて

#4

投稿記事 by Waon » 6年前

返信が大変遅くなり申し訳ございません・・・!!
無事フルスクリーンになりました!
ありがとうございました。 (*`・ω・)ゞ

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectX 9 フルスクリーンモードについて

#5

投稿記事 by ISLe » 6年前

オフトピック
ご存知の方には余計なお世話ですが、ウィンドウズアプリケーションは Alt+F4 (Altキーを押したままF4キーを押す)で終了できます。
フルスクリーンモードのアプリケーションでも有効なので終了方法が分からないとき試してみてください。

返信

“C言語何でも質問掲示板” へ戻る