注目キーワード
  1. Web
  2. GUI
  3. DirectX

DirectX11 | 3. ブルー画面で初期化

前回の記事(2. DX11の導入)では、DirectXを導入しただけでしたが、

今回は初期化されたブルー画面を表示しようと思います。

プロジェクトの作成

前回同様にプロジェクトを新しく作成します。

プロジェクト名は、” 0003_BlueScreen “としておきましょう。

ソースコード

以下がソースです。これも前回同様、流れが分かりやすいようにmain.cppだけでまとめました。

学習用のためにこれからもずっとmain.cppだけにまとめようと思っています。

ファイル分け、クラス分けは応用編でやりましょう。

以下のソースをコピペするか、ダウンロードしてVisual Studio の「ソースファイル」に保存してください。

コピペするなら、
「ソースファイル」で右クリックして
「追加」→「新しい項目」で、「C++ ファイル」を選び、名前を” main.cpp “にして追加ボタンを押して作成してください。

ダウンロードなら、
同じく「ソースファイル」で右クリックして
「追加」→「既存の項目」で、main.cppを選択して追加してください。

#include <windows.h>
#include <wrl.h>
#include <vector>
// DirectX11のコードセット
#include <d3d11.h>
#include <directxmath.h>
// ライブラリ
#pragma comment(lib, "d3d11.lib")
#define WINDOW_CLASS L"ブルー画面で初期化"
#define WINDOW_TITLE WINDOW_CLASS
#define WINDOW_WIDTH 750
#define WINDOW_HEIGHT 500
// プロトタイプ宣言
LRESULT CALLBACK WindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam); // ウィンドウプロシージャ
HRESULT OnInit(HWND hWnd); // 初期化
void OnRender(); // 描画
// usingディレクティブ
using namespace DirectX;
using Microsoft::WRL::ComPtr;
// パイプラインオブジェクト
ComPtr<ID3D11Device> g_device;
ComPtr<ID3D11DeviceContext> g_context;
ComPtr<IDXGISwapChain> g_swapChain;
ComPtr<ID3D11RenderTargetView> g_renderTargetView;
// メイン関数
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT nCmdShow)
{
// ウィンドウクラスを初期化
WNDCLASSEX windowClass = {};
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WindowProc;
windowClass.hInstance = hInstance;
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.lpszClassName = WINDOW_CLASS;
RegisterClassEx(&windowClass);
// ウィンドウのサイズを求める
RECT windowRect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE);
// ウィンドウハンドルを作成
HWND hWnd = CreateWindow(
WINDOW_CLASS,
WINDOW_TITLE,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top,
nullptr,
nullptr,
hInstance,
nullptr);
MSG msg;
ZeroMemory(&msg, sizeof(msg));
if (SUCCEEDED(OnInit(hWnd))) // DirectXの初期化
{
// ウィンドウの表示
ShowWindow(hWnd, SW_SHOW);
// メインループ
while (msg.message != WM_QUIT)
{
// キュー内のメッセージを処理
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// 描画
OnRender();
}
}
}
// WM_QUITメッセージの部分をWindowsに返す
return static_cast<char>(msg.wParam);
}
// ウィンドウプロシージャ
LRESULT CALLBACK WindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
switch (nMsg)
{
case WM_DESTROY: // 終了時
PostQuitMessage(0);
return 0;
}
// switch文が処理しなかったメッセージを処理
return DefWindowProc(hWnd, nMsg, wParam, lParam);
}
// 初期化
HRESULT OnInit(HWND hWnd)
{
// ドライバー種別を定義
std::vector<D3D_DRIVER_TYPE> driverTypes
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
D3D_DRIVER_TYPE_SOFTWARE,
};
// スワップチェインの作成
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferDesc.Width = WINDOW_WIDTH;
swapChainDesc.BufferDesc.Height = WINDOW_HEIGHT;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.Windowed = TRUE;
// ドライバー種別を上から検証し選択
// 選択したデバイスを用いて描画する
HRESULT hr;
for (size_t i = 0; i < driverTypes.size(); i++)
{
hr = D3D11CreateDeviceAndSwapChain(
nullptr,
driverTypes[i],
nullptr,
0,
nullptr,
0,
D3D11_SDK_VERSION,
&swapChainDesc,
g_swapChain.GetAddressOf(),
g_device.GetAddressOf(),
nullptr,
g_context.GetAddressOf()
);
if (SUCCEEDED(hr)) break;
}
if (FAILED(hr))
{
MessageBox(NULL, L"DirectX11に対応していないデバイスです。", WINDOW_TITLE, MB_OK | MB_ICONERROR);
return E_FAIL;
}
// 表示領域を作成
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(viewport));
viewport.Width = WINDOW_WIDTH;
viewport.Height = WINDOW_HEIGHT;
viewport.MinDepth = D3D11_MIN_DEPTH; // 0.0f
viewport.MaxDepth = D3D11_MAX_DEPTH; // 1.0f
g_context->RSSetViewports(1, &viewport);
// バックバッファを作成
ComPtr<ID3D11Texture2D> backBuffer;
g_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(backBuffer.GetAddressOf()));
g_device->CreateRenderTargetView(backBuffer.Get(), nullptr, g_renderTargetView.GetAddressOf());
// レンダーターゲットをバックバッファに設定
g_context->OMSetRenderTargets(1, g_renderTargetView.GetAddressOf(), nullptr);
// レンダーターゲットビューを指定した色でクリア
FLOAT clearColor[4] = { 0.0f, 0.0f, 1.0f, 1.0f }; // ブルー
g_context->ClearRenderTargetView(g_renderTargetView.Get(), clearColor);
return S_OK;
}
// 描画
void OnRender()
{
// フレームを最終出力
g_swapChain->Present(0, 0); // フリップ
}
view raw BlueScreen.cpp hosted with ❤ by GitHub

以下のようになっていればOK。

以上で作成は完了です!!

ツールバーの「デバッグ」から「デバッグの開始(F5)」で実行できます。

ビルドするときは、「0003_BlueScreen」を右クリックして「スタートアップ プロジェクトに設定」を押してプロジェクトターゲットを変更してからするようにしてください。

ブルー画面が表示できたら終わりです。お疲れさまでした。

最後に

学習を進めていく中でバージョンアップによる差分をすぐに確認できるように「WinMerge」というソフトを導入した方がすぐにでもプログラムを理解できるようになるかと思います。

この作例では、記事「DirectX11 | 2. DX11の導入」でのmain.cppと今回のmain.cppとで差分を確認して学習に活かしてください。

何のコードが変更されたり追加されたのかがすぐに分かります。

最新情報をチェックしよう!