# 機能設計書 261-imgui_impl_opengl2

## 概要

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

### 本機能の処理概要

OpenGL2レンダラーバックエンドは、Dear ImGuiのUI描画コマンドをOpenGL 2.x（固定機能パイプライン）のグラフィックスAPI呼び出しに変換し、画面にUIを描画する機能を提供する。

**業務上の目的・背景**：
レガシーなOpenGL 2.x環境やシェーダーをサポートしないグラフィックスドライバーを使用するシステムにおいて、Dear ImGuiを動作させる必要がある場合に本バックエンドを使用する。教育目的やImGui統合の参照実装としても有用であり、コードが短く読みやすい設計となっている。ただし、モダンOpenGL（シェーダー、VBO、VAO等）を使用するアプリケーションでは、imgui_impl_opengl3の使用が推奨される。

**機能の利用シーン**：
- 古いグラフィックスハードウェアやドライバーを使用するシステムでのUI表示
- OpenGL 2.xのみをサポートするプラットフォームでの開発
- ImGui統合方法の学習・教育目的（コードが短く理解しやすい）
- レガシーアプリケーションへのImGui追加

**主要な処理内容**：
1. バックエンドの初期化（`ImGui_ImplOpenGL2_Init`）：バックエンドデータ構造の作成、IO設定
2. フレーム開始処理（`ImGui_ImplOpenGL2_NewFrame`）：フレームごとの準備処理
3. 描画データのレンダリング（`ImGui_ImplOpenGL2_RenderDrawData`）：ImDrawDataをOpenGL2 API呼び出しに変換
4. テクスチャ更新（`ImGui_ImplOpenGL2_UpdateTexture`）：フォントアトラス等のテクスチャ作成・更新・破棄
5. バックエンドの終了処理（`ImGui_ImplOpenGL2_Shutdown`）：リソース解放、状態クリア

**関連システム・外部連携**：
- プラットフォームバックエンド（GLFW、SDL、Win32等）と組み合わせて使用
- OpenGL 2.x互換のグラフィックスドライバー

**権限による制御**：
特になし（単一ユーザー向けローカルアプリケーション用途）

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- ImGui::GetIO()からのIOコンテキスト
- ImDrawData構造体（頂点バッファ、インデックスバッファ、描画コマンド）
- ImTextureData構造体（テクスチャピクセルデータ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 初期化結果 | bool | Init関数の成功/失敗 |
| テクスチャID | GLuint | 作成されたOpenGLテクスチャハンドル |
| 画面出力 | OpenGL描画 | フレームバッファへのUI描画結果 |

### 出力先

- OpenGLフレームバッファ（画面表示）
- io.BackendRendererUserData（バックエンドデータ保存）

## 処理フロー

### 処理シーケンス

```
1. ImGui_ImplOpenGL2_Init()
   └─ バックエンドデータ構造作成、IO設定（BackendFlags）

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

3. [毎フレーム] ImGui_ImplOpenGL2_RenderDrawData(draw_data)
   ├─ フレームバッファサイズ計算
   ├─ テクスチャ更新チェック・実行
   ├─ OpenGL状態のバックアップ
   ├─ レンダリング状態設定
   ├─ 描画コマンドリストの処理
   │   ├─ 頂点ポインタ設定（glVertexPointer, glTexCoordPointer, glColorPointer）
   │   ├─ シザー矩形設定（glScissor）
   │   ├─ テクスチャバインド（glBindTexture）
   │   └─ 描画実行（glDrawElements）
   └─ OpenGL状態の復元

4. ImGui_ImplOpenGL2_Shutdown()
   └─ デバイスオブジェクト破棄、バックエンドデータ解放
```

### フローチャート

