# 機能設計書 262-imgui_impl_opengl3

## 概要

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

### 本機能の処理概要

OpenGL3レンダラーバックエンドは、Dear ImGuiのUI描画コマンドをモダンOpenGL（シェーダーベース、プログラマブルパイプライン）のグラフィックスAPI呼び出しに変換し、画面にUIを描画する機能を提供する。Desktop GL 2.x/3.x/4.xおよびEmbedded GL ES 2.0/3.0（WebGL 1.0/2.0）をサポートする。

**業務上の目的・背景**：
モダンOpenGL環境での標準的なDear ImGuiレンダリングバックエンドとして、シェーダーを使用した効率的なUI描画を実現する。VBO/VAO/シェーダーを使用するため、OpenGL2バックエンドよりも高性能で、64K頂点以上の大規模メッシュにも対応（Desktop OpenGL 3.2以上）。WebGL/OpenGL ES環境もサポートし、クロスプラットフォーム開発に最適。

**機能の利用シーン**：
- デスクトップアプリケーションでのUI描画（Windows/macOS/Linux）
- Webアプリケーション（WebGL/Emscripten）
- モバイルアプリケーション（OpenGL ES 2.0/3.0）
- ゲームエンジンやグラフィックスツールへのImGui統合

**主要な処理内容**：
1. バックエンドの初期化（`ImGui_ImplOpenGL3_Init`）：GLSLバージョン設定、GLローダー初期化、機能検出
2. デバイスオブジェクト作成（`ImGui_ImplOpenGL3_CreateDeviceObjects`）：シェーダーコンパイル、VBO/VAO作成
3. フレーム開始処理（`ImGui_ImplOpenGL3_NewFrame`）：デバイスオブジェクト確認
4. 描画データのレンダリング（`ImGui_ImplOpenGL3_RenderDrawData`）：VBO更新、シェーダー使用、描画実行
5. テクスチャ更新（`ImGui_ImplOpenGL3_UpdateTexture`）：テクスチャ作成・更新・破棄
6. バックエンドの終了処理（`ImGui_ImplOpenGL3_Shutdown`）：リソース解放

**関連システム・外部連携**：
- プラットフォームバックエンド（GLFW、SDL、Win32等）と組み合わせて使用
- OpenGL 2.x/3.x/4.x または OpenGL ES 2.0/3.0 互換のグラフィックスドライバー
- 内蔵GLローダー（imgui_impl_opengl3_loader.h）または外部GLローダー（glad、glew等）

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|-----------------|
| glsl_version | const char* | No | GLSLバージョン文字列（例: "#version 130"） | nullptr時はデフォルト値使用 |
| draw_data | ImDrawData* | Yes | 描画コマンドリスト | nullptr以外、DisplaySize > 0 |
| tex | ImTextureData* | Yes | テクスチャデータ（UpdateTexture用） | Status確認必須 |

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

- OpenGLフレームバッファ（画面表示）
- io.BackendRendererUserData（バックエンドデータ保存）
- platform_io.Renderer_TextureMaxWidth/Height（最大テクスチャサイズ）

## 処理フロー

### 処理シーケンス

```
1. ImGui_ImplOpenGL3_Init(glsl_version)
   ├─ GLローダー初期化
   ├─ GLバージョン検出・機能判定
   ├─ GLSLバージョン文字列保存
   └─ バックエンドフラグ設定

2. ImGui_ImplOpenGL3_CreateDeviceObjects()
   ├─ シェーダーソース選択（GLSLバージョンに応じて）
   ├─ 頂点シェーダー/フラグメントシェーダーコンパイル
   ├─ シェーダープログラムリンク
   ├─ uniform/attribute位置取得
   └─ VBO/VAO作成

3. [毎フレーム] ImGui_ImplOpenGL3_NewFrame()
   └─ デバイスオブジェクト未作成なら作成

4. [毎フレーム] ImGui_ImplOpenGL3_RenderDrawData(draw_data)
   ├─ フレームバッファサイズ計算
   ├─ テクスチャ更新チェック・実行
   ├─ OpenGL状態のバックアップ
   ├─ VAO作成・バインド
   ├─ シェーダー使用・uniform設定
   ├─ VBO/IBOデータアップロード
   ├─ 描画コマンドリストの処理
   │   ├─ シザー矩形設定（glScissor）
   │   ├─ テクスチャバインド（glBindTexture）
   │   └─ 描画実行（glDrawElements/glDrawElementsBaseVertex）
   ├─ VAO破棄
   └─ OpenGL状態の復元

5. ImGui_ImplOpenGL3_Shutdown()
   └─ デバイスオブジェクト破棄、GLローダー終了
```

