# 機能設計書 263-imgui_impl_dx9

## 概要

本ドキュメントは、Dear ImGuiのDirectX9レンダラーバックエンド（imgui_impl_dx9）の機能設計を定義する。

### 本機能の処理概要

DirectX9レンダラーバックエンドは、Dear ImGuiのUI描画コマンドをDirectX9の固定機能パイプラインAPI呼び出しに変換し、画面にUIを描画する機能を提供する。Windows環境でのレガシーDirectX9アプリケーションへのImGui統合に使用される。

**業務上の目的・背景**：
DirectX9を使用するレガシーWindowsアプリケーションやゲームにDear ImGuiを統合する必要がある場合に本バックエンドを使用する。DirectX9は固定機能パイプラインを使用するため、シェーダーを必要とせず、古いハードウェアやドライバーとの互換性が高い。IMGUI_USE_BGRA_PACKED_COLORによる最適化もサポート。

**機能の利用シーン**：
- レガシーDirectX9ゲームへのImGuiデバッグUI追加
- DirectX9を使用する業務アプリケーションへのUI統合
- 古いWindows環境（Windows XP等）でのImGui使用

**主要な処理内容**：
1. バックエンドの初期化（`ImGui_ImplDX9_Init`）：デバイス取得、RGBA対応チェック
2. フレーム開始処理（`ImGui_ImplDX9_NewFrame`）：状態確認
3. 描画データのレンダリング（`ImGui_ImplDX9_RenderDrawData`）：頂点変換、描画実行
4. テクスチャ更新（`ImGui_ImplDX9_UpdateTexture`）：テクスチャ作成・更新・破棄
5. バックエンドの終了処理（`ImGui_ImplDX9_Shutdown`）：リソース解放

**関連システム・外部連携**：
- プラットフォームバックエンド（Win32）と組み合わせて使用
- DirectX9ランタイム

**権限による制御**：
特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 全画面 | 主画面 | すべてのDear ImGuiウィジェットの描画出力先 |

## 機能種別

レンダリングバックエンド / グラフィックスAPI抽象化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|-----------------|
| device | IDirect3DDevice9* | Yes | Direct3D9デバイス | nullptr以外 |
| draw_data | ImDrawData* | Yes | 描画コマンドリスト | DisplaySize > 0 |
| tex | ImTextureData* | Yes | テクスチャデータ | Status確認必須 |

### 入力データソース

- IDirect3DDevice9インスタンス
- ImDrawData構造体
- ImTextureData構造体

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 初期化結果 | bool | Init関数の成功/失敗 |
| テクスチャ | LPDIRECT3DTEXTURE9 | 作成されたテクスチャオブジェクト |
| 画面出力 | Direct3D9描画 | バックバッファへのUI描画結果 |

### 出力先

- Direct3D9バックバッファ
- io.BackendRendererUserData

## 処理フロー

### 処理シーケンス

```
1. ImGui_ImplDX9_Init(device)
   ├─ デバイス参照カウント増加
   └─ RGBA形式サポートチェック

2. [毎フレーム] ImGui_ImplDX9_NewFrame()
   └─ バックエンド状態確認

3. [毎フレーム] ImGui_ImplDX9_RenderDrawData(draw_data)
   ├─ テクスチャ更新チェック
   ├─ 頂点/インデックスバッファ作成・拡張
   ├─ DX9状態のバックアップ（StateBlock）
   ├─ 頂点データ変換（ImDrawVert → CUSTOMVERTEX）
   ├─ 色変換（RGBA → BGRA）
   ├─ レンダリング状態設定
   ├─ 描画コマンド実行（DrawIndexedPrimitive）
   └─ DX9状態の復元

4. ImGui_ImplDX9_Shutdown()
   └─ リソース解放、デバイス参照カウント減少
```

### フローチャート

```mermaid
flowchart TD
    A[Init] --> B[NewFrame]
    B --> C[RenderDrawData]
    C --> D{DisplaySize > 0?}
    D -->|No| E[Return]
    D -->|Yes| F[Update Textures]
    F --> G[Create/Grow Buffers]
    G --> H[CreateStateBlock]
    H --> I[Lock VB/IB]
    I --> J[Convert Vertices RGBA→BGRA]
    J --> K[Unlock VB/IB]
    K --> L[SetupRenderState]
    L --> M[For each DrawList/DrawCmd]
    M --> N[SetScissorRect]
    N --> O[SetTexture]
    O --> P[DrawIndexedPrimitive]
    P --> Q[StateBlock Apply]
    Q --> R[Shutdown]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 頂点フォーマット | CUSTOMVERTEX構造体（D3DFVF_XYZ, D3DFVF_DIFFUSE, D3DFVF_TEX1） | 頂点データ変換時 |
| BR-002 | 色変換 | RGBA→BGRA変換（IMGUI_USE_BGRA_PACKED_COLOR無効時） | HasRgbaSupport=false時 |
| BR-003 | 大規模メッシュ対応 | 64K頂点以上サポート（VtxOffset使用） | レンダリング時 |

### 計算ロジック

**RGBA→BGRA色変換**（行77-81）:
```cpp
#define IMGUI_COL_TO_DX9_ARGB(_COL) \
    (((_COL) & 0xFF00FF00) | (((_COL) & 0xFF0000) >> 16) | (((_COL) & 0xFF) << 16))
