DirectX12 ① ウィンドウの作成
開発環境
言語 : C++
開発環境 : Visual Studio 2020
OS : Windows10
CPU : AMD Ryzen5 3600
RAM : 24.0GB
GPU : NVIDIA GeForce GTX 1050
DirectX12について
ここでは、Direct3D 12のことをDirectX12と呼ぶ。DirectX12は、Microsoftが開発する、DirectX12互換GPUを搭載したPCにおいてグラフィックス機能や計算機能をアプリケーションで利用すためのAPIである。
Win32 APIについて
ウィンドウの表示にはWin32 APIを使う。
Win32 APIは、ウィンドウの描画などWindowsの機能を使用するためのAPIである。
DirectX12はOpenGLのようにglutやGLFWなどの簡単にウィンドウを表示するための機能がないため、Win32 APIによってウィンドウの表示を行う。
main.cpp
#include "App.h" int main() { App app(1080, 720); app.Run(); }
App.h
#pragma once #include <Windows.h> #include <cstdint> #include <string> class App { public: App(uint32_t width, uint32_t height); void Run(); private: bool InitApp(); bool InitWindow(); void MainLoop(); static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); private: const std::wstring WindowClassName = L"WindowClass"; uint32_t _width; uint32_t _height; HWND _hwnd; HINSTANCE _hInstance; };
App.cpp
#include "App.h" App::App(uint32_t width, uint32_t height) { _width = width; _height = height; _hwnd = nullptr; _hInstance = nullptr; } void App::Run() { if (!InitApp()) { return; } MainLoop(); } //初期化 bool App::InitApp() { if (!InitWindow()) { return false; } return true; } //ウィンドウの初期化 bool App::InitWindow() { _hInstance = GetModuleHandle(nullptr); if (_hInstance == nullptr) { return false; } //ウィンドウの設定 WNDCLASSEX wc = {}; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; //水平方向と垂直方向のサイズ変更で再描画 wc.lpfnWndProc = WndProc; //ウィンドウプロシージャの登録 wc.hIcon = LoadIcon(_hInstance, IDI_APPLICATION); //アイコン wc.hCursor = LoadCursor(_hInstance, IDC_ARROW); //マウスカーソル wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //背景色は黒 wc.hInstance = _hInstance; //インスタンスハンドル wc.lpszMenuName = nullptr; //メニュー wc.lpszClassName = WindowClassName.c_str(); //ウィンドウクラスの名前 wc.hIconSm = LoadIcon(_hInstance, IDI_APPLICATION); //小さいアイコン RegisterClassEx(&wc); //ウィンドウクラスの登録 //ウィンドウサイズ RECT rc = {}; rc.right = static_cast<long>(_width); //ウィンドウの幅 rc.bottom = static_cast<long>(_height); //ウィンドウの高さ auto style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; AdjustWindowRect(&rc, style, false); _hwnd = CreateWindowEx( 0, WindowClassName.c_str(), L"Title", style, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, _hInstance, nullptr ); ShowWindow(_hwnd, SW_SHOWNORMAL); SetFocus(_hwnd); return true; } //メインループ void App::MainLoop() { MSG msg = {}; while (WM_QUIT != msg.message) { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE == true)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { // ここに描画処理を書く } } } //ウィンドウプロシージャ LRESULT CALLBACK App::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; default: break; } return DefWindowProc(hwnd, msg, wParam, lParam); }
実行結果