> ## Content Index
> Fetch the complete content index at: https://www.geekjp.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# DirectXTKでゲーム制作  第1回：DirectXTKとは何か
- URL: https://www.geekjp.com/directxtk-lesson01/
- Published: 2026-10-05T13:47:41.000Z
- Updated: 2026-10-05T14:03:04.000Z
- Description: DirectXTKの役割、できること、ゲームエンジンとの違い、主要APIの分類を整理します。
- Author: 工学じじい
- Tags: DirectXTK, Direct3D 11, C++, #Import 2026-10-05 22:41

Direct3D 11でゲームを作ろうとすると、画面に1枚の画像を出すだけでも、頂点やシェーダー、描画状態、テクスチャなど多くの準備が必要になります。DirectXTK（DirectX Tool Kit）は、そうした定番処理を使いやすいC++クラスとしてまとめたライブラリです。

ただし、DirectXTKはゲームエンジンではありません。ここを最初に区別しておくと、「何を任せられて、何を自分で作るのか」が見通しやすくなります。

## DirectXTKとは

DirectXTKは、MicrosoftがGitHubで公開している、Direct3D向けのヘルパークラス集です。Direct3Dそのものを置き換えるのではなく、その上に薄い便利な層を加えます。

たとえば、2D画像をまとめて描画する`SpriteBatch`、ビットマップフォントを描画する`SpriteFont`、基本的な3D形状を生成して描く`GeometricPrimitive`などが用意されています。毎回ゼロから書くと長くなりやすい処理を、再利用しやすい形で使えるのが特徴です。

