Win2D メモ - DrumMidiEditor/DrumMidiEditorApp GitHub Wiki

参考URL
https://baydachnyy.com/2015/08/04/win2d-how-to-use-graphics-without-knowledge-in-directx/
-
CanvasControl
静的な描画に適している。 -
CanvasAnimatedControl
WinUI3 では実装されていない。(2022/07時点) -
CanvasSwapChainPanel
DirectXのプログラムしているとよく出てくる SwapChain
プレイヤーの描画はこれを使うようにしないとね
使う機能メモ
<UserControl
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
Unloaded="UserControl_Unloaded">
<Grid>
<canvas:CanvasControl Draw="EditerCanvas_Draw" />
</Grid>
</UserControl>
イベント処理:
private void UserControl_Unloaded( object sender, RoutedEventArgs args )
{
// Win2D アンロード
_EqualizerCanvas.RemoveFromVisualTree();
_EqualizerCanvas = null;
}
private void _EqualizerCanvas_Draw( CanvasControl sender, CanvasDrawEventArgs args )
{
}
線描画:
args.DrawingSession.DrawLine
(
x1,
y1,
x2,
y2,
LineColor,
LineSize
);
四角
args.DrawingSession.FillRectangle
(
aDrawRect,
BackColor
);
args.DrawingSession.DrawRectangle
(
aDrawRect,
aFormatRect.LineColor,
aFormatRect.LineSize
);
円:XY座標は円の中心点、縦横のサイズは半径で指定が必要
aGraphics.FillEllipse
(
(float)( rect.X + rect.Width / 2 ),
(float)( rect.Y + rect.Height / 2 ),
rect._width / 2,
rect._height / 2,
_FormatRect.BackColor
);
テキスト:テキストの書式設定内でフォントや左寄などの設定が必要
args.DrawingSession.DrawText
(
aLabelText,
aDrawRect,
TextColor,
TextFormat
);
ひし形(多角形):CanvasControl sender の情報も必要
Vector2[] ps =
{
new( rect._x , (float)( rect.Y + rect.Height / 2 ) ),
new( (float)( rect.X + rect.Width / 2 ) , rect._y ),
new( (float)( rect.Right ) , (float)( rect.Y + rect.Height / 2 ) ),
new( (float)( rect.X + rect.Width / 2 ) , (float)( rect.Bottom ) )
};
// ノートOFF描画
args.DrawingSession.DrawGeometry
(
CanvasGeometry.CreatePolygon( sender, ps ),
LineColor,
LineSize
);
CanvasControl から CanvasSwapChainPanel への変更は簡単
Drawイベントがないので、非同期の描画ループ処理など、描画プロセスの実装が必要
<UserControl xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml">
<Grid>
<canvas:CanvasSwapChainPanel x:Name = "_PlayerCanvas" />
</Grid>
</UserControl>
// スワップチェイン作成
_PlayerCanvas.SwapChain = new CanvasSwapChain
(
new CanvasDevice(),
DrawSet.ResolutionScreenWidth,
DrawSet.ResolutionScreenHeight,
96
);
// 描画サイズ変更
//_PlayerCanvas.SwapChain.ResizeBuffers
// (
// DrawSet.ResolutionScreenWidth,
// DrawSet.ResolutionScreenHeight,
// 96
// );
// 描画開始前準備
using var drawSession = _PlayerCanvas.SwapChain
.CreateDrawingSession( DrawSet.SheetColor.Color );
var args = new CanvasDrawEventArgs( drawSession );
// 描画処理
//_PlayerSurface?.OnDraw( _PlayerCanvas, args );
// 描画終了
_PlayerCanvas.SwapChain.Present();
Win2Dのサンプルより垂直同期
https://github.com/microsoft/Win2D-Samples/blob/reunion_master/CompositionExample/SwapChainRenderer.cs
swapChain.WaitForVerticalBlank();
オフスクリーンに書き込んで、CanvasBitmap を作成後
Bitmapへバッファコピーする。
var device = CanvasDevice.GetSharedDevice();
var offscreen = new CanvasRenderTarget
(
device,
ActualSize.X,
ActualSize.Y,
96
);
using var g = offscreen.CreateDrawingSession();
// 描画処理
g.Clear( DrawSet.SheetColor.Color );
// CanvasBitmap作成
var frame = CanvasBitmap.CreateFromBytes
(
g,
offscreen.GetPixelBytes( 0, 0, (int)offscreen.SizeInPixels.Width, (int)offscreen.SizeInPixels.Height ),
(int)offscreen.SizeInPixels.Width,
(int)offscreen.SizeInPixels.Height,
DirectXPixelFormat.R8G8B8A8UIntNormalized, // ココ
96,
CanvasAlphaMode.Premultiplied
);
var buffer = frame.GetPixelBytes();
// Bitmap作成
var bmp = new Bitmap
(
(int)frameSize.Size.Width,
(int)frameSize.Size.Height,
PixelFormat.Format32bppArgb // ココ
);
// CanvasBitmap のデータを Bitmap へコピー
var bmpData = bmp.LockBits
(
new( 0, 0, bmp.Width, bmp.Height ),
ImageLockMode.WriteOnly,
bmp.PixelFormat
);
Marshal.Copy( buffer, 0, bmpData.Scan0, buffer.Length );
bmp.UnlockBits( bmpData );
恐らく上記だけだと色がおかしくなるのではないかと思われる
根拠なしですが、RGBA → ARGB に上書きしているので
A=R, R=G, G=B, B=A の値が設定されている?