-
Notifications
You must be signed in to change notification settings - Fork 0
/
XnaImageSource.cs
98 lines (86 loc) · 2.83 KB
/
XnaImageSource.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/// <summary>
/// A wrapper for a RenderTarget2D and WriteableBitmap
/// that handles taking the XNA rendering and moving it
/// into the WriteableBitmap which is consumed as the
/// ImageSource for an Image control.
/// </summary>
public class XnaImageSource : IDisposable
{
// the render target we draw to
private RenderTarget2D renderTarget;
// a WriteableBitmap we copy the pixels into for
// display into the Image
private WriteableBitmap writeableBitmap;
// a buffer array that gets the data from the render target
private byte[] buffer;
/// <summary>
/// Gets the render target used for this image source.
/// </summary>
public RenderTarget2D RenderTarget
{
get { return renderTarget; }
}
/// <summary>
/// Gets the underlying WriteableBitmap that can
/// be bound as an ImageSource.
/// </summary>
public WriteableBitmap WriteableBitmap
{
get { return writeableBitmap; }
}
/// <summary>
/// Creates a new XnaImageSource.
/// </summary>
/// <param name="graphics">The GraphicsDevice to use.</param>
/// <param name="width">The width of the image source.</param>
/// <param name="height">The height of the image source.</param>
public XnaImageSource(GraphicsDevice graphics, int width, int height)
{
// create the render target and buffer to hold the data
renderTarget = new RenderTarget2D(
graphics, width, height, false,
SurfaceFormat.Color,
DepthFormat.Depth24Stencil8);
buffer = new byte[width * height * 4];
writeableBitmap = new WriteableBitmap(
width, height, 96, 96,
PixelFormats.Bgra32, null);
}
~XnaImageSource()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
renderTarget.Dispose();
if (disposing)
GC.SuppressFinalize(this);
}
/// <summary>
/// Commits the render target data into our underlying bitmap source.
/// </summary>
public void Commit()
{
// get the data from the render target
renderTarget.GetData(buffer);
// because the only 32 bit pixel format for WPF is
// BGRA but XNA is all RGBA, we have to swap the R
// and B bytes for each pixel
for (int i = 0; i < buffer.Length - 2; i += 4)
{
byte r = buffer[i];
buffer[i] = buffer[i + 2];
buffer[i + 2] = r;
}
// write our pixels into the bitmap source
writeableBitmap.Lock();
Marshal.Copy(buffer, 0, writeableBitmap.BackBuffer, buffer.Length);
writeableBitmap.AddDirtyRect(
new Int32Rect(0, 0, renderTarget.Width, renderTarget.Height));
writeableBitmap.Unlock();
}
}