# 画面設計書 42-OpenGL

## 概要

本ドキュメントは、Avalonia UIフレームワークのControlCatalogサンプルアプリケーションにおける「OpenGL」デモページの画面設計書です。

### 本画面の処理概要

OpenGLページは、AvaloniaフレームワークのOpenGL統合機能をデモンストレーションする画面です。GPUアクセラレーションを使用した3Dレンダリングの実装例として、ティーポット（Utah Teapot）の3Dモデルをリアルタイムで描画・回転させることができます。

**業務上の目的・背景**：クロスプラットフォームのGUIフレームワークにおいてOpenGLを使用した高性能グラフィックス描画が必要なシナリオ（3Dビューア、CADアプリケーション、ゲーム、データビジュアライゼーションなど）での実装方法を示しています。OpenGlControlBaseを継承したカスタムコントロールの作成方法を学ぶための参考実装として提供されています。

**画面へのアクセス方法**：MainWindowからMainViewのHamburgerMenuを開き、「OpenGL」メニュー項目を選択することでアクセスできます。

**主要な操作・処理内容**：
1. 3Dティーポットモデルのリアルタイム描画
2. Yaw（ヨー）スライダーによるY軸回転制御
3. Pitch（ピッチ）スライダーによるX軸回転制御
4. Roll（ロール）スライダーによるZ軸回転制御
5. Discoスライダーによるアニメーション効果の適用
6. Snapshotボタンによる現在の描画内容のキャプチャ

**画面遷移**：本画面は単独のデモページであり、MainViewのHamburgerMenuから遷移します。Snapshotボタンクリック時にモーダルウィンドウが表示されます。

**権限による表示制御**：本デモ画面では権限による表示制御は実装されていません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 106 | OpenGL | 主機能 | OpenGLレンダリングによる3D描画 |

## 画面種別

デモ / 3Dレンダリング

## URL/ルーティング

ControlCatalog内のHamburgerMenuナビゲーションによるページ切り替え（URL/ルーティング定義なし）

## 入出力項目

| 項目名 | 項目種別 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| Yaw | 入力 | float | - | Y軸回転角度（0-10） |
| Pitch | 入力 | float | - | X軸回転角度（0-10） |
| Roll | 入力 | float | - | Z軸回転角度（0-10） |
| Disco | 入力 | float | - | ディスコエフェクト強度（0-1） |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| OpenGLレンダリング領域 | 画面全体 | 3Dティーポットのレンダリング表示 |
| Info | 右上 | OpenGLレンダラーとバージョン情報 |
| Yawスライダー | 右パネル | Y軸回転制御 |
| Pitchスライダー | 右パネル | X軸回転制御 |
| Rollスライダー | 右パネル | Z軸回転制御 |
| Discoスライダー | 右パネル | アニメーション効果制御 |
| Snapshotボタン | 右下 | スクリーンショット取得（ウィンドウモードのみ表示） |

## イベント仕様

### 1-スライダー値変更イベント

GlPageKnobsのYaw/Pitch/Roll/Discoプロパティが変更されると、KnobsPropertyChangedイベントハンドラが呼び出され、OpenGlPageControlのRequestNextFrameRenderingメソッドにより次フレームの再描画がリクエストされる。

### 2-Snapshotボタンクリックイベント

Snapshotボタンクリック時、SnapshotClickメソッドが実行される。ElementCompositionを使用して現在のビジュアルをキャプチャし、1.5倍スケールのスナップショットを作成。新しいウィンドウでScrollViewer内にImage として表示する。

### 3-OpenGLレンダリングイベント

OnOpenGlRenderメソッドが毎フレーム呼び出され、シェーダープログラムを使用してティーポットモデルを描画する。Disco値が0.01より大きい場合は継続的なアニメーションフレームがリクエストされる。

## データベース更新仕様

本画面はUIコントロールのデモ画面であり、データベースへのアクセス・更新は行いません。

## メッセージ仕様

本画面では特定のメッセージ表示は実装されていません。

## 例外処理

- OpenGL初期化エラー時はコンソールにエラーメッセージを出力
- シェーダーコンパイルエラー時はコンソールにエラー詳細を出力
- 描画エラー時はglGetError()でエラーコードを取得しコンソールに出力

## 備考

- 3Dモデルデータはteapot.binとしてアセンブリに埋め込まれている
- シェーダーはOpenGL 1.2/1.5（デスクトップ）およびOpenGL ES 1.0（モバイル）に対応
- macOSではOpenGL 1.5（Core Profile）、その他のプラットフォームではOpenGL 1.2を使用
- ライティングは固定位置の単一光源によるPhong照明モデルを使用

---

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

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

### 推奨読解順序

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

3Dモデルの頂点データ構造とシェーダーパラメータを理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OpenGlContent.cs | `samples/ControlCatalog/Pages/OpenGl/OpenGlContent.cs` | Vertex構造体（122-127行）でPosition/Normalの配置を確認 |
| 1-2 | OpenGlContent.cs | `samples/ControlCatalog/Pages/OpenGl/OpenGlContent.cs` | _points、_indices配列（129-130行）で頂点・インデックスバッファを確認 |
| 1-3 | GlPageKnobs.xaml.cs | `samples/ControlCatalog/Pages/OpenGl/GlPageKnobs.xaml.cs` | Yaw/Pitch/Roll/Discoプロパティ（14-68行）でパラメータ定義を確認 |

