Skip to content

Promete v2 - #80

Draft
EbiseLutica wants to merge 107 commits into
masterfrom
v2
Draft

Promete v2#80
EbiseLutica wants to merge 107 commits into
masterfrom
v2

Conversation

@EbiseLutica

@EbiseLutica EbiseLutica commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator
  • Texture2D: UV座標を持てるように
  • OpenGLTextureFactory: LoadSpriteSheetで、同じハンドルのUV違いのTexture2Dを生成するように
  • グラフィック描画の仕組みとして、コマンドキューシステムを追加
    • テクスチャ描画、プリミティブ描画、マスクモード有効化など、GPUへの命令を「コマンド」としてカプセル化し、そのコマンドを毎フレーム実行するという低レイヤー層を新たに導入
    • NodeからRendererを廃止し、コマンドを発行するように
  • .NET 8 から .NET 10へ移行

EbiseLutica and others added 3 commits March 18, 2026 03:15
* feat(Renderer): Step 1 - レンダリングコマンド型を定義

IRenderCommand マーカーインターフェースと各コマンド型を追加。
型マッチングで処理するため RenderCommandKind enum は不要と判断し採用しない。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(Renderer): Step 2 - ScissorStateTrackerを実装

コレクトフェーズでGL呼び出しなしにシザー矩形をCPUスタックで管理する
ScissorStateTrackerを追加。Push()が計算済みの BeginScissorCommand /
EndScissorCommand ペアを返す。あわせて BeginScissorCommand から
不要なParent系フィールドを削除し簡素化した。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(Renderer): Step 3 - RenderCommandQueue / CommandRunner を実装、FlushBarrierCommand を削除

- RenderCommandQueue をバックエンド非依存で実装。CommandRunner<T> の登録により
  コマンド実行ロジックを外部から差し替え・拡張可能にした
- Enqueue() 時に DrawTextureCommand を DrawTextureBatchedCommand へ自動集約する
  ことで ProcessAndFlush() での特別扱いを不要にした
- FlushBarrierCommand を削除: Enqueue時バッチ集約により任意のコマンドが
  自動的にバッチを区切るため不要と判断
- CommandRunner<T> 基底クラスを追加

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(Renderer): Step 4 - GL CommandRunner 群を実装

各コマンドに対応するGLランナーを Promete.Nodes.Renderer.GL.Runners に追加。
ランナー間でステンシル有効状態を共有するための GLRenderState も追加。
GLDrawTextureBatchedCommandRunner は Step 5 の GLBatchTextureRenderer に依存するため
現時点ではビルド未完。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(Renderer): Step 5/6 - GLBatchTextureRenderer とインスタンシングシェーダーを実装

- DrawTextureCommand に Pivot フィールドを追加(NineSliceSprite等のオフセット描画に対応)
- texture_instanced.vert/frag を追加(per-instance mat4 + vec4 tintColor)
- GLBatchTextureRenderer を実装。DrawInstanced() で件数を問わずインスタンシング統一。
  EnsureInstanceBufferCapacity() で初期512・倍増リサイズ
- GLDrawTextureBatchedCommandRunner を internal に変更(DrawTextureBatchedCommand が internal のため)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(Renderer): Step 7 - NodeRendererBase に Collect() を追加

Collect() を virtual メソッドとして追加。デフォルト実装は旧 Render() を
LegacyRenderCommand にラップしてキューに積む。
Render() を [Obsolete] に変更し後方互換を維持。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(Renderer): Step 8/9 - 各レンダラーを Collect() に移行、PrometeApp を更新

- GLSpriteRenderer/GLTextRenderer/GLShapeRenderer/GLTilemapRenderer/
  GLNineSliceSpriteRenderer を Collect() に移行
- GLPieSpriteRenderer は専用シェーダーのため LegacyRenderCommand フォールバックを維持
- GLContainbleNodeRenderer/GLMaskedContainerRenderer を Collect() に移行し
  ScissorStateTracker を導入
- PrometeApp に CollectNode() を追加し、OnRender() をコマンドキュー方式に変更
- RenderCommandQueue/ScissorStateTracker を OnStart でキャッシュし
  毎フレームの DI 解決コストを除去

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(Renderer): Step 10 - DI登録・ランナー紐付け、RegisterRunnerRange を追加

