Well, the problem is simple, I have something rendered on a WPF Visual. I want to get it to on a DirectX Texture. At present, I using the following code to get the job done.
var bmp = new System.Windows.Media.Imaging.RenderTargetBitmap(bound.Width, bound.Height, 96, 96, System.Windows.Media.PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bmp));
Texture texture = new Texture(dxDevice, bound.Width, bound.Height, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
ms.Seek(0, SeekOrigin.Begin);
Surface privateSurface = texture.GetSurfaceLevel(0);
SurfaceLoader.FromStream(privateSurface, ms, Filter.None, Color.MediumAquamarine.ToArgb());
ms.Close();
}
return texture; // our prepared texture
But it's somewhat slow, in an obvious manner. Can you guys suggest something which could possibly make it quicker?
[EDIT] I tried to load the data using CopyPixels(), but it throws D3DXERR_INVALIDDATA exception.
RenderTargetBitmap bmp = GetBitmap();
// copy into a byte array
int stride = bmp.PixelWidth * 4;
byte[] data = new byte[bmp.PixelHeight * stride];
bmp.CopyPixels(data, stride, 0);
// create texture
using (MemoryStream ms = new MemoryStream(data))
{
ms.Seek(0, SeekOrigin.Begin);
if (dxDevice != null)
{
// next line throws D3DXERR_INVALIDDATA exception
texture = TextureLoader.FromStream(dxDevice, ms);
}
}
[EDIT] Ok, so here's how I managed to do it.
RenderTargetBitmap bmp = GetBitmap();
// copy into a byte array
int stride = bmp.PixelWidth * 4;
byte[] data = new byte[bmp.PixelHeight * stride];
bmp.CopyPixels(data, stride, 0);
// create texture
Texture texture = new Texture(dxDevice, bound.Width, bound.Height, 1, Usage.SoftwareProcessing, Format.A8R8G8B8, Pool.Managed);
Surface privateSurface = texture.GetSurfaceLevel(0);
var graphicsStream = privateSurface.LockRectangle(LockFlags.None);
graphicsStream.Write(data);
privateSurface.UnlockRectangle();