![Direct3D 11などの低レベルAPI、その上のDirectXTK、さらに上のゲーム固有コードという三層構造](https://www.geekjp.com/content/images/2026/10/01-directxtk-position-1.png)

DirectXTKは低レベルAPIとゲーム固有コードの間に置く補助ライブラリ

重要なのは、DirectXTKを使ってもDirect3D 11を扱っている事実は変わらないことです。デバイスやデバイスコンテキスト、レンダーターゲット、フレーム単位の更新と描画といった基本構造は、アプリケーション側が管理します。

## DirectXTKで何ができるか

DirectXTKの機能は、目的別の部品として捉えると分かりやすくなります。

![DirectXTKの主要機能を2D描画、3D描画、テクスチャ、状態と数学、入力、音声の6分類で示した図](https://www.geekjp.com/content/images/2026/10/02-directxtk-features-1.png)

DirectXTKの主要機能は、必要なものだけ選んで利用できる

### 2D描画と文字

`SpriteBatch`は、テクスチャを2Dスプライトとして効率よく描画するためのクラスです。位置、回転、拡大縮小、色、描画順などを指定できます。`SpriteFont`と組み合わせれば、画面上に文字を描画できます。HUD、メニュー、デバッグ表示などに向いています。

### 3D描画の補助

`GeometricPrimitive`は立方体や球などの基本形状を生成して描画します。`Model`は対応形式のメッシュを読み込み、`Effects`は一般的な描画に使える組み込みシェーダーを提供します。`PrimitiveBatch`や`VertexTypes`は、独自の頂点を使った描画を組み立てるときに役立ちます。

### テクスチャの読み込みと画面保存

`DDSTextureLoader`はDDS、`WICTextureLoader`はPNGやJPEGなどをDirect3Dのテクスチャとして読み込むための軽量ローダーです。`ScreenGrab`を使えば、描画結果を画像として保存できます。

### 描画状態、リソース、数学

`CommonStates`は、ブレンド、深度ステンシル、ラスタライザー、サンプラーといった定番の描画状態をまとめて提供します。`BufferHelpers`や`GraphicsMemory`はリソース作成や動的メモリ管理を補助し、`SimpleMath`はDirectXMathを扱いやすいC++型で包みます。

### 入力

`Keyboard`、`Mouse`、`GamePad`は、各入力デバイスの現在状態や前フレームからの変化を扱いやすくします。入力APIの細部を毎回直接処理する負担を減らせます。

### 音声

`AudioEngine`、`SoundEffect`、`WaveBank`などを使い、XAudio2を基盤とした効果音や音声の再生を組み立てられます。

## DirectXTKはゲームエンジンではない

UnityやUnreal Engineのようなゲームエンジンは、描画だけでなく、シーン管理、オブジェクト管理、物理、アニメーション、エディタ、アセットの取り込みなど、制作全体を支える大きな枠組みを提供します。

DirectXTKが提供するのは、そのうちの一部で使える便利な部品です。ゲームの実行方式やデータ構造まで決めるものではありません。

![DirectXTKが補助する描画、入力、音声などの領域と、自分で設計するゲームループ、シーン、ルールなどの領域を分けた図](https://www.geekjp.com/content/images/2026/10/03-directxtk-boundary-1.png)

DirectXTKが担当するのは便利な部品。ゲーム全体の設計はアプリケーション側が担う

つまり、DirectXTKを採用しても、少なくとも次のような部分は自分で設計します。

- 更新と描画を回すゲームループ
- タイトル、ゲーム中、結果画面などの状態遷移
- キャラクターや敵、弾などのオブジェクト管理
- 当たり判定、ゲームルール、AI
- アセットの所有方法と読み込みのタイミング

> DirectXTKは「ゲームを完成させる仕組み」ではなく、「Direct3D 11でゲームを作るときの定番作業を短くする道具」と考えるのが適切です。

## 初期化処理を任せると、利用側のコードはどう変わるか

DirectXTKの公式チュートリアルやVisual Studioテンプレートでは、`DeviceResources`という補助クラスを使って、Direct3Dデバイス、デバイスコンテキスト、スワップチェーン、レンダーターゲット、深度バッファなどの初期化と管理をまとめます。

ここでは、800×600のウィンドウを作り、背景色でクリアして表示するだけの最小例を比較します。どちらもWin32のウィンドウ作成とメッセージループは必要ですが、Direct3D 11の初期化部分が大きく変わります。

### Direct3D 11を直接初期化する場合

直書きでは、スワップチェーンの設定、デバイスとコンテキストの作成、バックバッファの取得、レンダーターゲットビューの作成、ビューポートの設定、COMオブジェクトの保持を自分で行います。

```cpp
#include <windows.h>
#include <d3d11.h>
#include <wrl/client.h>

#pragma comment(lib, "d3d11.lib")

using Microsoft::WRL::ComPtr;

ComPtr<ID3D11Device>           g_device;
ComPtr<ID3D11DeviceContext>    g_context;
ComPtr<IDXGISwapChain>         g_swapChain;
ComPtr<ID3D11RenderTargetView> g_renderTarget;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    if (msg == WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}

bool InitializeDirect3D(HWND hwnd)
{
    DXGI_SWAP_CHAIN_DESC desc{};
    desc.BufferDesc.Width = 800;
    desc.BufferDesc.Height = 600;
    desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    desc.SampleDesc.Count = 1;
    desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    desc.BufferCount = 2;
    desc.OutputWindow = hwnd;
    desc.Windowed = TRUE;
    desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

    D3D_FEATURE_LEVEL level{};
    if (FAILED(D3D11CreateDeviceAndSwapChain(
        nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0,
        nullptr, 0, D3D11_SDK_VERSION,
        &desc, &g_swapChain, &g_device, &level, &g_context)))
    {
        return false;
    }

    ComPtr<ID3D11Texture2D> backBuffer;
    if (FAILED(g_swapChain->GetBuffer(
        0, IID_PPV_ARGS(backBuffer.GetAddressOf()))))
    {
        return false;
    }

    if (FAILED(g_device->CreateRenderTargetView(
        backBuffer.Get(), nullptr, &g_renderTarget)))
    {
        return false;
    }

    D3D11_VIEWPORT viewport{};
    viewport.Width = 800.0f;
    viewport.Height = 600.0f;
    viewport.MaxDepth = 1.0f;
    g_context->RSSetViewports(1, &viewport);
    return true;
}

int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
{
    WNDCLASS wc{};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = instance;
    wc.lpszClassName = L"RawD3D11Window";
    RegisterClass(&wc);

    RECT rect{ 0, 0, 800, 600 };
    AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);

    HWND hwnd = CreateWindowEx(
        0, wc.lpszClassName, L"Direct3D 11 直書き",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        rect.right - rect.left, rect.bottom - rect.top,
        nullptr, nullptr, instance, nullptr);

    if (!hwnd || !InitializeDirect3D(hwnd)) return 1;
    ShowWindow(hwnd, show);

    MSG msg{};
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            continue;
        }

        const float color[] = { 0.08f, 0.12f, 0.20f, 1.0f };
        ID3D11RenderTargetView* target = g_renderTarget.Get();
        g_context->OMSetRenderTargets(1, &target, nullptr);
        g_context->ClearRenderTargetView(target, color);
        g_swapChain->Present(1, 0);
    }
    return 0;
}
```

### DirectXTK公式テンプレートのDeviceResourcesを使う場合

`DeviceResources`をプロジェクトに用意しておけば、利用側ではウィンドウを渡し、デバイス依存リソースとウィンドウサイズ依存リソースの作成を呼び出すだけです。描画時も、必要なオブジェクトをアクセサーから取得し、最後に`Present`を呼びます。

```cpp
#include <windows.h>
#include <memory>
#include "DeviceResources.h"

std::unique_ptr<DX::DeviceResources> g_deviceResources;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    if (msg == WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}

int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
{
    WNDCLASS wc{};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = instance;
    wc.lpszClassName = L"DirectXTKWindow";
    RegisterClass(&wc);

    RECT rect{ 0, 0, 800, 600 };
    AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);

    HWND hwnd = CreateWindowEx(
        0, wc.lpszClassName, L"DirectXTK + DeviceResources",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        rect.right - rect.left, rect.bottom - rect.top,
        nullptr, nullptr, instance, nullptr);

    if (!hwnd) return 1;
    ShowWindow(hwnd, show);

    // Direct3D 11の初期化をDeviceResourcesへ任せる
    g_deviceResources = std::make_unique<DX::DeviceResources>(
        DXGI_FORMAT_B8G8R8A8_UNORM,
        DXGI_FORMAT_UNKNOWN); // 今回は深度バッファ不要

    g_deviceResources->SetWindow(hwnd, 800, 600);
    g_deviceResources->CreateDeviceResources();
    g_deviceResources->CreateWindowSizeDependentResources();

    MSG msg{};
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            continue;
        }

        auto context = g_deviceResources->GetD3DDeviceContext();
        auto target = g_deviceResources->GetRenderTargetView();
        auto viewport = g_deviceResources->GetScreenViewport();

        const float color[] = { 0.08f, 0.12f, 0.20f, 1.0f };
        context->OMSetRenderTargets(1, &target, nullptr);
        context->RSSetViewports(1, &viewport);
        context->ClearRenderTargetView(target, color);

        g_deviceResources->Present();
    }
    return 0;
}
```

比較すると、直書き版にあった`DXGI_SWAP_CHAIN_DESC`の設定、`D3D11CreateDeviceAndSwapChain`、バックバッファの取得、レンダーターゲットビューの生成が、利用側のコードから消えています。さらに公式の`DeviceResources`は、ウィンドウサイズ変更時のリソース再作成、デバイスロストからの復旧、デバッグレイヤーがない環境でのフォールバックなどもまとめて扱います。

> DirectXTKを使う利点は、Direct3D 11を使わなくてよくなることではありません。毎回必要になる初期化と管理を信頼できる共通部品へ任せ、ゲーム側のコードを描画やゲームロジックに集中させられることです。

注：`DeviceResources`はDirectXTK本体のNuGetライブラリに含まれる単一APIではなく、DirectXTK公式のVisual Studioテンプレートやサンプルで提供される補助クラスです。この比較は、公式テンプレートを使ったときに自分が記述・保守する`Main.cpp`の差を示しています。

## 使うメリット

最大のメリットは、定番処理の実装量を減らしつつ、Direct3D 11の構造を隠しすぎないことです。高水準のゲームエンジンほど自動化はしませんが、その分、レンダリングの流れやリソースの扱いを自分で決められます。（特に、DirectXでのプログラミングを求められるゲーム業界志望の人におすすめです）  
 そのためDirectXTKは、Direct3D 11を学びながら小規模なゲームや描画アプリケーションを作りたい場合や、独自フレームワークの土台に必要な機能だけ取り込みたい場合に向いています。

## DirectXTexとの関係

名前の似た`DirectXTex`なんてのもあります。同じDirectXTKのライブラリのセットにも入ってたりしますが、主に画像の読み書き、DDSの読み書き、リサイズ、形式変換、ミップマップ生成、ブロック圧縮などを行う、本格的なテクスチャ処理ライブラリです。主に制作ツールやコンテンツパイプラインでの利用を想定しています。まぁ、使う時が来たらまた説明します。

一方、DirectXTKの`DDSTextureLoader`と`WICTextureLoader`は、ゲーム実行時に加工済みの画像を軽量に読み込むためのものです。ゲーム内で画像を表示するだけなら、まずDirectXTKのローダーで十分です。画像を事前変換・圧縮する工程が必要になったときに、DirectXTexを別の道具として検討します。

## まとめ

- DirectXTKは、Direct3D向けのC++ヘルパークラス集
- 2D・3D描画、テクスチャ、入力、音声、数学などの定番処理を補助する
- Direct3D 11を置き換えるものではなく、ゲームエンジンでもない
- ゲームループ、シーン、ルール、オブジェクト管理は自分で設計する
- DirectXTexは主にテクスチャの加工や制作パイプラインを担う別ライブラリ

## 参考資料

- [Microsoft DirectXTK](https://github.com/microsoft/DirectXTK?ref=geekjp.com)
- [DirectXTK Wiki](https://github.com/microsoft/DirectXTK/wiki?ref=geekjp.com)
- [DirectXTex Wiki](https://github.com/microsoft/DirectXTex/wiki?ref=geekjp.com)