v1 → v2 移行ガイド
このガイドでは、Promete v1 で作られたプロジェクトを v2 に移行する手順を解説します。
アプリケーション開発者向け手順
Section titled “アプリケーション開発者向け手順”-
ターゲットフレームワークを更新する
プロジェクトファイル(
.csproj)のTargetFrameworkをnet10.0に変更してください。<!-- Before --><TargetFramework>net8.0</TargetFramework><!-- After --><TargetFramework>net10.0</TargetFramework>LangVersionを明示している場合は、14以上(または削除して既定値)にしてください。手順5で使う.Degrees/.Radiansは C# 14 の機能で実装されています。変更後、
dotnet restoreを実行してパッケージを再取得してください。 -
Promete パッケージを更新する
NuGet パッケージを v2 系の最新版に更新してください。
Terminal window dotnet add package Prometeプラグインパッケージを使用している場合は合わせて更新してください(例:
Promete.ImGui)。v2 では依存パッケージも変わっています。次に当てはまる場合は、プロジェクト側の参照を調整してください。
- Silk.NET を直接参照している: Promete v2 は Silk.NET のフォークを使っており、パッケージ ID は
Promete.Silk.*です(例:Promete.Silk.OpenGL)。upstream のSilk.NET.*と併用すると同じアセンブリ名が二重に持ち込まれるため、PackageReferenceの ID をPromete.Silk.*に揃えてください。アセンブリ名と名前空間はSilk.NET.*のままなので、usingの変更は不要です。 SixLabors.ImageSharp/SixLabors.Fonts/SixLabors.ImageSharp.Drawingを使っている: v2 の Promete はこれらに依存しなくなったため、推移的には入ってきません。必要なら自分でPackageReferenceを追加してください。- PNG / BMP 以外の画像を読み込んでいる: v2 の画像読み込みは Promete 自身が実装しており、対応形式は PNG と BMP のみです。JPEG や GIF などは
LoadがNotSupportedExceptionをスローするので、PNG へ変換してください。
- Silk.NET を直接参照している: Promete v2 は Silk.NET のフォークを使っており、パッケージ ID は
-
IWindowの参照をView/Time/Appに置き換えるv1 では
IWindowがウィンドウ操作・時間管理・イベントのすべてを担っていましたが、v2 では次のように分割されました。- 画面に関するもの:
IGameView(シーンからはView) - 時間に関するもの:
ITimeProvider(シーンからはTime) - ゲームループのイベントと終了処理:
PrometeApp(シーンからはApp)
シーン内の
window.*の呼び出しを次の表を参考に書き換えてください。v1 v2 window.Size/Width/HeightView.Size/Width/Heightwindow.ActualSize/ActualWidth/ActualHeightView.ActualSize/ActualWidth/ActualHeightwindow.Location/X/YView.Location/X/Ywindow.TitleView.Titlewindow.ScaleView.Scalewindow.PixelRatioView.PixelRatiowindow.ModeView.Modewindow.IsFullScreen/IsVisible/IsFocused/TopMostView.IsFullScreen/IsVisible/IsFocused/TopMostwindow.TakeScreenshot()/SaveScreenshotAsync()View.TakeScreenshot()/SaveScreenshotAsync()window.FileDropped/Resize(イベント)View.FileDropped/Resizewindow.DeltaTime/TotalTime/TotalTimeWithoutScaleTime.DeltaTime/TotalTime/TotalTimeWithoutScalewindow.TotalFrameTime.TotalFramewindow.FramePerSeconds/UpdatePerSecondsTime.FramePerSeconds/UpdatePerSecondswindow.TargetFps/TargetUpsTime.TargetFps/TargetUpswindow.TimeScaleTime.TimeScalewindow.Start/Update/Render/Destroy(イベント)App.Start/Update/Render/Destroywindow.PreUpdate/PostUpdate(イベント)App.PreUpdate/PostUpdatewindow.Exit()App.Exit()window.IsVsyncMode起動時の WindowOptions.IsVsyncModeのみ(実行中の変更は不可)コンストラクタで
IWindowを受け取っていたシーンは、コンストラクタから削除してView/Timeプロパティを直接使うように変更してください。public class MainScene(IWindow window) : Scene{public override void OnUpdate(){var dt = window.DeltaTime;var size = window.Size;window.Title = "My Game";}}public class MainScene : Scene{public override void OnUpdate(){var dt = Time.DeltaTime;var size = View.Size;View.Title = "My Game";}}シーン以外のクラス(自作プラグインなど)では、コンストラクタで
IGameView/ITimeProviderを受け取ってください。どちらもPromete.Backends名前空間にあります。using Promete.Backends;public class MyPlugin(IGameView view, ITimeProvider time){// ...} - 画面に関するもの:
-
TextureFactoryの参照先を変更するテクスチャの読み込みで
Window.TextureFactoryを使っている箇所をApp.TextureFactoryに置き換えてください。var texture = Window.TextureFactory.Load("image.png");var texture = App.TextureFactory.Load("image.png");またはコンストラクタ経由で
TextureFactoryBaseをインジェクションして取得することもできます。public class MyScene(TextureFactoryBase textureFactory) : Scene{public override void OnStart(){var texture = textureFactory.Load("./path/to/texture.png");}}TextureFactory型を明示して変数やフィールドに受けている場合は、型名をTextureFactoryBaseに変更してください。また、
LoadSpriteSheetの挙動が変わっています。v1 ではセルごとに独立したテクスチャを作っていましたが、v2 では画像全体を1枚のテクスチャとして読み込み、全セルがそれを共有します。そのため、セルを1つDisposeすると、同じスプライトシートの全セルが使えなくなります。foreach (var cell in cells){cell.Dispose();}// どれか1つを1回だけ破棄すれば、全セルが解放されますcells[0].Dispose();一部のセルだけを破棄して、残りのセルを使い続けることはできません。
-
Angle型の変更に対応するv2 では角度を表す
Angle構造体が追加され、ノードの回転角度など、角度を扱う API の型がfloatからAngleに変わりました。float/intとの暗黙的な変換はできないので、Angleを受け取るプロパティ・メソッドに数値を直接渡すとコンパイルエラーになります。拡張プロパティ
.Degrees/.Radiansを使ってAngleを生成してください。sprite.Angle = 90f;sprite.Angle += 1f;sprite.Angle = 90.Degrees; // int から度数法sprite.Angle = 90.0f.Degrees; // float から度数法sprite.Angle += 1.Degrees;sprite.Angle = MathF.PI.Radians; // float からラジアン// 静的メソッドでも生成できますsprite.Angle = Angle.FromDegrees(90);sprite.Angle = Angle.FromRadians(MathF.PI / 2);floatで角度を管理しているコードは次のように書き換えてください。float angle = 0;angle += Window.DeltaTime * 90;sprite.Angle = angle;float angle = 0;angle += Time.DeltaTime * 90;sprite.Angle = angle.Degrees;floatとして取り出す場合はToDegrees()/ToRadians()メソッドを使います。Angleには大小比較の演算子(<>など)がないため、比較する場合もfloatに変換してください。float deg = sprite.Angle.ToDegrees();float rad = sprite.Angle.ToRadians();if (sprite.Angle.ToDegrees() > 180) { /* ... */ }v1 で
MathHelper.ToRadian(sprite.Angle)/MathHelper.ToDegree(...)を使って単位を変換していた箇所は、上記のメソッドに置き換えてください。Angleを受け取る・返すようになった主な API は次のとおりです。Node.Angle、Node.AbsoluteAngle、Setup API の.Angle(...)Vector/VectorIntの.Angle()メソッドと、静的メソッドVector.Angle(from, to)/VectorInt.Angle(from, to)Vector.Rotate(...)
v1 の
Vector.Angle()はラジアンを返し、Node.Angleは度数法だったため、v1 ではMathHelper.ToDegreeで変換してから代入する必要がありました。v2 ではどちらもAngleなので、変換せずにそのまま代入できます。float angle = player.Location.Angle(mouse.Position); // ラジアンsprite.Angle = MathHelper.ToDegree(angle);Angle angle = player.Location.Angle(mouse.Position);sprite.Angle = angle;v1 の
Vector.Rotate(float)の引数はラジアンでした。書き換えるときは.Degreesではなく.Radiansを使ってください。// v1: v.Rotate(MathF.PI / 2)v.Rotate((MathF.PI / 2).Radians); -
WindowOptionsの渡し方を変更するPromete v2 では、
PrometeApp.RunメソッドにWindowOptions型を渡せなくなりました(Run(WindowOptions)/Run<TScene>(WindowOptions)は削除されました)。 代わりに、バックエンドの初期化時に渡す必要があります。OpenGLバックエンドでは次のように変更してください。
var app = PrometeApp.Create().BuildWithOpenGLDesktop();return app.Run<MainScene>(WindowOptions.Default with{Title = "Promete Demo",Mode = WindowMode.Resizable,TargetFps = 0,TargetUps = 0,IsVsyncMode = false,});var app = PrometeApp.Create().BuildWithOpenGLDesktop(WindowOptions.Default with{Title = "Promete Demo",Mode = WindowMode.Resizable,TargetFps = 0,TargetUps = 0,IsVsyncMode = false,});return app.Run<MainScene>(); -
シーン関連の変更に対応する
SceneWillChangeイベントの引数PrometeApp.SceneWillChangeの型がActionからAction<SceneTransitionEventArgs>に変わりました。引数から遷移の種類(Type)と、遷移前後のシーン(Previous/Next)を取得できます。App.SceneWillChange += () => Console.WriteLine("シーンが変わります");App.SceneWillChange += e => Console.WriteLine($"{e.Previous} → {e.Next}");シーンの自動登録
シーンの自動登録が、実行時のリフレクションからコンパイル時のソースジェネレータに変わりました。これに伴い、次のシーンは自動登録されなくなりました。
private/protectedなネスト型やfileローカル型のシーン(PROMETE0001の警告が出ます)。internal以上の可視性にしてください- 抽象クラス・ジェネリック型のシーン
Promete を NuGet パッケージではなく
ProjectReferenceで参照している場合(サブモジュールとして取り込んでいる場合など)は、ソースジェネレータが自動では適用されず、シーンが1つも登録されません。プロジェクトファイルに次の参照を追加してください。<ItemGroup><ProjectReference Include="path/to/Promete.SceneGen/Promete.SceneGen.csproj"OutputItemType="Analyzer"ReferenceOutputAssembly="false" /><CompilerVisibleProperty Include="OutputType" /></ItemGroup>エントリアセンブリ以外にシーンを置いている場合は、
UseScenesFromでそのアセンブリを指定してください。var app = PrometeApp.Create().UseScenesFrom<SomeTypeInContentAssembly>().BuildWithOpenGLDesktop(); -
フォントとテキストの変更に対応する
フォント機能が刷新され、テキストのレイアウトと描画を Promete 自身が行うようになりました。
Font.FromFile(path, ...)/Font.FromSystem(name, ...)/Font.GetDefault()/font.With(...)と、Textノードのコンストラクタ・主要なプロパティ(Content/Color/Font/BorderColor/BorderThickness/LineSpacing/UseRichTextなど)はそのまま使えます。次の API は変更・削除されています。
v1 v2 IFont削除。 Fontを使用Font.FromFile(Stream stream, ...)Font.FromStream(stream, ...)Font.FromSystem(name, CultureInfo culture, ...)削除。 Font.FromSystem(name, ...)を使用font.GetTextBounds(text, options)(戻り値Rect)TextLayoutEngine.Measure(text, font, options)(戻り値VectorInt)font.GenerateTexture(...)削除(代替なし) Text.WordWrap/TextRenderingOptions.WordWrapWrapMode(None/Character/Word/Mixed)Text.RenderTexture()Text.UpdateLayout()Text.RenderedTexture削除。サイズは Text.SizeまたはText.Layout.Sizeで取得var font = Font.FromFile(stream, 24);var bounds = font.GetTextBounds("Hello", new TextRenderingOptions());text.WordWrap = true;text.RenderTexture();var size = text.RenderedTexture?.Size;var font = Font.FromStream(stream, 24);var size = TextLayoutEngine.Measure("Hello", font, new TextRenderingOptions());text.WrapMode = WrapMode.Word; // 和文を含む場合は WrapMode.Mixedtext.UpdateLayout();var textSize = text.Layout.Size;見た目に影響する挙動の変更もあります。レイアウトが重要な画面は実際に表示して確認してください。
- 禁則処理(
KinsokuMode.Standard)が既定で有効になりました - カーニングが既定で有効になり(
UseKerning = true)、アンチエイリアスの有無に関わらず適用されます Text.Sizeは、描画された文字の外接矩形ではなく「文字の送り幅 × 行の高さ」で計算されるようになりました。Pivotを中央にしたテキストなどは位置が少しずれることがあります- 縁取りの描画方式が変わったため、太さの見え方が変わることがあります
TextRenderingOptions.TextColorの既定値が白になりましたFont.FromSystemは、フォントが見つからない場合にFontExceptionをスローしますFont.FromStreamは呼び出すたびに新しいフォントを読み込みます。サイズ違いのフォントが必要な場合は、読み込み直さずにfont.With(size)を使ってください
- 禁則処理(
-
オーディオの変更に対応する
AudioPlayerの主な API(Play/Stop/Pause/Resume/PlayOneShot/Gain/Pan/Pitch/Time/ イベントなど)はそのまま使えます。次の点に注意してください。- 音源のプロパティ:
WaveAudioSource/VorbisAudioSourceのSamplesはFramesに変わり、Bitsは削除されました(WaveAudioSource.Lengthも削除)。Samplesは全チャンネル合計のサンプル数でしたが、Framesは1チャンネルあたりのフレーム数です。v1 のSamplesと同じ値が必要な場合はFrames * Channelsとしてください AudioPlayer.BufferSize: 単位がフレーム数に変わり、既定値は 1024 になりました。v1 の値(全チャンネル合計のサンプル数。既定値 10000)をそのまま設定すると、ステレオでは約2倍の長さになりますStop(time)によるフェードアウト: v1 ではフェード後にGainが 1 に戻されていましたが、v2 ではGainを書き換えません- 出力とパン: 出力はステレオ固定になり、パンはステレオ音源にも効くようになりました。パンが中央のとき左右それぞれ約 0.707 倍(約 -3dB)されるため、ステレオ音源は v1 より小さく聞こえることがあります
- 音源のプロパティ:
-
ピクセルスナップの影響を確認する
v2 では、ノードの描画位置が既定で整数ピクセルにスナップされるようになりました。奇数サイズのノードを
Pivot(0.5f, 0.5f)で中央に置いたときなどのにじみを防ぐためです。サブピクセル単位の滑らかな移動・回転・ズームを行うノードでは、動きがカクつくことがあります。その場合はノードごとに無効化してください。
var sprite = new Sprite(texture).PixelSnap(false);// またはsprite.IsPixelSnapEnabled = false; -
同梱プラグインの変更に対応する
Promete.ImGuiのImGuiPluginのコンストラクタが(PrometeApp, IWindow)から(PrometeApp, InputProvider)に変わりました。ImGuiPluginを継承している場合は書き換えてください。public class MyImGuiPlugin(PrometeApp app, IWindow window) : ImGuiPlugin(app, window){protected override void OnConfigure(ImGuiIOPtr io) { /* ... */ }}using Promete.Backends.SilkNetCommon;public class MyImGuiPlugin(PrometeApp app, InputProvider provider) : ImGuiPlugin(app, provider){protected override void OnConfigure(ImGuiIOPtr io) { /* ... */ }}同様に、
Keyboard/Mouse/Gamepads/ConsoleLayer/CoroutineManagerのコンストラクタもIWindowを受け取らなくなりました。DI 経由で取得している場合は影響ありませんが、自分でnewしている場合は DI から取得するように変更してください。 -
ビルドして、残っている箇所を確認する
ここまでの手順を終えたら一度ビルドしてください。
IWindowを参照している箇所には[Obsolete]警告が出ます。警告の一覧を見て、手順3・4で対応できていない箇所が残っていないか確認してください。IWindowは後方互換のために残されていますが、次のメンバーはそのままでは動きません。IWindow.Run(WindowOptions):NotSupportedExceptionをスローします。手順6のとおりapp.Run()を使ってくださいIWindow.IsVsyncMode: 値を設定しても反映されませんIWindow._RawInputContext:RawInputContextに名前が変わっているため、コンパイルエラーになります。v2 ではInputProviderを DI で受け取り、CreateInput()で取得してくださいIWindow.TextureFactory: 型がTextureFactoryBaseに変わっています
その他の挙動の変更
Section titled “その他の挙動の変更”手順には含めていませんが、次の挙動も v1 から変わっています。該当する処理がある場合は確認してください。
Vector.Dot/VectorInt.Dotが正しい内積を返すようになりました(v1 は誤った式で計算していました)Rect.Intersect/RectInt.Intersectで、幅または高さが 0 の矩形は常に重なっていないと判定されるようになりましたAudioPlayer.IsPlayingは、Playを呼んだ直後から(フェード中も含めて)trueを返します
プラグイン・カスタムノード・バックエンド開発者向け追加手順
Section titled “プラグイン・カスタムノード・バックエンド開発者向け追加手順”ゲームロジックのみ書いていて、カスタムノード・独自の音源やフォント・バックエンドを実装していない場合はここから先は不要です。
-
NodeRendererをCollect()に移行するv1 では各ノードタイプに対して
NodeRendererBaseを継承したレンダラーを実装しUseRenderer<TNode, TRenderer>()で登録していましたが、この仕組みは v2 で廃止されました。代わりに、ノード自身が
Collect()メソッドをオーバーライドして、描画コマンドをキューに追加する方式に変わりました。キューに積まれたコマンドは、バックエンドが登録したコマンドランナーが実行します。同じテクスチャ・同じマテリアルが連続するDrawTextureCommandは自動的にまとめて描画されます。public class MyNode : Node { /* ... */ }public class MyNodeRenderer : NodeRendererBase{public override void Render(Node node) { /* ... */ }}var app = PrometeApp.Create().UseRenderer<MyNode, MyNodeRenderer>().BuildWithOpenGLDesktop();using System.Drawing;using Promete.Graphics.Rendering;using Promete.Graphics.Rendering.Commands;public class MyNode(Texture2D texture) : Node{public override void Collect(RenderCommandQueue queue, RenderContext ctx){queue.Enqueue(new DrawTextureCommand{Texture = texture,ModelMatrix = ModelMatrix, // 親の変形込みの変換行列TintColor = Color.White,Width = texture.Size.X,Height = texture.Size.Y,Material = Material,});}}登録コード(
UseRenderer<,>())はすべて削除してください。標準のコマンドは次のとおりです(いずれも
Promete.Graphics.Rendering.Commands名前空間)。コマンド 用途 DrawTextureCommandテクスチャの描画 DrawPrimitiveCommand図形の描画 DrawPieTextureCommand扇形に切り抜いた描画 BeginTrimCommand/EndTrimCommand矩形での切り抜き BeginStencilMaskCommand/BeginAlphaMaskCommand/EndMaskCommandマスク コンテナ系のノードについては、次の点も変わっています。
- v1 の
PrometeApp.RenderNode(Node)は削除されました。子ノードの描画にはPrometeApp.CollectNode(Node, RenderCommandQueue, RenderContext)を使います。ただしContainableNodeのCollect()は子ノードを自動で収集するため、通常はbase.Collect(queue, ctx)を呼べば十分です ContainableNodeのisTrimmable/sortedChildrenはIsTrimmable/SortedChildrenに名前が変わりましたIsTrimmableによるトリミングを処理するのはContainer/MaskedContainerのCollect()です。ContainableNodeを直接継承してトリミングする場合は、queue.PushTrim(this, ctx)/queue.PopTrim()で子ノードの収集を囲んでください
- v1 の
-
独自の描画コマンドを追加する(必要な場合)
標準のコマンドで表現できない描画を行う場合は、
IRenderCommandを実装したコマンドと、それを実行するCommandRunner<T>を作成し、RenderCommandQueueに登録します。public sealed class MyCommand : IRenderCommand{public required int Value { get; init; }}public sealed class MyCommandRunner : CommandRunner<MyCommand>{public override void Execute(MyCommand command) { /* 描画処理 */ }}// アプリのビルド後に登録するapp.GetPlugin<RenderCommandQueue>().RegisterRunner(new MyCommandRunner());ランナーが登録されていないコマンドは、何もせずに読み飛ばされます。
-
独自の音源(
IAudioSource)を新しい契約に合わせるIAudioSourceは、16bit 整数・サンプル単位の契約から、32bit 浮動小数点・フレーム単位の契約に変わりました。v1 v2 int? Samples(全チャンネル合計のサンプル数)int? Frames(1チャンネルあたりのフレーム数。終わりがない場合はnull)int Bits削除 FillSamples(short[] buffer, int offset)FillSamples(Span<float> buffer, int offsetFrames)戻り値: 書き込んだ shortの数と、終端に達したか戻り値: 書き込んだフレーム数と、終端に達したか bufferには -1〜1 の範囲の値を、チャンネルごとにインターリーブして書き込みます。public class MySource : IAudioSource{public int? Samples => _pcm.Length;public int Channels => 2;public int Bits => 16;public int SampleRate => 44100;public (int loadedSize, bool isFinished) FillSamples(short[] buffer, int offset){// ...}}public class MySource : IAudioSource{private readonly float[] _pcm; // -1〜1 のインターリーブ済みデータpublic int? Frames => _pcm.Length / Channels;public int Channels => 2;public int SampleRate => 44100;public (int FilledFrames, bool IsFinished) FillSamples(Span<float> buffer, int offsetFrames){var total = _pcm.Length / Channels;var frames = Math.Min(buffer.Length / Channels, Math.Max(0, total - offsetFrames));_pcm.AsSpan(offsetFrames * Channels, frames * Channels).CopyTo(buffer);return (frames, offsetFrames + frames >= total);}}実装時は次の点に注意してください。
bufferの長さは呼び出しごとに変わります。buffer.Lengthを超えて書き込まないでくださいFillSamplesはオーディオスレッドから呼ばれます。ファイル読み込みなど、ブロックする処理を行わないでください- 終端でないのに要求より少ないフレーム数を返した場合、残りは無音で埋められます
- 3チャンネル以上の音源は、
Playでは先頭の2チャンネルだけが再生されます。PlayOneShotAsyncではNotSupportedExceptionになり、PlayOneShotでは例外にならず何も再生されません
-
独自のフォント(
IFont)をIGlyphSourceに移行するIFontは削除されました。v2 ではレイアウトをエンジン側のTextLayoutEngineが行い、フォントの実装は「文字ごとのグリフを供給する」だけになりました。独自のフォントはIGlyphSourceを実装し、Font.FromGlyphSourceでFontに変換して使います。- 実装するメンバー:
SourceId/GetMetrics/TryGetGlyph/Rasterize/GetKerning、およびIDisposable SourceIdはGlyphSourceId.Next()で採番してくださいRasterizeが返すGlyphBitmapは RGBA8888 形式で、Bearingはベースラインを原点とした値にします
画像から作るビットマップフォントであれば、自分で実装しなくても
BitmapGlyphSourceで置き換えられます。var source = BitmapGlyphSource.FromGrid("font.png", (8, 8), " !\"#$%&'()*+,-./0123456789");var font = Font.FromGlyphSource(source, 16, FontStyle.Normal, false); - 実装するメンバー:
-
IWindowに依存していたプラグインを書き換えるプラグインで
IWindowのイベントを購読していた場合は、PrometeAppのイベントに置き換えてください(手順3の表を参照)。v2 ではPreRender/PostRenderイベントも追加されています。// v1window.Update += OnUpdate;// v2app.Update += OnUpdate;v1 の
IWindow._RawInputContextで Silk.NET の入力コンテキストを取得していた場合は、InputProvider(Promete.Backends.SilkNetCommon名前空間)を DI で受け取り、CreateInput()を呼んでください。public class MyInputPlugin(InputProvider inputProvider) : IInitializable{public void OnStart(){var input = inputProvider.CreateInput();}} -
バックエンドを
BackendBaseに移行するv1 では
IWindowインターフェースを直接実装してバックエンドを構成していましたが、v2 ではBackendBase抽象クラスを継承する方式に変わりました。各抽象メソッドを実装することで、ウィンドウ・時間管理・入力・レンダリングなどの責務を個別に提供します。
public class MyBackend : BackendBase{public override void OnInitialize(PrometeApp app, WindowOptions windowOptions) { /* ... */ }public override ITimeProvider SetupTimeProvider() => new MyTimeProvider();public override IGameView SetupGameView() => new MyGameView();public override InputProvider SetupInputProvider() => new MyInputProvider();public override IScreenBlitter SetupScreenBlitter() => new MyScreenBlitter();public override TextureFactoryBase SetupTextureFactory() => new MyTextureFactory();public override IRenderTextureProvider SetupRenderTextureProvider() => new MyRenderTextureProvider();public override IShaderFactory SetupShaderFactory() => new MyShaderFactory();public override void OnStart(PrometeApp app) { /* ... */ }public override void OnExit(PrometeApp app) { /* ... */ }}バックエンドの登録は
Build<T>()で行います。var app = PrometeApp.Create().Use<Keyboard>().Build<MyBackend>(WindowOptions.Default);実装にあたっては、次の点に注意してください。
- 呼び出し順:
OnInitialize→ 各Setup*の順で呼ばれ、その後に DI コンテナが構築されます。OnInitializeの時点で取得できるプラグインは、Use<T>(instance)でインスタンスとして登録されたものだけです - ゲームループ:
OnStartでは、app.OnStart()を1度呼んだ後、ゲームループの中でapp.OnUpdate()/app.OnRender()を呼び出してください。終了時にはapp.OnDestroy()を呼んでください - コマンドランナー: 描画は手順1のコマンドで行われます。
RenderCommandQueueはBuild<T>()が自動的に登録するので、app.GetPlugin<RenderCommandQueue>()で取得し、標準のコマンドに対応するランナーをRegisterRunnerで登録してください。テクスチャの描画は、連続するDrawTextureCommandをまとめたDrawTextureBatchedCommandとして届きます TextureFactoryBase: v1 のTextureFactoryから名前が変わりました。テクスチャの一部を書き換える抽象メソッドUpdate(Texture2D, VectorInt, VectorInt, byte[])が追加されました。v1 にあったLoadFromImageSharpImage(Image)は廃止されたため、実装は不要です。テクスチャはnew Texture2D(handle, size, onDispose)で生成しますIRenderTextureProvider: v1 のIFrameBufferProviderとはメンバーがまったく異なるため、作り直しになります。Createではnew RenderTexture(size, texture, this)を返し、Resizeでテクスチャを作り直した場合はRenderTexture.Textureを差し替えてくださいIShaderFactory:Compileでシェーダーをコンパイルし、ShaderProgram.SetCompiledData(handle, onDispose)で結果を設定してください。マテリアルの Uniform 値はMaterial.Uniformsで取得できます
また、以下の型が廃止・リネームされています。
v1 の型 v2 の代替 IWindow(バックエンドとして)BackendBaseIFrameBufferProviderIRenderTextureProvider(メンバーは別物)OpenGLDesktopWindowOpenGLDesktopBackendTextureFactory(抽象クラス)TextureFactoryBaseOpenGLTextureFactoryGLTextureFactoryGLFrameBufferProvider内部実装になりました。 IRenderTextureProviderを使用してくださいHeadlessAppExtesionHeadlessAppExtension(綴りの修正) - 呼び出し順:
名前空間の変更一覧
Section titled “名前空間の変更一覧”移動された型
Section titled “移動された型”| 型名 | v1 の名前空間 | v2 の名前空間 |
|---|---|---|
CoordinateExtension | Promete.Nodes.Renderer | Promete.Graphics.Rendering |
RenderingHelper | Promete.Nodes.Renderer | Promete.Graphics.Rendering |
GLHelper | Promete.Nodes.Renderer.GL.Helper | Promete.Graphics.Rendering.GL |
GLMaskedContainerHelper | Promete.Nodes.Renderer.GL.Helper | Promete.Graphics.Rendering.GL |
GLMaskedContainerHelper は、名前空間に加えてコンストラクタ((PrometeApp, RenderCommandQueue, IRenderTextureProvider))と RenderToTexture(MaskedContainer, RenderContext) のシグネチャも変わっています。
名前が変わった型
Section titled “名前が変わった型”| v1 の型 | v2 の型 |
|---|---|
Promete.Graphics.TextureFactory | Promete.Graphics.TextureFactoryBase |
Promete.Windowing.GLDesktop.OpenGLTextureFactory | Promete.Windowing.GLDesktop.GLTextureFactory |
Promete.Windowing.GLDesktop.OpenGLDesktopWindow | Promete.Backends.GL.OpenGLDesktopBackend |
Promete.Graphics.IFrameBufferProvider | Promete.Graphics.IRenderTextureProvider(メンバーは別物) |
Promete.Headless.HeadlessAppExtesion | Promete.Headless.HeadlessAppExtension |
削除された型
Section titled “削除された型”| v1 の型 | 代替 |
|---|---|
Promete.Graphics.Fonts.IFont | Promete.Graphics.Fonts.Font / IGlyphSource |
Promete.GLDesktop.GLFrameBufferProvider | なし(内部実装)。IRenderTextureProvider を使用 |
Promete.Nodes.Renderer.NodeRendererBase | ノード自身の Collect() メソッド |
Promete.Nodes.Renderer.GL.GLSpriteRenderer | Sprite.Collect() + DrawTextureCommand |
Promete.Nodes.Renderer.GL.GLTextRenderer | Text.Collect() + DrawTextureCommand |
Promete.Nodes.Renderer.GL.GLShapeRenderer | Shape.Collect() + DrawPrimitiveCommand |
Promete.Nodes.Renderer.GL.GLTilemapRenderer | Tilemap.Collect() + DrawTextureCommand |
Promete.Nodes.Renderer.GL.GLNineSliceSpriteRenderer | NineSliceSprite.Collect() + DrawTextureCommand |
Promete.Nodes.Renderer.GL.GLPieSpriteRenderer | PieSprite.Collect() + DrawPieTextureCommand |
Promete.Nodes.Renderer.GL.GLMaskedContainerRenderer | MaskedContainer.Collect() + マスクコマンド |
Promete.Nodes.Renderer.GL.GLContainbleNodeRenderer | ContainableNode.Collect() + BeginTrimCommand / EndTrimCommand |
Promete.Nodes.Renderer.GL.Helper.GLTextureRendererHelper | DrawTextureCommand(キューが自動的にバッチ化) |
Promete.Nodes.Renderer.GL.Helper.GLPrimitiveRendererHelper | DrawPrimitiveCommand + Promete.Graphics.Rendering.GL.Runners.GLDrawPrimitiveCommandRunner |
Promete.Nodes.Renderer.GL.Helper.GLPieSpriteRendererHelper | DrawPieTextureCommand + Promete.Graphics.Rendering.GL.Runners.GLDrawPieTextureCommandRunner |