**読解のコツ**: OpenGLの頂点バッファオブジェクト（VBO）とインデックスバッファオブジェクト（IBO）の概念を理解しておくと良い。

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

OpenGLコントロールの初期化処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OpenGlPage.xaml.cs | `samples/ControlCatalog/Pages/OpenGlPage.xaml.cs` | コンストラクタ（16-26行）でGL.Initの呼び出しとSnapshot表示制御 |
| 2-2 | OpenGlPage.xaml.cs | `samples/ControlCatalog/Pages/OpenGlPage.xaml.cs` | OpenGlPageControl.Init（52-56行）でKnobsとの接続 |

**主要処理フロー**:
1. **18行**: InitializeComponentでXAMLをロード
2. **19行**: GL.Init(Knobs)でKnobsコントロールを接続
3. **21-25行**: ウィンドウモードの場合のみSnapshotボタンを表示

#### Step 3: シェーダープログラムを理解する

頂点シェーダーとフラグメントシェーダーのGLSLコードを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OpenGlContent.cs | `samples/ControlCatalog/Pages/OpenGl/OpenGlContent.cs` | VertexShaderSource（50-78行）で頂点変換とディスコエフェクト |
| 3-2 | OpenGlContent.cs | `samples/ControlCatalog/Pages/OpenGl/OpenGlContent.cs` | FragmentShaderSource（80-120行）でPhongライティングとカラー計算 |

**主要処理フロー**:
- **63-72行**: ディスコエフェクトによるスケール・歪み計算
- **92-102行**: ディスコカラーの動的計算
- **104-116行**: Phongライティングモデルの適用

#### Step 4: OpenGLレンダリングループを理解する

毎フレームの描画処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | OpenGlContent.cs | `samples/ControlCatalog/Pages/OpenGl/OpenGlContent.cs` | OnOpenGlRender（263-310行）でフレーム描画処理 |
| 4-2 | OpenGlPage.xaml.cs | `samples/ControlCatalog/Pages/OpenGlPage.xaml.cs` | OnOpenGlRender（71-79行）でコントロールからの呼び出し |

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

```
OpenGlPage (UserControl)
    │
    ├─ OpenGlPageControl (OpenGlControlBase継承)
    │      ├─ OnOpenGlInit()
    │      │      └─ OpenGlContent.Init()
    │      │             ├─ シェーダーコンパイル
    │      │             ├─ VBO/IBO作成
    │      │             └─ VAO設定
    │      │
    │      ├─ OnOpenGlRender()
    │      │      └─ OpenGlContent.OnOpenGlRender()
    │      │             ├─ Viewport設定
    │      │             ├─ 行列計算（Model/View/Projection）
    │      │             ├─ Uniform変数設定
    │      │             └─ DrawElements呼び出し
    │      │
    │      └─ OnOpenGlDeinit()
    │             └─ OpenGlContent.Deinit()
    │                    └─ リソース解放
    │
    ├─ GlPageKnobs (UserControl)
    │      ├─ Yaw (Property)
    │      ├─ Pitch (Property)
    │      ├─ Roll (Property)
    │      ├─ Disco (Property)
    │      └─ Info (Property)
    │
    └─ SnapshotClick()
           └─ CreateCompositionVisualSnapshot()
                  └─ 新規Window表示
```

### データフロー図

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

teapot.bin ─────────────▶ OpenGlContent ────────────▶ OpenGLレンダリング
(埋め込みリソース)         ├─ 頂点データ解析              │
                          └─ 法線ベクトル計算             ▼
                                                     GPU描画

スライダー操作 ──────────▶ GlPageKnobs ─────────────▶ 回転パラメータ
(Yaw/Pitch/Roll/Disco)    ├─ プロパティ変更通知           │
                          └─ RequestNextFrameRendering   ▼
                                                     再描画リクエスト

Snapshotボタン ──────────▶ CreateCompositionVisualSnapshot ──▶ Image
                          └─ 1.5倍スケール                   ↓
                                                        新規ウィンドウ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OpenGlPage.xaml | `samples/ControlCatalog/Pages/OpenGlPage.xaml` | XAML | 画面レイアウト定義 |
| OpenGlPage.xaml.cs | `samples/ControlCatalog/Pages/OpenGlPage.xaml.cs` | ソース | コードビハインド・OpenGLコントロール |
| OpenGlContent.cs | `samples/ControlCatalog/Pages/OpenGl/OpenGlContent.cs` | ソース | OpenGLレンダリングロジック |
| GlPageKnobs.xaml | `samples/ControlCatalog/Pages/OpenGl/GlPageKnobs.xaml` | XAML | 操作パネルレイアウト |
| GlPageKnobs.xaml.cs | `samples/ControlCatalog/Pages/OpenGl/GlPageKnobs.xaml.cs` | ソース | 操作パネルプロパティ定義 |
| teapot.bin | 埋め込みリソース | データ | ティーポット3Dモデルデータ |
