i just implemented Nick Gravelyn's Tutorial about integrating XNA in WPF (This One).
Which is not using an extra window rendered over the wpf dialog but renders off screen and copies the result in to a Image Control.
In principal it's working fine but it is very slow due to copying the frame buffer many times per frame.
Bottom line it's all about optimizing the following code lines.
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
unsafe
{
byte r;
int length = buffer.Length;
fixed (byte* p = buffer)
{
for (int i = 0; i < length; i += 4)
{
r = p;
p = p[i + 2];
p[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();//*/
}
I already replaced the color conversion with an unsafe version but the performance benefit was practically irrelevant.
I tried to replace the WriteableBitmap with a InteropBitmap but there was contrary to hints in the tutorial's comments no performance increase. (using InteropBitmap)
Last thing I was thinking of was to replace the renderTarget.GetData(buffer); call buy directly getting the pointer to the raw data. But here I stuck ...
Based on the following tutorial (xna mag) I was able to get the IDirect3DTexture9 via the following lines ...
public unsafe IntPtr GetRenderTargetPointer(RenderTarget2D renderTarget)
{
FieldInfo comPtr = renderTarget.GetType().GetField(
"pComPtr",
BindingFlags.NonPublic | BindingFlags.Instance
);
return new IntPtr(Pointer.Unbox(comPtr.GetValue(renderTarget)));
}
But how can I get now further? I'm not familiar with these interop and using external dll's stuff.
Next thing should be to get an IDirect3DSurface9 right?
Thanks for any help!