```

**正射影行列の計算**（行146-161）:
```cpp
L = DisplayPos.x + 0.5f;
R = DisplayPos.x + DisplaySize.x + 0.5f;
T = DisplayPos.y + 0.5f;
B = DisplayPos.y + DisplaySize.y + 0.5f;
// 0.5fオフセット: DX9ピクセル中心補正
```

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IM_ASSERT | 初期化エラー | 二重初期化 | 初期化状態確認 |
| HRESULT < 0 | バッファ作成失敗 | CreateVertexBuffer/CreateIndexBuffer失敗 | return |
| HRESULT < 0 | StateBlock作成失敗 | CreateStateBlock失敗 | return |
| HRESULT < 0 | Lock失敗 | VB/IB Lock失敗 | StateBlock解放してreturn |

### リトライ仕様

リトライなし

## トランザクション仕様

該当なし

## パフォーマンス要件

- CUSTOMVERTEX構造体への頂点変換が毎フレーム発生
- StateBlockによる状態バックアップ・復元
- D3DPOOL_DEFAULT使用による動的バッファ

## セキュリティ考慮事項

- デバイスポインタの検証
- バッファサイズの上限管理

## 備考

- IMGUI_USE_BGRA_PACKED_COLORを定義すると色変換をスキップ可能
- 一部のドライバーはRGBA形式をサポートしないため、HasRgbaSupportで判定

---

## コードリーディングガイド

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_impl_dx9.cpp | `backends/imgui_impl_dx9.cpp` | ImGui_ImplDX9_Data構造体（行57-67）を確認 |
| 1-2 | imgui_impl_dx9.cpp | `backends/imgui_impl_dx9.cpp` | CUSTOMVERTEX構造体（行69-75）を確認 |

**読解のコツ**: DX9はImDrawVertと異なる頂点フォーマット（Z座標追加、色フォーマット異なる）を使用するため、CUSTOMVERTEXへの変換が必要。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_impl_dx9.h | `backends/imgui_impl_dx9.h` | 公開API宣言（行25-35）を確認 |
| 2-2 | imgui_impl_dx9.cpp | `backends/imgui_impl_dx9.cpp` | Init関数（行327-348）を確認 |

**主要処理フロー**:
- **行337-338**: ImGuiBackendFlags設定
- **行343-345**: デバイス参照とRGBA対応チェック

#### Step 3: 頂点変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_impl_dx9.cpp | `backends/imgui_impl_dx9.cpp` | RenderDrawData関数（行165-307）の頂点変換部分（行228-248）を確認 |

**主要処理フロー**:
- **行234-244**: ImDrawVert → CUSTOMVERTEX変換ループ
- **行240**: IMGUI_COL_TO_DX9_ARGBマクロによる色変換

#### Step 4: レンダリング状態設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_impl_dx9.cpp | `backends/imgui_impl_dx9.cpp` | SetupRenderState関数（行91-162）を確認 |

**主要処理フロー**:
- **行106-128**: 固定機能パイプライン状態設定（SetRenderState多数）
- **行129-140**: テクスチャステージ状態設定
- **行146-161**: 正射影行列設定

### プログラム呼び出し階層図

```
アプリケーション
    │
    ├─ ImGui_ImplDX9_Init(device)
    │      ├─ device->AddRef()
    │      └─ ImGui_ImplDX9_CheckFormatSupport()
    │
    ├─ [フレームループ]
    │      │
    │      ├─ ImGui_ImplDX9_NewFrame()
    │      │
    │      └─ ImGui_ImplDX9_RenderDrawData()
    │             ├─ ImGui_ImplDX9_UpdateTexture()  [テクスチャ更新]
    │             ├─ device->CreateVertexBuffer()  [バッファ作成/拡張]
    │             ├─ device->CreateStateBlock()  [状態バックアップ]
    │             ├─ pVB->Lock() / pIB->Lock()  [バッファロック]
    │             ├─ [頂点変換ループ]
    │             ├─ ImGui_ImplDX9_SetupRenderState()
    │             │      ├─ device->SetRenderState() ×多数
    │             │      ├─ device->SetTextureStageState() ×多数
    │             │      └─ device->SetTransform()
    │             ├─ device->DrawIndexedPrimitive()  [描画]
    │             └─ stateBlock->Apply()  [状態復元]
    │
    └─ ImGui_ImplDX9_Shutdown()
           └─ ImGui_ImplDX9_InvalidateDeviceObjects()
```

### データフロー図

```
[入力]                    [処理]                         [出力]

IDirect3DDevice9 ──────▶ Init() ─────────────────────▶ バックエンドデータ
                          └─ CheckFormatSupport()       └─ HasRgbaSupport

ImDrawData ───────────▶ RenderDrawData() ─────────▶ Direct3D9描画
  ├─ DisplaySize           ├─ 頂点変換                   └─ バックバッファ
  ├─ CmdLists[]            │   └─ RGBA→BGRA
  │   ├─ VtxBuffer         ├─ StateBlock保存/復元
  │   └─ IdxBuffer         └─ DrawIndexedPrimitive()
  │
  └─ Textures[] ──────────▶ UpdateTexture() ──────────▶ LPDIRECT3DTEXTURE9
       └─ ImTextureData       ├─ CreateTexture()
                              └─ LockRect() / UnlockRect()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_impl_dx9.h | `backends/imgui_impl_dx9.h` | ヘッダー | 公開API宣言 |
| imgui_impl_dx9.cpp | `backends/imgui_impl_dx9.cpp` | ソース | バックエンド実装本体（481行） |
| d3d9.h | システム | ヘッダー | DirectX9 API宣言 |
