.net - 获取 WPF 视觉到 DirectX 纹理的快速代码(性能方面)

标签 .net wpf managed-directx

好吧,问题很简单,我在 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 .但不是将其编码为 PNG 并在 Direct3D 中读取,您可以调用 CopyPixels在您的 RenderTargetBitmap然后将像素直接写入您的纹理。应该会快很多!

// 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?其他什么?),您需要锁定纹理,并将数据写入 pixels数组到纹理。

关于.net - 获取 WPF 视觉到 DirectX 纹理的快速代码(性能方面),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5767252/

相关文章:

c# - 如何在 app.xaml [C#] 中全局设置文本框的属性

c# - DirectX9 中的简单 HLSL 发光/模糊效果

c# - 将表示为字符串的英国时间(BST 和 GMT)转​​换为 UTC(在 C# 中)

.net - 为什么 ReadOnlyCollection<T> 不是 ReadOnlyList<T>?

c# - OpenFileDialog 继续显示 .lnk 文件 WPF

c# - 我应该如何将托管的 DirectX 程序迁移到 Windows 7?

c# - 在 Google Drive API 中使用服务帐户下载文件时出现未经授权的响应

c# - 如何在 C# 中获取对象的子对象?

c# - xmldataprovider 在后面的代码中使用元素值