- OpenGLDesktopAppExtension に GLBatchTextureRenderer / ScissorStateTracker /
  RenderCommandQueue / GL Runners を登録
- Build() 後に RegisterRunnerRange() でランナーをキューへ一括紐付け
- CommandRunner に CommandType プロパティを追加
- RenderCommandQueue に RegisterRunnerRange() を追加

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(Renderer): 全Helperクラスをコンストラクタ遅延初期化に変更

DI解決時点ではウィンドウが未オープンのため window.GL にアクセスできず
クラッシュしていた問題を修正。GLBatchTextureRenderer に加え、
GLPrimitiveRendererHelper / GLTextureRendererHelper /
GLPieSpriteRendererHelper / GLMaskedContainerHelper の全ヘルパーも
EnsureInitialized() パターンで初回描画時まで GL 初期化を遅延させた。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ConsoleLayer): 新レンダリングエンジンでも動作するよう修正

* 最適化

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor

* Texture2DにuvStart、uvEndを追加し、UV座標を明示的にレンダリング時に指定できるように

* LoadSpriteSheetで、同じハンドルを用いるように

* 1.0.1-exp.1

* テクスチャの一部が見切れる問題を修正

* テクスチャのマッピングがおかしかった問題を修正

* BatchTextureRendererに、TextureのUV対応を追加
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Mar 18, 2026

Copy link
Copy Markdown

Deploying promete with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2d5c455
Status:🚫  Build failed.

View logs

EbiseLutica and others added 26 commits March 18, 2026 16:39
- Node.Collect(queue, ctx) を追加し、各Nodeが直接コマンドをキューに積むように変更
- NodeRendererBase, 全GLRenderer (8ファイル), ScissorStateTracker を削除
- LegacyRenderCommand, ScissorCommands を削除
- BeginTrimCommand/EndTrimCommand に置き換え、RenderCommandQueueにTrimスタック管理を統合
- DrawPieTextureCommand + GLDrawPieTextureCommandRunner を新設
- RenderContext を導入し、ウィンドウ情報をCollectに渡す
- PrometeApp から UseRenderer, _renderers, ResolveRenderer を削除

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
refactor: NodeRenderer廃止、Nodeが直接コマンドを生成する方式に移行
feat: ShaderProgram/Material APIとエフェクトデモの追加
…ctory に分割

TextureFactory を基底クラス TextureFactoryBase と OpenGL固有実装 GLTextureFactory に分離した。
OpenGLTextureFactory は GLTextureFactory に統合して削除した。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
IWindow の複合責務を分解するため、以下を追加した:
- BackendBase: バックエンド実装の抽象基底クラス
- IGameView: 画面表示に関するインターフェース
- ITimeProvider: 時間情報に関するインターフェース

OpenGLDesktopBackend と HeadlessBackend を BackendBase ベースで実装した。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
IWindow に [Obsolete] を付与し、後方互換のための CompatibleWindow アダプタを追加した。
新規コードでは IGameView / ITimeProvider を直接使用することを推奨する。
不要になった OpenGLDesktopWindow を削除した。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PrometeApp に Start/PreUpdate/Update/PostUpdate/PreRender/Render/PostRender/Destroy
イベントを追加し、BackendBase を通じてバックエンドを初期化する設計に変更した。
Scene も IWindow 依存を除去し、IGameView / ITimeProvider を参照するよう更新した。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Keyboard / Mouse / Gamepad / Gamepads が IWindow ではなく
PrometeApp のイベントと SilkNetCommonInputProvider を通じて動作するよう変更した。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CoroutineManager が IWindow ではなく PrometeApp イベントを購読するよう変更した。
WaitForSeconds が IWindow.TotalTime の代わりに ITimeProvider.TotalTime を参照するよう更新した。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OpenGLDesktopAppExtension を Build<OpenGLDesktopBackend>() 経由のビルダーに変更した。
GLScreenBlitter の IWindow 参照を IGameView に置き換えた。
HeadlessAppExtension も新バックエンドアーキテクチャに対応した。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EbiseLutica and others added 30 commits May 31, 2026 09:43
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
過去 (894bfcf) と同様に、UVオフセットによる挙動が不安定なため元に戻す。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
タイル総数とビューポート容量の比較ではなく、タイルマップの
バウンディングボックス(列数・行数)とビューポートのタイル収容数を
比較するように変更。