### フローチャート

```mermaid
flowchart TD
    A[Init] --> B{GLローダー初期化}
    B -->|成功| C[GLバージョン検出]
    B -->|失敗| Z[return false]
    C --> D[GLSLバージョン設定]
    D --> E[BackendFlags設定]
    E --> F[NewFrame]
    F --> G{シェーダー作成済み?}
    G -->|No| H[CreateDeviceObjects]
    G -->|Yes| I[RenderDrawData]
    H --> I
    I --> J{Textures != null?}
    J -->|Yes| K[UpdateTexture for each]
    J -->|No| L[Backup GL State]
    K --> L
    L --> M[Create/Bind VAO]
    M --> N[Use Shader Program]
    N --> O[Upload VBO/IBO]
    O --> P[For each DrawList/DrawCmd]
    P --> Q{GL >= 3.2?}
    Q -->|Yes| R[glDrawElementsBaseVertex]
    Q -->|No| S[glDrawElements]
    R --> T[Delete VAO]
    S --> T
    T --> U[Restore GL State]
    U --> V[Shutdown]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | テクスチャフォーマット | RGBA32形式のみサポート | テクスチャ作成時 |
| BR-002 | 大規模メッシュ対応 | 64K頂点以上はDesktop GL 3.2以上でのみサポート | GL_VERSION >= 3.2 |
| BR-003 | GLSLバージョン自動選択 | ES2→#version 100, ES3→#version 300 es, Desktop→#version 130等 | Init時 |
| BR-004 | サンプラー設定 | GL 3.3以上またはES3でglBindSamplerを使用 | HasBindSamplerフラグ |

### 計算ロジック

**正射影行列の計算**（行493-506）:
```cpp
float L = DisplayPos.x;
float R = DisplayPos.x + DisplaySize.x;
float T = DisplayPos.y;
float B = DisplayPos.y + DisplaySize.y;
float ortho_projection[4][4] = {
    { 2.0f/(R-L),   0.0f,         0.0f,   0.0f },
    { 0.0f,         2.0f/(T-B),   0.0f,   0.0f },
    { 0.0f,         0.0f,        -1.0f,   0.0f },
    { (R+L)/(L-R),  (T+B)/(B-T),  0.0f,   1.0f },
};
```

**GLバージョン番号計算**（行344）:
```cpp
GlVersion = major * 100 + minor * 10;  // 例: GL 3.2 → 320
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IM_ASSERT | 初期化エラー | BackendRendererUserDataが既に設定済み | 二重初期化を避ける |
| IM_ASSERT | 終了エラー | バックエンドが未初期化または既に終了 | 初期化状態を確認 |
| fprintf(stderr) | シェーダーコンパイルエラー | GLSLソースのコンパイル失敗 | GLバージョン確認、エラーログ参照 |
| fprintf(stderr) | シェーダーリンクエラー | プログラムリンク失敗 | 頂点/フラグメントシェーダー確認 |
| - | レンダリングスキップ | fb_width/fb_height <= 0 | 最小化時は自動スキップ |

### リトライ仕様

シェーダーエラー時はASSERTで停止。リトライなし。

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

該当なし

## パフォーマンス要件

- VBO/VAOを使用した効率的なデータ転送
- シェーダーベースのレンダリングパイプライン
- 毎フレームVAOを再作成（複数GLコンテキスト対応のため）
- テクスチャ更新は差分更新対応（glTexSubImage2D）
- glBufferData使用（glBufferSubDataはIntel GPU問題により非推奨化）

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

- 入力データのポインタ検証（nullptr チェック）
- シェーダーコンパイル時のエラーハンドリング
- GLコンテキスト有効性の確認

