当前位置 : 主页 > 网络安全 > 测试自动化 >

.net – 获取WPF Visual到DirectX纹理的快速代码(性能明智)

来源:互联网 收集:自由互联 发布时间:2021-06-22
嗯,问题很简单,我在 WPF Visual上渲染了一些东西.我想在DirectX纹理上得到它.目前,我使用以下代码完成工作. var bmp = new System.Windows.Media.Imaging.RenderTargetBitmap(bound.Width, bound.Height, 96, 96, Syst
嗯,问题很简单,我在 WPF Visual上渲染了一些东西.我想在DirectX纹理上得到它.目前,我使用以下代码完成工作.

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

但它有点慢,显而易见.你们能提出一些可能让它更快的东西吗?

[编辑]我试图使用CopyPixels()加载数据,但它抛出D3DXERR_INVALIDDATA异常.

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);
    }
}

[编辑]好的,所以这就是我设法做到的.

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();
是.您仍然可以使用RenderTargetBitmap.但是,您可以在RenderTargetBitmap上调用CopyPixels,然后将像素直接写入纹理,而不是将其编码为PNG并在Direct3D中读取.应该快得多!

// render the visual, just like you did
var bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default, null);
bmp.Render(visual);

// get the pixels
var pixels = new int[width * height];
bmp.CopyPixels(pixels, 4 * width, 0); // each line consists of 4*width bytes.

现在,根据您使用的确切API(SlimDX?还有其他?),您需要锁定纹理,并将像素数组中的数据写入纹理.

网友评论