旧ロジックはタイル配置の形状を考慮しないため、例えば 200×10 タイルの
マップ(2000タイル)に対してビューポート容量(82×47=3854)が上回ると
誤って RenderAll を選択し、画面外の多数のタイルも毎フレーム処理していた。

新ロジックはマップの列数・行数がビューポートのタイル収容数に収まる
場合のみ RenderAll を選択し、それ以外は Scan に切り替える。
SetTile でインクリメンタルにバウンディングボックスを更新し、
Clear でリセットする。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014gryrJ6noVbM34bPXSDVj7
…ce-6647x2

fix(Tilemap): AutoモードのGetPreferredModeをタイル空間的広がり比較に修正
バックスラッシュを含む不正なファイル名がコミットされており、
Windows環境でのgit pull/checkoutが失敗する原因となっていたため削除。
Time / TimeInSamples プロパティに setter を追加し、再生位置を
変更できるように。再生中は OpenAL バッファを詰め直してシークし、
停止中の設定値は次回再生の開始位置になる(Stop で 0 リセット)。

あわせて FillSamples の offset が範囲外のとき読み出しサイズが
負になる問題をガード。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DSPフィルター対応の土台として、オーディオパイプラインの交換フォーマットを
16bit shortからfloat32に変更。読み出し位置・サイズをフレーム単位に統一し、
シーク不可・長さ未確定ソースを契約として明文化。

- IAudioSource: Frames/Channels/SampleRate + FillSamples(Span<float>, int)。Bits廃止
- WaveAudioSource: floatストア化。8/16/24/32bit PCMと32bit IEEE floatに対応
- VorbisAudioSource: NVorbisのfloatデコードを直接保持(short変換削除)。
  デコードループがtemp.Length固定で回るバグとoffset範囲外例外を修正
- MeltySynthAudioSource: float版Renderに切替、渡されたbuffer長に追従
- AudioPlayer: 暫定のfloat→short変換ブリッジ(本体はフェーズ3で書き換え予定)
- Promete.Test: AudioSourceTests追加(12件、デバイス不要)。
  テストプロジェクトのみStyleCopメンバー並び順ルールを無効化

BREAKING CHANGE: IAudioSourceのシグネチャ変更。カスタムソース実装は要改修

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
OpenALのカレントコンテキストはプロセスグローバルであり、AudioPlayerごとに
コンテキストを作る現行実装では複数インスタンスが共存できなかった。
参照カウント式のAudioDeviceに所有を一元化し、この問題を解消する。

- AudioDevice: ALCデバイス/コンテキストのプロセス共有シングルトン。
  AL_EXT_FLOAT32拡張の判定を初期化時に実施(フェーズ3のfloat直渡しで使用)
- AudioPlayer: 自前のデバイス生成を廃止しAudioDevice.Acquire()へ。
  Disposeに二重呼び出しガードを追加
- IAudioOutput + AudioRenderCallback: 常駐レンダーループ(フェーズ3)用の
  出力ドライバ抽象。NullAudioOutput / CaptureAudioOutput(テスト用)を同梱
- CaptureAudioOutputはRenderNext(N)で「N回バッファ生成=時間経過」の
  決定的テストを可能にする

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
再生のたびにループを起動する方式をやめ、プレイヤーは常に音を出し続け
(停止時は無音)、Play/Stop/Seek/Pauseは「次のバッファ生成時に適用される
コマンド」となる。ライフサイクル競合を構造的に排除する。

- AudioRenderPipeline: 状態機械(Stopped/Playing/Pausing/FadingOut)、
  コマンドキューのバッファ境界適用、シーク、バッファ内ループ継続、
  サンプル単位フェード、constant-powerソフトウェアパン、モノラル→ステレオ
  アップミックスを持つ純粋ロジック。OpenAL・スレッド非依存で決定的にテスト可能
- OpenALAudioOutput: 専用スレッド+トリプルバッファの常駐出力ドライバ。
  AL_EXT_FLOAT32対応時はfloat直渡し。DisposeはJoinで完了待ち
