DirectXTK講座 第2回:Direct3D 11のテンプレート導入からウィンドウを表示まで

Share
DirectXTK講座 第2回:Direct3D 11のテンプレート導入からウィンドウを表示まで

DirectXTK講座 第2回:Direct3D 11のテンプレートを導入してウィンドウを表示しよう

今回は、DirectXTKを使ったプログラムを作る土台として、Direct3D 11のプロジェクトテンプレートをVisual Studioに導入し、実際にウィンドウが表示されるところまで確認してみよう!

使用するのは、Chuck Walbourn氏が公開している directx-vs-templates を使います。個人のリポジトリですが、MS公式からもリンクされており、ほぼ公式です。テンプレートを使うことで、あらかじめWindow1枚ぐらいペロッと出すところまでを作ってくれます。
そのために、テンプレートを自分の開発環境にインストールする必要があります。VS(VisualStudio)までは前回まででインストールできていると思うので、それにテンプレートを追加するって感じ。

1.Direct3D用テンプレートを入手する

まず、ブラウザ(なんでもいいよ)で次のGitHubリポジトリを開きます。

directx-vs-templates - GitHub

directx-vs-templatesのGitHubリポジトリ

リポジトリを開いたら、VSIX フォルダーを開いて、その中にある Direct3DUWPGame.vsix をダウンロードします。

Direct3DUWPGame.vsix

ファイル名には UWP と入っていますが、このVSIXにはUWP用だけでなく、Win32デスクトップ用のDirect3D 11 / Direct3D 12テンプレートも含まれています。(何のことかわからないと思うけど、気にしないでってことで大丈夫)

2.VSIXをインストールする

ダウンロードした Direct3DUWPGame.vsix を実行します。これがテンプレート本体(というか、テンプレートを読み込めるように設定してくれるスクリプトです)

VSIX Installerが起動したら、使用しているVisual Studioを選択してインストールします。Visual Studioを起動したままの場合は、いったん終了してから進めます。

VSIX自体は通常ユーザー単位でインストールされます。ただし、Visual Studio側に必要なコンポーネントが不足している場合は、Visual Studio Installerから追加する必要があります。

3.Direct3D Win32 Game VCPKGでプロジェクトを作る

Visual Studioを起動し、「新しいプロジェクトの作成」を開きます。

検索欄で Direct3D と検索すると、インストールしたテンプレートが表示されます。

今回は Direct3D Win32 Game VCPKG を選択します。

Visual StudioのDirect3D Win32 Game VCPKGテンプレート

このテンプレートは、次の構成になっています。

  • Direct3D 11
  • Win32デスクトップアプリケーション
  • DeviceResourcesによるDirect3Dデバイス管理
  • vcpkgによるライブラリ管理

名前に DR は付いていませんが、説明欄に DeviceResources abstraction とあるように、DeviceResourcesを使う構成です。

これもなんのこっちゃって感じだと思いますが、今は気にしなくていいです。とりあえずテンプレート側で面倒なデバイス周りの設定をまとめてクラス化してくれるってことだと思ってください。クラス化されてないと、全部の設定を自分で書くのと変わりない構成になってあまりうまみがないと思うので。(んで、こういうデバイス周りの設定とかを自分で書けないとゲーム業界じゃ使い物にならない、とかいう人いますが(業界に)最近この部分書いたのいつか聞いてみてください。多分10年前とか言うと思います笑)

4.プロジェクトを作成してビルドする

プロジェクト名と保存場所を指定してプロジェクトを作成します。これはどこでもいいよ。ドライブ分けてる人はCドライブ以外(D:とかの下ね)に作るのがいいと思う。
プロジェクト名などは任意でいいと思うよ。OK押すとそのままプロジェクトできるので、あとはビルドボタン(▶️)を押してみるだけ。

作成直後は、まず Debug / x64 のままビルドしてみます。

VCPKG版テンプレートでは、必要なライブラリが vcpkg.json に記述されています。初期状態では、次のように directxmath が登録されています。

{
  "dependencies": [
    "directxmath"
  ]
}

初回ビルドでは、Visual Studioがvcpkgを使って必要なパッケージを自動的に取得します。

Visual Studioがvcpkgの依存ライブラリを自動取得しているビルド出力

出力ウィンドウに Installing vcpkg dependencies と表示され、その後に directxmath などのパッケージ名が表示されます。

初回はパッケージの取得や準備が行われるため、通常のビルドより時間がかかることがあります。

。。。だけど、これも気にすることないと思うよ。とりあえずこれで自動でやってくれるって話。心配なのはVCPKGってみんな使えるのかな?
多分、インストール時にデスクトップ開発、にチェック入れると自動で追加されてるはず!(もしダメなときは、vsインストーラーを起動してvcpkgを検索してインストールして!)

5.実行してウィンドウを確認する

ビルドが完了したら、F5キーまたは「デバッグの開始」で実行します。

テンプレートの初期状態では、背景が青っぽい800×600のウィンドウが作成されます。

Direct3D Win32 Game VCPKGテンプレートを実行した画面

ここまで動けば、Win32ウィンドウの作成、Direct3D 11デバイスの準備、描画用バッファの準備、画面への表示までが動作しています。
ここまででも、自分で書くと結構大変です。ゲーム業界に就職したければ、この辺のハード制御やWindowsネイティブのプログラムも結構大事だとは思うけど、一番大事なのはゲームのロジックや、オブジェクトやリソースの管理のほうだと思う。今はほとんど、自社製のエンジンやツールで何とかするからね。エンジンプログラマ目指すならハード周りやWindowsプログラミングも頑張ってください。(ただし、就職作品としてまずみられるのはソースコードじゃなくゲームの完成度です!)

6.生成されたファイルを確認する

