Promete v2 - #80
Draft
EbiseLutica wants to merge 118 commits into
Draft
Conversation
* 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対応を追加
- 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が直接コマンドを生成する方式に移行
close #79
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>
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で 既に対応済みのゼロサイズガードと合わせ、テストを追加。
これまで Scene 派生クラスの自動登録は Assembly.GetEntryAssembly() のみを
走査していたため、ゲームをエンジン層とコンテンツ層の2プロジェクトに分割し、
シーンをエンジン側のアセンブリに置くと LoadScene が
「The scene "Xxx" is not registered.」で落ちていた。
PrometeAppBuilder に UseScenesFrom(Assembly) と UseScenesFrom<T>() を足し、
エントリアセンブリに加えて任意のアセンブリを探索対象にできるようにした。
PrometeApp.Create()
.UseScenesFrom(typeof(LoadingScene).Assembly)
.BuildWithVulkanDesktop(opts);
既定の挙動は変えていないので、単一アセンブリの構成には影響しない。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019eZmjGkVajSwKumgLsMwrA
Scene 派生クラスの自動登録がエントリアセンブリに限られることは、 これまでドキュメントに書かれていなかった。エントリアセンブリ外に シーンを置いたときの対処とあわせて記載する。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019eZmjGkVajSwKumgLsMwrA
フォント機能刷新の第一段階として、レイアウトとラスタライズを分離した 新しい抽象を導入する。 - IGlyphSource: コードポイントからグリフを供給する抽象。 ベクターフォント・ビットマップフォント・外字を同一の枠組みで扱えるようにし、 レイアウトの責務は持たせない。 - FreeTypeGlyphSource: FreeTypeSharp を用いた実装。 埋め込みビットマップストライクを自動的に利用するため、 ドット絵フォントもピクセルパーフェクトに描画できる。 - GlyphAtlas: ラスタライズ済みグリフを 1 枚のテクスチャへ集約する。 同一ページのグリフはテクスチャハンドルを共有するため、 RenderCommandQueue によって 1 回の描画命令へバッチ化される。 - TextureFactoryBase.Update: アトラスへの部分書き込みのために追加。 既存の Font (ImageSharp 実装) はこの時点では変更していない。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ImageSharp によるテキスト描画を廃止し、レイアウトからラスタライズまでを Promete 自身が制御するようにする。 - TextLayoutEngine: 行分割・整列・カーニング・文字間を解決する。 WrapMode.Mixed により、和文は任意の位置で、欧文は単語境界で折り返す。 - Text ノード: レイアウト結果のグリフを個別に Enqueue する。 同一アトラスページのグリフは 1 回の描画命令にまとめられるため、 内容を毎フレーム書き換えてもテクスチャの再生成が発生しない。 - Font: グリフソースとサイズ・スタイルを束ねた不変の値オブジェクトへ変更。 IFont は、レイアウトまで実装に押し付ける抽象であり Text が具象へ依存する原因となっていたため削除した。 - CompositeGlyphSource: フォールバックチェーン。 外字の差し込みと、収録されていない文字の補完を同じ仕組みで解決する。 - BitmapGlyphSource: 画像ベースのビットマップフォントおよび外字。 フォントサイズは元の大きさに対する整数倍として解決し、ドットを保つ。 - スタイルは専用の字形がない場合、FreeType により合成する。 ConsoleLayer の行数計算は、二分探索的な測定からメトリクス参照へ変更した。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- PTML に終了タグを持たない単独タグを導入し、<tex=名前> で外字を差し込めるようにする。 単独タグは本文へ U+FFFC (置換文字) を 1 文字挿入し、 範囲を持つ既存の装飾と同じ仕組みでレイアウトへ伝える。 - INamedGlyphSource: 名前からグリフを引く抽象。 BitmapGlyphSource は名前付き登録時に私用領域のコードポイントを自動採番する。 - 縁取りはラスタライズ後のアルファを膨張させて生成する。 FT_Stroker と異なりアウトラインを必要としないため、 ビットマップフォントや外字にも同じように適用できる。 文字ごとに重ねると隣の本体が隠れるため、全文字の縁を先に描画する。 - 禁則処理 (KinsokuMode.Standard) を追加。 句読点や閉じ括弧を行頭に、開き括弧を行末に置かないようにする。 - MaxLines と Ellipsis を追加。行が溢れた場合は省略記号を末尾に挿入する。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ImageSharp の SystemFonts に代わり、実行環境のフォントディレクトリを 走査してファミリー名の索引を構築する。 - SystemFonts: ファミリー名による検索を提供する。 索引は初回アクセス時にのみ構築されるため、 ファイル指定のみでフォントを扱うアプリケーションには走査のコストが発生しない。 (Windows で 414 ファイル・458 フェイスの走査に約 320ms) - Font.FromSystem: ファミリー名とスタイルからフォントを読み込む。 要求されたスタイルの字形が存在する場合はそれを使い、 存在しない場合のみ描画時に合成する。 - Font.GetDefault: 環境ごとの候補ファミリーから既定のフォントを解決する。 - Font.FromFile: TTC などのコレクションに対応するため faceIndex を追加した。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CompositeGlyphSource.GetMetrics が常に先頭のグリフソースを参照していたため、 WithOverride で外字をチェーンの先頭へ置くと、 行の高さやベースラインが本文のフォントではなく外字基準になっていた。 結果として行が詰まり、本文の文字が下へずれて見えていた。 - CompositeGlyphSource に、行の高さの基準とするグリフソースを明示できるようにした。 Font.WithOverride および WithFallback は、常に本文のフォントを基準として保つ。 - BitmapGlyphSource の拡大率が、既定の偶数寄せの丸めによって 意図せず縮小されることがあった (24px 指定で 1.5 倍が 2 倍になる一方、 40px 指定では 2.5 倍が 2 倍に丸められていた)。中間値は大きい方へ丸めるようにした。 あわせて外字のデモを、本文のアセンダーにアイコンの下端を合わせるよう修正し、 アイコンの大きさと文字サイズの刻みを揃えた。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
FreeTypeGlyphSource と BitmapGlyphSource が、それぞれ独立した静的カウンタで 識別子を採番していたため、両者の識別子が 1 から重複していた。 グリフアトラスのキャッシュキーは (識別子, グリフ番号, オプション) で構成されるため、 外字と本文のグリフが同じキーに解決され、取り違えて描画されることがあった。 - GlyphSourceId: プロセス全体で一意な識別子を採番する。 IGlyphSource を実装する場合は、ここから採番する必要がある。 - FreeTypeGlyphSource・BitmapGlyphSource・CompositeGlyphSource を この採番へ統一した。 回帰を防ぐため、グリフアトラスへ実際に転送された内容を読み出して 取り違えを検出するテストを追加した。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
アトラスは使われなくなったグリフを個別には解放しないため、 キャッシュキーの種類が際限なく増える使い方をすると単調に肥大化していた。 特にフォントサイズを連続的に変化させた場合、 そのすべてが別のグリフとして積まれてしまう。 - GlyphRenderOptions.Size を 0.5px 単位へ丸めるようにした。 with 式による変更にも適用されるよう、設定時に丸めている。 - GlyphAtlas.MaxPages を追加し、ページ数が上限に達したらアトラスを作り直す。 描画の途中でページを解放すると発行済みの描画命令が 解放済みのテクスチャを参照してしまうため、 実際の解放は TrimIfNeeded によってフレームの境界まで遅延させる。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
フォント機能を FreeType ベースへ全面刷新する
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.