```mermaid
flowchart TD
    A[Init] --> B[NewFrame]
    B --> C[RenderDrawData]
    C --> D{Textures != null?}
    D -->|Yes| E[UpdateTexture for each]
    D -->|No| F[Backup GL State]
    E --> F
    F --> G[Setup Render State]
    G --> H[For each DrawList]
    H --> I[Set Vertex Pointers]
    I --> J[For each DrawCmd]
    J --> K{UserCallback?}
    K -->|Yes| L[Call Callback]
    K -->|No| M[Set Scissor & Bind Texture]
    M --> N[glDrawElements]
    L --> J
    N --> J
    J --> O[Restore GL State]
    O --> P[Shutdown]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | テクスチャフォーマット | RGBA32形式のみサポート | テクスチャ作成時 |
| BR-002 | 大規模メッシュ非対応 | 64K頂点以上のメッシュはサポートしない（VtxOffset非対応） | レンダリング時 |
| BR-003 | レガシーOpenGL専用 | シェーダー使用時はopengl3を使用すべき | 初期化時の選択 |

### 計算ロジック

**正射影行列の計算**（行137-175）:
```
L = DisplayPos.x + 0.5
R = DisplayPos.x + DisplaySize.x + 0.5
T = DisplayPos.y + 0.5
B = DisplayPos.y + DisplaySize.y + 0.5

glOrtho(L, R, B, T, -1.0, +1.0)
```

**フレームバッファスケール計算**（行187-188）:
```
fb_width = DisplaySize.x * FramebufferScale.x
fb_height = DisplaySize.y * FramebufferScale.y
```

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

該当なし（グラフィックスAPIバックエンド）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IM_ASSERT | 初期化エラー | BackendRendererUserDataが既に設定済み | 二重初期化を避ける |
| IM_ASSERT | 終了エラー | バックエンドが未初期化または既に終了 | 初期化状態を確認 |
| - | レンダリングスキップ | fb_width/fb_height が 0 | 最小化時は自動スキップ |

### リトライ仕様

リトライなし。エラー時はASSERTマクロで停止。

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

該当なし

## パフォーマンス要件

- 頂点データは固定機能パイプラインを使用（glVertexPointer等）
- 毎フレームOpenGL状態のバックアップ・復元を実行
- テクスチャ更新は差分更新対応（glTexSubImage2D）

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

- 入力データのポインタ検証（nullptr チェック）
- テクスチャサイズの検証（極端に大きいサイズへの対応）

## 備考

- **重要**: モダンOpenGL（GL3+）を使用するアプリケーションではimgui_impl_opengl3.cppの使用を強く推奨
- GL2ではglUseProgram(0)などのリセット呼び出しが不可能なため、ホストアプリケーション側での状態管理が必要

---

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

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

### 推奨読解順序

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

まず、バックエンドで使用されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_impl_opengl2.cpp | `backends/imgui_impl_opengl2.cpp` | ImGui_ImplOpenGL2_Data構造体（行86-89）を確認 |

**読解のコツ**: OpenGL2バックエンドは非常にシンプルで、バックエンドデータ構造はほぼ空の構造体となっている。これはOpenGL2の固定機能パイプラインがシェーダーやバッファオブジェクトを必要としないためである。

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

処理の起点となるAPI関数群を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_impl_opengl2.h | `backends/imgui_impl_opengl2.h` | 公開API宣言（行31-41）を確認 |
| 2-2 | imgui_impl_opengl2.cpp | `backends/imgui_impl_opengl2.cpp` | Init関数（行99-112）の初期化処理を確認 |

**主要処理フロー**:
1. **行99-102**: バージョンチェックとユーザーデータ検証
2. **行105-108**: バックエンドデータの作成とIO設定
3. **行109**: ImGuiBackendFlags_RendererHasTexturesフラグ設定

#### Step 3: 状態設定処理を理解する

OpenGL固定機能パイプラインの状態設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_impl_opengl2.cpp | `backends/imgui_impl_opengl2.cpp` | SetupRenderState関数（行137-179）でOpenGL状態の設定を確認 |

**主要処理フロー**:
- **行140-156**: ブレンド、カリング、深度テスト、シザー等の状態設定
- **行149-151**: 頂点配列クライアント状態の有効化
- **行169-178**: 正射影行列の設定

#### Step 4: メインレンダリング処理を理解する

描画コマンドの処理ループを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_impl_opengl2.cpp | `backends/imgui_impl_opengl2.cpp` | RenderDrawData関数（行184-269）で描画処理を確認 |

**主要処理フロー**:
- **行187-190**: フレームバッファサイズ計算と最小化チェック
- **行192-197**: テクスチャ更新チェック
- **行199-206**: OpenGL状態のバックアップ
- **行216-222**: 描画リストごとの処理開始
- **行220-222**: 頂点ポインタ設定（glVertexPointer, glTexCoordPointer, glColorPointer）
- **行224-251**: 描画コマンドループ（コールバック処理または描画実行）
- **行248-249**: glBindTexture + glDrawElements による描画
- **行254-268**: OpenGL状態の復元

#### Step 5: テクスチャ管理を理解する

テクスチャの作成・更新・破棄処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | imgui_impl_opengl2.cpp | `backends/imgui_impl_opengl2.cpp` | UpdateTexture関数（行271-329）でテクスチャ状態管理を確認 |

**主要処理フロー**:
- **行273-302**: WantCreate状態：新規テクスチャ作成（glGenTextures, glTexImage2D）
- **行303-318**: WantUpdates状態：部分更新（glTexSubImage2D）
- **行320-328**: WantDestroy状態：テクスチャ破棄（glDeleteTextures）

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

```
アプリケーション
    │
    ├─ ImGui_ImplOpenGL2_Init()
    │      └─ ImGui_ImplOpenGL2_Data構造体作成
    │
    ├─ [フレームループ]
    │      │
    │      ├─ ImGui_ImplOpenGL2_NewFrame()
    │      │      └─ バックエンド状態確認
    │      │
    │      └─ ImGui_ImplOpenGL2_RenderDrawData()
    │             ├─ ImGui_ImplOpenGL2_UpdateTexture()  [テクスチャ更新]
    │             │      ├─ glGenTextures() / glTexImage2D()  [WantCreate]
    │             │      ├─ glTexSubImage2D()  [WantUpdates]
    │             │      └─ glDeleteTextures()  [WantDestroy]
    │             │
    │             ├─ ImGui_ImplOpenGL2_SetupRenderState()  [状態設定]
    │             │      ├─ glEnable/glDisable (各種状態)
    │             │      ├─ glVertexPointer/glTexCoordPointer/glColorPointer
    │             │      └─ glOrtho (正射影行列)
    │             │
    │             └─ [描画ループ]
    │                    ├─ glScissor()
    │                    ├─ glBindTexture()
    │                    └─ glDrawElements()
    │
    └─ ImGui_ImplOpenGL2_Shutdown()
           └─ ImGui_ImplOpenGL2_DestroyDeviceObjects()
                  └─ ImGui_ImplOpenGL2_UpdateTexture() [WantDestroy]
```

### データフロー図

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

ImDrawData ───────────▶ RenderDrawData() ─────────▶ OpenGLフレームバッファ
  ├─ DisplaySize           ├─ fb_width/height計算        └─ 画面表示
  ├─ DisplayPos            ├─ glOrtho設定
  ├─ CmdLists[]            ├─ 頂点ポインタ設定
  │   ├─ VtxBuffer         │
  │   ├─ IdxBuffer         └─ glDrawElements()
  │   └─ CmdBuffer[]
  │       ├─ ClipRect
  │       ├─ TextureId
  │       └─ ElemCount
  │
  └─ Textures[] ──────────▶ UpdateTexture() ──────────▶ GLuint (テクスチャID)
       └─ ImTextureData       ├─ glGenTextures()
           ├─ Width/Height    ├─ glTexImage2D()
           ├─ Pixels          └─ glTexSubImage2D()
           └─ Status
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_impl_opengl2.h | `backends/imgui_impl_opengl2.h` | ヘッダー | 公開API宣言 |
| imgui_impl_opengl2.cpp | `backends/imgui_impl_opengl2.cpp` | ソース | バックエンド実装本体 |
| imgui.h | `imgui.h` | ヘッダー | ImDrawData, ImTextureData等の型定義 |
| GL/gl.h または OpenGL/gl.h | システム | ヘッダー | OpenGL API宣言 |