このテンプレートでは、Direct3D 11の初期化処理とゲームループがいくつかのファイルに分けられています。

  • Main.cpp:Win32ウィンドウの作成とメッセージループ
  • Game.h / Game.cpp:ゲームの初期化、更新、描画
  • DeviceResources.h / DeviceResources.cpp:Direct3Dのデバイスやスワップチェインなどの管理
  • StepTimer.h:フレームごとの時間管理
  • vcpkg.json:vcpkgで使用する依存ライブラリの一覧

最初からすべてのコードを読む必要はありません。まずは、どのファイルが何を担当しているのかを把握しておきます。

7.Main.cppはウィンドウとメインループを担当する

Main.cpp には、Windowsアプリケーションの入口となる wWinMain() があります。

ここでは、ウィンドウクラスの登録、CreateWindowExW() によるウィンドウ作成、Windowsメッセージの処理などが行われています。

メッセージを処理していない間は、Game::Tick() が繰り返し呼ばれます。

wWinMain()
  ├─ ウィンドウを作る
  ├─ Game::Initialize()
  └─ メインループ
       └─ Game::Tick()

つまり、Win32側の処理は Main.cpp、ゲーム側の処理は Game クラスという形に分けられています。

8.Gameクラスがゲームの中心になる

Game クラスには、ゲームを動かすための基本的な処理がまとめられています。

特に重要なのは、次の流れです。

Initialize()
    ↓
Tick()
 ├─ Update()
 └─ Render()
      ├─ Clear()
      └─ Present()

Initialize() はゲーム開始時の初期化、Update() はゲーム状態の更新、Render() は画面描画を担当します。

Tick() が毎フレーム呼ばれ、その中から Update() と Render() が実行される構造です。

9.Gameクラスの主なメンバ

Game.h には、最初から次の2つの重要なメンバが用意されています。

std::unique_ptr<DX::DeviceResources> m_deviceResources;
DX::StepTimer                         m_timer;

m_deviceResources

m_deviceResources は、Direct3D 11の描画に必要なリソースをまとめて管理します。

主に、Direct3Dデバイス、デバイスコンテキスト、スワップチェイン、レンダーターゲット、深度ステンシルなどを保持しています。

Gameクラスは必要に応じて、GetD3DDevice() や GetD3DDeviceContext() などを使ってこれらにアクセスします。

m_timer

m_timer は、フレームごとの経過時間を管理するための StepTimer です。

Tick() 内で時間を更新し、その情報を Update() に渡します。ゲーム内の移動速度やアニメーションをフレームレートに依存させないために使える仕組みです。

10.DeviceResourcesはDirect3Dの初期化をまとめている

DeviceResourcesを使わないテンプレートでは、Direct3Dデバイス、スワップチェイン、レンダーターゲットなどの作成処理がGameクラス側に直接書かれています。

今回使用しているVCPKG版では、それらを DeviceResources クラスに分離しています。

Game
 ├─ Update
 ├─ Render
 └─ DeviceResources
      ├─ Device
      ├─ DeviceContext
      ├─ SwapChain
      ├─ RenderTarget
      ├─ DepthStencil
      └─ Present

初期化処理が消えているわけではありません。DeviceResources.cpp を開けば、Direct3D 11のデバイスやスワップチェインをどのように作っているか確認できます。

ゲームを作る側では、Direct3D 11の初期化処理を毎回書かずに、Gameクラスの更新と描画に集中できる構成になっています。

まとめ

今回は、Direct3D用のVSIXテンプレートをVisual Studioへ追加し、Direct3D Win32 Game VCPKG からプロジェクトを作成しました。

テンプレートをそのままビルドするだけでも、Win32ウィンドウ、Direct3D 11デバイス、スワップチェイン、描画用バッファ、ゲームループ、時間管理までが用意されています。

コードを見るときは、まず Main.cpp、Game.cpp、DeviceResources.cpp、StepTimer.h の役割を分けて考えると、全体の構造を追いやすくなります。

うまくいかない場合

Direct3D Win32 Game VCPKGが表示されない

VSIXのインストール後にVisual Studioを再起動してください。

それでも表示されない場合は、「新しいプロジェクトの作成」で Direct3D と検索して確認します。

vcpkgのエラーが出る

Visual Studio Installerを開き、使用しているVisual Studioの「変更」から vcpkg Package Manager がインストールされているか確認します。

VCPKG版テンプレートは、このコンポーネントを使用します。

初回ビルドに時間がかかる

初回ビルドではvcpkgが依存ライブラリを取得するため、時間がかかることがあります。出力ウィンドウに処理が続いている場合は、そのまま完了まで待ちます。

Read more

どうしてWindowsはCドライブから始まるの? AとBはどこへ行った?

どうしてWindowsはCドライブから始まるの? AとBはどこへ行った?

どうしてWindowsはCドライブから始まるの? AとBはどこへ行った? Windowsを使っていると、システムが入っているドライブってだいたい C: ですよね。 でも、よく考えると変じゃないですか? アルファベットなら普通はAから始まりそうなのに、なんでいきなりCなの? じゃあ、 A: B: はどこに行ったんだよ、って話です。 これ、別にCに何か特別な意味があるわけじゃありません。 昔、AとBを先に使っちゃったから、その次がCになった。 だいたいそれだけの話です。 そもそも「Cドライブ」ってWindows系の文化 まず、C: とか D: とかいう呼び方は、今だとWindowsでおなじみのものです。 LinuxやmacOSでは、基本的にこんな呼び方はしません。 Linuxなんかだと、 / ├─ home ├─ usr ├─ var └─ ... みたいに / を一番上にして、ディスクもそのディレクトリ構造の中にくっつけて使います。 じゃあWindowsの C: D: E: はどこから来たのか。 Windowsより前の MS-DOS です。 ……