## 備考

- 推奨OpenGLバックエンド。Desktop/Mobile/Web全環境に対応
- IMGUI_IMPL_OPENGL_ES2/ES3マクロで明示的にES環境を指定可能
- カスタムGLローダー使用時はIMGUI_IMPL_OPENGL_LOADER_CUSTOMを定義

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_impl_opengl3.cpp | `backends/imgui_impl_opengl3.cpp` | ImGui_ImplOpenGL3_Data構造体（行232-257）を確認 |
| 1-2 | imgui_impl_opengl3.cpp | `backends/imgui_impl_opengl3.cpp` | GLSLバージョンテーブル（行102-118）を確認 |

**読解のコツ**: OpenGL3バックエンドはGL2と異なり、シェーダーハンドル、VBO/VAO、各種フラグを保持する必要がある。GlVersionフィールドでランタイムの機能検出結果を保存する設計となっている。

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

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

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

**主要処理フロー**:
1. **行321-322**: GLローダー初期化
2. **行329-358**: GLバージョン検出（GL_MAJOR_VERSION/GL_MINOR_VERSION）
3. **行375-378**: ImGuiBackendFlags_RendererHasVtxOffsetの条件付き設定（GL >= 3.2）
4. **行379**: ImGuiBackendFlags_RendererHasTextures設定
5. **行386-400**: GLSLバージョン自動選択

#### Step 3: シェーダー作成処理を理解する

GLSLシェーダーのコンパイルとリンク処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_impl_opengl3.cpp | `backends/imgui_impl_opengl3.cpp` | CreateDeviceObjects関数（行844-1041）を確認 |
| 3-2 | imgui_impl_opengl3.cpp | `backends/imgui_impl_opengl3.cpp` | シェーダーソース定義（行866-964）を確認 |

**主要処理フロー**:
- **行863-864**: GLSLバージョン番号パース
- **行866-964**: 4種類のシェーダーソース（GLSL 120/130/300es/410core）
- **行966-988**: バージョンに応じたシェーダー選択
- **行990-1018**: シェーダーコンパイル・リンク
- **行1020-1028**: uniform/attribute位置取得

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

VBO更新と描画コマンド処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_impl_opengl3.cpp | `backends/imgui_impl_opengl3.cpp` | RenderDrawData関数（行535-718）を確認 |
| 4-2 | imgui_impl_opengl3.cpp | `backends/imgui_impl_opengl3.cpp` | SetupRenderState関数（行458-530）を確認 |

**主要処理フロー**:
- **行537-541**: フレームバッファサイズ計算と最小化チェック
- **行547-552**: テクスチャ更新チェック
- **行554-591**: OpenGL状態のバックアップ（非常に詳細）
- **行596-600**: VAO作成とバインド
- **行606-638**: DrawListごとのVBOデータアップロード
- **行640-672**: 描画コマンドループ
- **行665-670**: GL 3.2以上でglDrawElementsBaseVertex、それ以外でglDrawElements
- **行675-717**: OpenGL状態の復元

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | imgui_impl_opengl3.cpp | `backends/imgui_impl_opengl3.cpp` | UpdateTexture関数（行730-804）を確認 |

**主要処理フロー**:
- **行733-741**: GL_UNPACK設定
- **行743-770**: WantCreate状態：新規テクスチャ作成
- **行771-801**: WantUpdates状態：部分更新（GL_UNPACK_ROW_LENGTHの有無で分岐）
- **行802-803**: WantDestroy状態：テクスチャ破棄

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