- AudioPlayer: 互換ファサード化。公開APIは維持しつつ、旧再生ループ・
  CancellationTokenSource・フェード用Task・AL直接操作を全廃
- 修正されるバグ: フェード後のGain破壊、フェード停止レース、Dispose時の
  コンテキスト破棄競合、Play連打での二重ループ、終了待機ハング、
  ステレオ音源にパンが効かない問題
- AudioPlayerPipelineTests: CaptureAudioOutputによるデバイス非依存・
  実時間なしの決定的テスト22件
- StopTokenSource(未使用)を削除

BREAKING CHANGE: 再生はステレオ出力に統一。IAudioOutput.Startの
シグネチャ変更(Pitchプロパティ・getSampleRate追加)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PrometeApp.Currentがプロセスグローバルなまま破棄後も残留し、後から生成
されたAudioPlayer等が死んだアプリへイベント配送してしまう問題を修正。

- PrometeApp.Dispose: 自身がCurrentなら解除
- テスト: PrometeAppを生成する既存テストをusingで確実に破棄
- StyleCopルール緩和(SA1122/SA1503/SA1623)とCHANGELOG更新

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AudioPlayer.Filters に IAudioFilter を追加すると、レンダーパイプラインの
出力段に適用される。フィルターは常駐ラインの一部として再生停止中も
毎バッファ動作し続けるため、ディレイの残響がStop後も自然に鳴り切る。
停止・シーク・ソース切替でフィルター状態は自動リセットされない。

- IAudioFilter: Process(Span<float>, channels, sampleRate) + Reset()。
  パラメータはfloat単発読み書きでロックフリー
- AudioPlayer.Filters: ObservableCollection<IAudioFilter>。変更は
  次バッファからスレッドセーフに反映
- 標準フィルター3種: DelayFilter(ステレオ独立ライン+フィードバック)、
  LowPassFilter(RBJ biquad)、DistortionFilter(tanhソフトクリップ)
- パイプラインが最後に再生したサンプルレートを保持し、停止時の
  出力ストリーム再構成とフィルター状態破棄を防止
- BufferSizeデフォルトを10000→1024フレームに変更。実効レイテンシ
  約680ms→約70ms
- AudioFilterTests: インパルス応答・RMS減衰・クランプ・残響継続の
  信号検証10件

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- PlayOneShot(Async)にfollowsMasterGain引数を追加(trueでプレイヤーの
  Gainを乗算。デフォルトfalseで従来挙動)
- fire-and-forgetのPlayOneShotで例外を捕捉しログ出力(未観測例外による
  プロセスクラッシュを防止)
- LowPassFilterにMixプロパティを追加(dry/wet比率。デフォルト1=ウェット
  のみ)。ミックス比率に関わらず内部状態を常に更新するため、値を徐々に
  変化させてもプチノイズなくスムーズに遷移できる
- Promete.Exampleにフィルターデモシーン(/audio/filters.demo)を追加
- ドキュメント: オーディオフィルターの新ガイドページ、再生・カスタム
  ソースガイドをfloat/フレーム契約に更新、docs-llm.md更新、CHANGELOG追記

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(Audio)!: オーディオシステム v2 — pull型レンダーパイプライン・DSPフィルター・シーク対応
- Time/TimeInSamples がレンダリング済み位置でなく「実際に聴こえている位置」を返すように修正。
  パイプラインにレンダリング履歴を導入し、出力段の未再生キュー分を逆引きして算出
- Play/シーク時に未再生バッファをフラッシュし、先行キューされた無音・旧音声の排出待ち(最大~70ms)を解消
- レンダースレッドのポーリングを AutoResetEvent 化し、フラッシュ即応
- BufferSize / BufferCount / Latency プロパティでレイテンシと負荷のバランスを調整可能に

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Right/Bottomプロパティのinclusive端(-1オフセット)をIntersect内で
そのまま使っていたため、幅か高さが0の矩形が実質1pxとして扱われ、
隣接する矩形と誤って交差判定されていた。Vector/VectorInt.Inで
既に対応済みのゼロサイズガードと合わせ、テストを追加。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants