# 機能設計書 10-Render

## 概要

本ドキュメントはDear ImGuiライブラリのRender関数に関する機能設計書である。RenderはImGuiフレームを終了し、描画データを確定させる関数である。

### 本機能の処理概要

Render関数は、NewFrameで開始されたImGuiフレームを終了し、すべてのウィンドウとウィジェットの描画データ（ImDrawData）を生成・確定させる。確定した描画データはGetDrawData()で取得でき、レンダラーバックエンドに渡して実際の描画を行う。

**業務上の目的・背景**：ImGuiはプラットフォーム非依存のUIライブラリであり、描画処理自体は行わない。代わりに、描画に必要なすべての情報（頂点、インデックス、テクスチャ参照等）を含むImDrawDataを生成する。Render関数はこのデータを確定させる最終ステップであり、生成されたデータはOpenGL、DirectX、Vulkan等のレンダラーバックエンドに渡される。

**機能の利用シーン**：
- メインループの各フレーム終了時
- ウィジェット呼び出し完了後
- バックエンドのRenderDrawData呼び出し前

**主要な処理内容**：
1. EndFrame()の呼び出し（未呼び出しの場合）
2. 重複呼び出しの防止
3. RenderPreフック呼び出し
4. 各ビューポートの描画データ初期化
5. 背景描画リストの追加
6. ウィンドウ白抜き効果の描画
7. ウィンドウの描画リスト追加
8. マウスカーソルの描画
9. 前景描画リストの追加
10. ImDrawDataの確定
11. RenderPostフック呼び出し

**関連システム・外部連携**：
- レンダラーバックエンド：GetDrawData()で取得したデータを描画
- プラットフォームバックエンド：マルチビューポート時の連携（Dockingブランチ）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 全ての画面の描画データ生成 |

## 機能種別

フレーム管理 / 描画データ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | 引数なし | - |

### 入力データソース

- GImGuiグローバル変数（現在のコンテキスト）
- 各ウィンドウのImDrawList

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | void | 戻り値なし |

### 出力先

- ImDrawData（GetDrawData()で取得可能）
- ビューポートのDrawDataP

## 処理フロー

### 処理シーケンス

```
1. 初期化確認
   └─ g.Initializedを確認

2. EndFrame呼び出し
   └─ 未終了の場合EndFrame()を呼び出し

3. 重複呼び出しチェック
   └─ g.FrameCountRendered == g.FrameCountなら早期リターン

4. RenderPreフック
   └─ CallContextHooks(ImGuiContextHookType_RenderPre)

5. 各ビューポートの描画データ初期化
   └─ InitViewportDrawData(viewport)

6. 背景描画リスト追加
   └─ GetBackgroundDrawList()の内容を追加

7. ウィンドウ白抜き効果
   └─ RenderDimmedBackgrounds()

8. ウィンドウ描画リスト追加
   └─ AddRootWindowToDrawData()

9. マウスカーソル描画
   └─ RenderMouseCursor() [io.MouseDrawCursor有効時]

10. 描画データの平坦化
    └─ FlattenDrawDataIntoSingleLayer()

11. 前景描画リスト追加
    └─ GetForegroundDrawList()の内容を追加

12. 描画データの確定
    └─ DrawDataP.Valid = true, SetupDrawData()

13. RenderPostフック
    └─ CallContextHooks(ImGuiContextHookType_RenderPost)

14. フレームカウント更新
    └─ g.FrameCountRendered = g.FrameCount
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{g.Initialized?}
    B -->|No| C[アサート失敗]
    B -->|Yes| D{EndFrame未呼び出し?}
    D -->|Yes| E[EndFrame呼び出し]
    D -->|No| F{既にレンダリング済み?}
    E --> F
    F -->|Yes| G[早期リターン]
    F -->|No| H[RenderPreフック]
    H --> I[ビューポート初期化]
    I --> J[背景DrawList追加]
    J --> K[ウィンドウ白抜き効果]
    K --> L[ウィンドウDrawList追加]
    L --> M[マウスカーソル描画]
    M --> N[DrawData平坦化]
    N --> O[前景DrawList追加]
    O --> P[DrawData確定]
    P --> Q[RenderPostフック]
    Q --> R[FrameCountRendered更新]
    R --> S[終了]
    G --> S
    C --> T[プログラム停止]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 初期化必須 | g.Initializedがfalseの場合アサート失敗 | 常に |
| BR-02 | EndFrame自動呼び出し | EndFrameが未呼び出しの場合、自動的に呼び出す | FrameCountEnded != FrameCount |
| BR-03 | 重複呼び出し防止 | 同一フレームで複数回呼び出されても1回だけ処理 | FrameCountRendered == FrameCount |
| BR-04 | DrawData有効期間 | GetDrawData()はRender後、次のNewFrame前まで有効 | 常に |

### 計算ロジック

描画メトリクス計算:
```cpp
g.IO.MetricsRenderVertices = 0;
g.IO.MetricsRenderIndices = 0;
// 各DrawListの頂点/インデックス数を合計
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IM_ASSERT | アサート失敗 | 未初期化 | NewFrame()を呼び出す |

