我已经开始在WPF应用程序中使用DirectX了。我的第一步是使用简单的库: SharpdDX.WPF。基于样本,我实现了WPF控制绘制简单线。 SharpDX.WPF使用D3DImage在WPF中渲染图像。 不幸的是,应用程序的内存一直在增加。
我实现了类TestControlRenderer:D3D10。 顶点着色器初始化为:
var sizeInBytes = dataLength * sizeof(int) * 3;
var bufferDescription = new BufferDescription(
sizeInBytes,
ResourceUsage.Dynamic,
BindFlags.VertexBuffer,
CpuAccessFlags.Write,
ResourceOptionFlags.None);
using (var stream = new DataStream(sizeInBytes, true, true))
{
stream.Position = 0;
_graphDataVertexBuffer = new SharpDX.Direct3D10.Buffer(Device, stream, bufferDescription);
}
Device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(_graphDataVertexBuffer, sizeof(int) * 3, 0));
Device.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;
然后使用着色器中使用参数的常量缓冲区:
_controlInfoConstantBuffer = new ConstantBuffer<ControlParamsShaderData>(Device);
Device.VertexShader.SetConstantBuffer(0, _controlInfoConstantBuffer.Buffer);
初始化动画重置方法被覆盖:
base.Reset(args);
if (args.RenderSize.Width == 0) return;
_drawArgs = args;
InitVertexBuffer(dataLength);
_controlInfoConstantBuffer.Value = new ControlParamsShaderData
{
SamplesInControl = dataLength,
MinSignalDataY = -1500,
MaxSignalDataY = 1500
};
Device.VertexShader.SetConstantBuffer(0, _controlInfoConstantBuffer.Buffer);
最后一步是RenderScene方法:
public override void RenderScene(DrawEventArgs args)
{
if (args.RenderSize.Width == 0) return;
Device.ClearRenderTargetView(RenderTargetView, Color.Transparent);
using (var stream = _graphDataVertexBuffer.Map(MapMode.WriteDiscard, SharpDX.Direct3D10.MapFlags.None))
{
for (int i = 0; i < Data.Length; i++)
{
stream.Write(new Vector3(i, Data[i], 0));
}
}
_graphDataVertexBuffer.Unmap();
Device.Draw(Data.Length, 0);
}
渲染由DispatcherTimer控制,其中OnTickMethod使用点坐标更新数组,然后调用Render()方法。
我的问题很简单,就是每次渲染迭代都会产生内存泄漏或其他内容? 我不会更改后备缓冲区或创建其他对象。仅更改数据阵列,将其更新为GPU,然后着色器处理它以显示。 我的情况是在一个屏幕上显示大约30个wpf控件宽度DirectX。控件具有简单但实时的动画。那可能吗?
答案 0 :(得分:2)
您很可能是在泄漏资源。您可以通过设置静态配置属性
来查看SharpDX.Configuration.EnableObjectTracking = true;
然后调用
SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()
在您的应用程序生命周期的各个点,看看是否有任何泄漏(至少在SharpDX方面)。您可以编辑代码以确保处置这些对象。仅在调试时启用对象跟踪 - 这会影响性能。
SharpDX用于在终结器运行时释放COM对象,如果对象尚未被放置(至少在版本2.4.2中),但后来禁用了(他们详细说明了为什么在他们的一个更改日志中,我忘了哪一个)。
此外,DirectX requires that you release objects in the reverse order they were created - 这可能会造成难以调试的内存泄漏。所以当你的代码是
时var device = new Devie(...);
var effect = new Effec(Device, byteCode);
technique = effect.GetTechniqueByName(techniqueName);
inputLayout = new InputLayout(Device, _technique.GetPassByIndex(0).Description.Signature, ...);
然后你的处理代码必须是
_inputLayout.Dispose();
_technique.Dispose();
_effect.Dispose();
_device.Dispose();