I did not expect
RenderTargetBitmap.Render(visual)
to have any side effects excerpt changing the bitmap data itself. It looks like it is not true. I am unable to repeat it more than 60 times before some ugly rendering artifacts start to happen.
How to properly render a lot of sprites in WPF? Below is the code to reproduce the problem.
I generate sprites this way:
BitmapSource Sprite()
{
var bitmap = new RenderTargetBitmap(
500, 500,
96, 96,
PixelFormats.Default);
var visual = new DrawingVisual();
var rect = new Rect(
new Size(
bitmap.Width,
bitmap.Height));
using (DrawingContext context = visual.RenderOpen())
context.DrawLine(
new Pen(Brushes.Red, 100),
rect.TopLeft,
rect.BottomRight);
bitmap.Render(visual);
bitmap.Freeze();
return bitmap;
}
Here is the canvas to render many of them:
public BitmapSource Canvas
{
get
{
var bitmap = new RenderTargetBitmap(
1980, 1080,
96, 96,
PixelFormats.Default);
var tiles = 70;
for (int i = 0; i < tiles; i++)
{
var visual = new DrawingVisual();
var rect = new Rect(
bitmap.Width / tiles * i,
0,
bitmap.Width / tiles,
bitmap.Height);
using (DrawingContext context = visual.RenderOpen())
context.DrawImage(Sprite(), rect);
bitmap.Render(visual);
}
bitmap.Freeze();
return bitmap;
}
}
I can see this strange picture while being data bound to Canvas property ...
for
loop into theusing (DrawingContext ...)
block. You could also save the "inner" RenderTargetBitmaps completely by drawing lines directly to the "outer" DrawingContext. – Hypermetertiles = 2000
. 2) I can reproduce the out-of-memory exception when keeping all references to sprites in a single Visual -- but at around 855 tiles rather than 70. What kind of graphics hardware are you using? – Beebreadtiles = 10000
either. – Beebread