### リトライ仕様

特になし

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

該当なし

## パフォーマンス要件

- 毎フレーム呼び出されるため、効率的な実装が必要
- 描画リストのマージや頂点/インデックスのカウントを行う
- ウィンドウ数に比例した処理時間

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

- 特になし

## 備考

- Render()後はGetDrawData()でImDrawDataを取得可能
- ImDrawDataは次のNewFrame()呼び出しまで有効
- レンダラーバックエンドのImGui_ImplXXX_RenderDrawData()に渡す

---

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

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

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

Renderで生成されるImDrawDataの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImDrawData構造体: CmdLists, TotalVtxCount, TotalIdxCount, DisplayPos, DisplaySize等 |
| 1-2 | imgui.h | `imgui.h` | ImDrawList構造体: CmdBuffer, VtxBuffer, IdxBuffer等 |

**読解のコツ**: ImDrawDataの主要メンバ:
- `ImDrawList** CmdLists` - 描画コマンドリストの配列
- `int CmdListsCount` - リスト数
- `int TotalVtxCount` - 総頂点数
- `int TotalIdxCount` - 総インデックス数
- `ImVec2 DisplayPos/DisplaySize` - 描画領域

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | 403行目: RenderのAPI宣言 |
| 2-2 | imgui.cpp | `imgui.cpp` | 6031-6100行目: Render関数の実装 |

**主要処理フロー**:
1. **6034行目**: 初期化確認
2. **6036-6037行目**: EndFrame呼び出し
3. **6038-6040行目**: 重複呼び出しチェック
4. **6043行目**: RenderPreフック
5. **6046-6051行目**: ビューポート初期化、背景DrawList追加
6. **6054行目**: ウィンドウ白抜き効果
7. **6057-6068行目**: ウィンドウDrawList追加
8. **6071-6072行目**: マウスカーソル描画
9. **6076-6090行目**: DrawData確定

#### Step 3: GetDrawData()を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.h | `imgui.h` | 404行目: GetDrawDataのAPI宣言 |
| 3-2 | imgui.cpp | `imgui.cpp` | GetDrawData関数の実装 |

**読解のコツ**:
- Render()後、GetDrawData()でImDrawData*を取得
- 取得したデータをレンダラーバックエンドに渡す

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

```
ImGui::Render()
    │
    ├─ ImGui::EndFrame() [if not called]
    │
    ├─ CallContextHooks(ImGuiContextHookType_RenderPre)
    │
    ├─ For each Viewport:
    │      ├─ InitViewportDrawData(viewport)
    │      └─ AddDrawListToDrawDataEx(BackgroundDrawList)
    │
    ├─ RenderDimmedBackgrounds()
    │
    ├─ For each Window:
    │      └─ AddRootWindowToDrawData(window)
    │             └─ AddDrawListToDrawDataEx(window->DrawList)
    │
    ├─ RenderMouseCursor() [if enabled]
    │
    ├─ For each Viewport:
    │      ├─ FlattenDrawDataIntoSingleLayer()
    │      ├─ AddDrawListToDrawDataEx(ForegroundDrawList)
    │      └─ SetupDrawData(&viewport->DrawDataP)
    │
    └─ CallContextHooks(ImGuiContextHookType_RenderPost)
```

### データフロー図

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

各ウィンドウの            Render() ─────────────────────▶ ImDrawData
  DrawList                    │                           - CmdLists[]
                              │                           - TotalVtxCount
                              ▼                           - TotalIdxCount
                       DrawListをマージ
                       DrawData生成
                              │
                              ▼
                       GetDrawData()で取得可能
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | パブリックAPI宣言（403行目）、ImDrawData/ImDrawList定義 |
| imgui.cpp | `imgui.cpp` | ソース | Render実装（6031-6100行目） |
| imgui.cpp | `imgui.cpp` | ソース | GetDrawData実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | ImGuiContext構造体定義 |
