合計 昨日 今日

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

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: Waon
[URL]
Date: 2017年12月03日(日) 17:44
No: 1
(OFFLINE)

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

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

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

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

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#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)の値の中で、
なにかフルスクリーンモードではだめなものを指定しているんじゃないかと思って
色々といじってみたものの、結局だめでした。

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

Name: V30
[URL]
熟練のプログラマー(61,174 ポイント)
Date: 2017年12月04日(月) 17:35
No: 2
(OFFLINE)

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

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

コード[C++]: 全て選択
1
window_parameter.BackBufferFormat = D3DFMT_UNKNOWN;

を、
コード[C++]: 全て選択
1
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

Offtopic :
あと、当該コードを実行の際は、
コールバック関数に
コード[C++]: 全て選択
1
2
3
4
5
    if (mes == WM_LBUTTONDOWN)
    {
        PostQuitMessage(0);
        return 0;
    }

のような、フルスクリーンアプリ終了手段を付加することをお奨めします。
素人的な質問は、素人に聞こう!

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

Name: V30
[URL]
熟練のプログラマー(61,174 ポイント)
Date: 2017年12月04日(月) 20:08
No: 3
(OFFLINE)

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

あっ!
V30 さんが書きました:
Offtopic :
あと、当該コードを実行の際は、
コールバック関数に
コード[C++]: 全て選択
1
2
3
4
5
    if (mes == WM_LBUTTONDOWN)
    {
        PostQuitMessage(0);
        return 0;
    }

のような、フルスクリーンアプリ終了手段を付加することをお奨めします。

↑上記コードをそのままご使用の場合は、
コード[C++]: 全て選択
1
2
    if (g_pD3DDev) g_pD3DDev->Release();
    if (g_pD3D) g_pD3D->Release();

を然るべき所へ挿入し、メモリリーク防止しをお忘れなく。

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

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

Name: Waon
[URL]
Date: 2017年12月12日(火) 17:07
No: 4
(OFFLINE)

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

[解決!]

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

Name: ISLe
[URL]
ハッカー(265,720 ポイント)
Date: 2017年12月12日(火) 17:33
No: 5
(OFFLINE)

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

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


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[13人]