```
アプリケーション
    │
    ├─ ImGui_ImplOpenGL3_Init(glsl_version)
    │      ├─ ImGui_ImplOpenGL3_InitLoader()
    │      │      └─ imgl3wInit()  [内蔵ローダー使用時]
    │      ├─ glGetString(GL_VERSION)
    │      ├─ glGetIntegerv(GL_MAJOR_VERSION/GL_MINOR_VERSION)
    │      └─ GLSLバージョン設定
    │
    ├─ [フレームループ]
    │      │
    │      ├─ ImGui_ImplOpenGL3_NewFrame()
    │      │      └─ ImGui_ImplOpenGL3_CreateDeviceObjects() [初回のみ]
    │      │             ├─ D3DCompile() [シェーダーコンパイル]
    │      │             ├─ glCreateShader() / glShaderSource() / glCompileShader()
    │      │             ├─ glCreateProgram() / glAttachShader() / glLinkProgram()
    │      │             ├─ glGetUniformLocation() / glGetAttribLocation()
    │      │             └─ glGenBuffers()  [VBO/IBO作成]
    │      │
    │      └─ ImGui_ImplOpenGL3_RenderDrawData()
    │             ├─ ImGui_ImplOpenGL3_UpdateTexture()  [テクスチャ更新]
    │             │      ├─ glGenTextures() / glTexImage2D()  [WantCreate]
    │             │      ├─ glTexSubImage2D()  [WantUpdates]
    │             │      └─ glDeleteTextures()  [WantDestroy]
    │             │
    │             ├─ [状態バックアップ]
    │             │      └─ glGetIntegerv() / glIsEnabled() など多数
    │             │
    │             ├─ glGenVertexArrays() / glBindVertexArray()
    │             │
    │             ├─ ImGui_ImplOpenGL3_SetupRenderState()
    │             │      ├─ glEnable/glDisable (各種状態)
    │             │      ├─ glUseProgram()
    │             │      ├─ glUniform1i() / glUniformMatrix4fv()
    │             │      └─ glVertexAttribPointer()
    │             │
    │             ├─ [DrawListループ]
    │             │      ├─ glBufferData()  [VBO/IBOアップロード]
    │             │      └─ [DrawCmdループ]
    │             │             ├─ glScissor()
    │             │             ├─ glBindTexture()
    │             │             └─ glDrawElementsBaseVertex() / glDrawElements()
    │             │
    │             ├─ glDeleteVertexArrays()
    │             │
    │             └─ [状態復元]
    │
    └─ ImGui_ImplOpenGL3_Shutdown()
           ├─ ImGui_ImplOpenGL3_DestroyDeviceObjects()
           │      ├─ glDeleteBuffers()
           │      ├─ glDeleteProgram()
           │      └─ ImGui_ImplOpenGL3_DestroyTexture()
           └─ ImGui_ImplOpenGL3_ShutdownLoader()
```

### データフロー図

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

glsl_version ──────────▶ Init() ─────────────────────▶ バックエンドデータ
  (nullable)              ├─ GLバージョン検出             ├─ GlVersion
                          ├─ GLSLバージョン設定           ├─ GlslVersionString
                          └─ 機能フラグ設定               └─ HasXxxフラグ群

ImDrawData ───────────▶ RenderDrawData() ─────────▶ OpenGLフレームバッファ
  ├─ DisplaySize           ├─ 正射影行列計算              └─ 画面表示
  ├─ DisplayPos            ├─ VBOアップロード
  ├─ CmdLists[]            │   └─ glBufferData()
  │   ├─ VtxBuffer         ├─ シェーダー使用
  │   ├─ IdxBuffer         │   └─ glUseProgram()
  │   └─ CmdBuffer[]       └─ glDrawElementsBaseVertex()
  │       ├─ ClipRect
  │       ├─ TextureId
  │       ├─ ElemCount
  │       └─ VtxOffset [GL 3.2+]
  │
  └─ Textures[] ──────────▶ UpdateTexture() ──────────▶ GLuint (テクスチャID)
       └─ ImTextureData       ├─ glGenTextures()
           ├─ Width/Height    ├─ glTexImage2D()
           ├─ Pixels          └─ glTexSubImage2D()
           └─ Status
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_impl_opengl3.h | `backends/imgui_impl_opengl3.h` | ヘッダー | 公開API宣言、設定マクロ |
| imgui_impl_opengl3.cpp | `backends/imgui_impl_opengl3.cpp` | ソース | バックエンド実装本体（1067行） |
| imgui_impl_opengl3_loader.h | `backends/imgui_impl_opengl3_loader.h` | ヘッダー | 内蔵OpenGLローダー |
| imgui.h | `imgui.h` | ヘッダー | ImDrawData, ImTextureData等の型定義 |
