ctrl + alt + del 后重置 SharpDX 设备
Resetting SharpDX device after ctrl + alt + del
我正在使用 SharpDX 开发 3D 建模软件,其中元素是使用 Vertex- 和 IndexBuffers 绘制的。我是 3D 图形和 DirectX 的初学者,代码不是我写的,我正在尝试修改它。
但问题是:调试时按 Alt 键可以正常工作,但在锁定和解锁计算机或按 ctrl + alt + del 时,SharpDX 的状态。Direct3D9.Device 我正在使用对 "DeviceNotReset" 的更改。我现在正在尝试恢复设备以便继续渲染。
创建设备:
public ModelerControl(MainViewPresenter parent)
{
PresentParameters par = new PresentParameters();
par.Windowed = true;
par.SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard;
par.PresentationInterval = PresentInterval.One;
par.AutoDepthStencilFormat = SharpDX.Direct3D9.Format.D16;
par.EnableAutoDepthStencil = true;
par.BackBufferFormat = SharpDX.Direct3D9.Format.X8R8G8B8;
par.BackBufferHeight = this.ClientSize.Height;
par.BackBufferWidth = this.ClientSize.Width;
if (device == null)
{
device = new SharpDX.Direct3D9.Device(new Direct3D(), 0, DeviceType.Hardware, this.Handle, CreateFlags.SoftwareVertexProcessing, par);
SC = device.GetSwapChain(0);
}
else
{
SC = new SharpDX.Direct3D9.SwapChain(device, pp);
}
this.parentPresenter = parent;
InitializeComponent();
}
渲染并尝试重置设备:
public void Render()
{
lock (this)
{
ModelerProperties properties = ProjectModel.Instance.Project.ModelerPropertyList;
if (properties == null)
return;
if (!properties.IsPropertySenderInited)
{
properties.PropertyChanged += new PropertyChangedEventHandler(ModelerControl_PropertyChanged);
properties.IsPropertySenderInited = true;
}
int index = 0;
if (device == null)
return;
if (clock == null)
return;
if (SC.IsDisposed)
return;
if (this.IsDisposed)
return;
SharpDX.Result result = device.TestCooperativeLevel();
if(result == ResultCode.DeviceNotReset)
{
PresentParameters pp = new PresentParameters();
pp.Windowed = true;
pp.SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard;
pp.PresentationInterval = PresentInterval.One;
pp.AutoDepthStencilFormat = SharpDX.Direct3D9.Format.D16;
pp.EnableAutoDepthStencil = true;
pp.BackBufferFormat = SharpDX.Direct3D9.Format.X8R8G8B8;
pp.BackBufferHeight = this.ClientSize.Height;
pp.BackBufferWidth = this.ClientSize.Width;
try
{
device.Reset(pp);
}
catch { }
}
SharpDX.Direct3D9.Surface bb = SC.GetBackBuffer(0);
device.SetRenderTarget(0, bb);
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, properties.GetBackGroundColor(), 1.0f, 0);
device.BeginScene();
//Defining matrices
device.SetTransform(TransformState.World, ref mScale);
device.SetTransform(TransformState.View, ref mView);
device.SetTransform(TransformState.Projection, ref mProj);
device.SetRenderState(RenderState.PointSpriteEnable, true);
device.SetRenderState(RenderState.PointScaleA, 0f);
device.SetRenderState(RenderState.PointScaleB, 0f);
device.SetRenderState(RenderState.PointScaleC, 100f);
device.SetRenderState(RenderState.Lighting, true);
device.SetRenderState(RenderState.Ambient, System.Drawing.Color.White.ToArgb());
device.SetRenderState(RenderState.ZEnable, ZBufferType.UseZBuffer);
device.SetRenderState(RenderState.NormalizeNormals, true);
device.SetRenderState(RenderState.CullMode, Cull.Counterclockwise);
device.SetRenderState(RenderState.AlphaBlendEnable, true);
device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
//Drawing elements
device.EndScene();
try
{
SC.Present(Present.None, new SharpDX.Rectangle(), new SharpDX.Rectangle(), this.Handle);
}
catch { }
bb.Dispose();
}
}
在设备重置时添加断点时,按 ctrl + alt + delete 并继续,捕获到 SharpDXException 消息 HRESULT: [0x8876086C], Module: [SharpDX.Direct3D9], ApiCode: [D3DERR_INVALIDCALL/InvalidCall], Message: Unknown
做同样的事情,但在第 SC.Present(Present.None, new SharpDX.Rectangle(), new SharpDX.Rectangle(), this.Handle);
行,抛出 SharpDXException 并显示以下消息 HRESULT: [0x88760868], Module: [SharpDX.Direct3D9], ApiCode: [D3DERR_DEVICELOST/DeviceLost], Message: Unknown
我想我应该释放资源然后重置设备但是重置方法抛出异常。或者当 SC.Present()
处的异常表明设备丢失时是否应该重新创建设备?
我无法让设备的重置工作,而是我创建了一个新的 SharpDX.Device
与上面相同的 PresentParameters
。然后我重新初始化了图形,这似乎工作正常。可能不是最有效的方法,但在这种情况下有效。
我正在使用 SharpDX 开发 3D 建模软件,其中元素是使用 Vertex- 和 IndexBuffers 绘制的。我是 3D 图形和 DirectX 的初学者,代码不是我写的,我正在尝试修改它。 但问题是:调试时按 Alt 键可以正常工作,但在锁定和解锁计算机或按 ctrl + alt + del 时,SharpDX 的状态。Direct3D9.Device 我正在使用对 "DeviceNotReset" 的更改。我现在正在尝试恢复设备以便继续渲染。
创建设备:
public ModelerControl(MainViewPresenter parent)
{
PresentParameters par = new PresentParameters();
par.Windowed = true;
par.SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard;
par.PresentationInterval = PresentInterval.One;
par.AutoDepthStencilFormat = SharpDX.Direct3D9.Format.D16;
par.EnableAutoDepthStencil = true;
par.BackBufferFormat = SharpDX.Direct3D9.Format.X8R8G8B8;
par.BackBufferHeight = this.ClientSize.Height;
par.BackBufferWidth = this.ClientSize.Width;
if (device == null)
{
device = new SharpDX.Direct3D9.Device(new Direct3D(), 0, DeviceType.Hardware, this.Handle, CreateFlags.SoftwareVertexProcessing, par);
SC = device.GetSwapChain(0);
}
else
{
SC = new SharpDX.Direct3D9.SwapChain(device, pp);
}
this.parentPresenter = parent;
InitializeComponent();
}
渲染并尝试重置设备:
public void Render()
{
lock (this)
{
ModelerProperties properties = ProjectModel.Instance.Project.ModelerPropertyList;
if (properties == null)
return;
if (!properties.IsPropertySenderInited)
{
properties.PropertyChanged += new PropertyChangedEventHandler(ModelerControl_PropertyChanged);
properties.IsPropertySenderInited = true;
}
int index = 0;
if (device == null)
return;
if (clock == null)
return;
if (SC.IsDisposed)
return;
if (this.IsDisposed)
return;
SharpDX.Result result = device.TestCooperativeLevel();
if(result == ResultCode.DeviceNotReset)
{
PresentParameters pp = new PresentParameters();
pp.Windowed = true;
pp.SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard;
pp.PresentationInterval = PresentInterval.One;
pp.AutoDepthStencilFormat = SharpDX.Direct3D9.Format.D16;
pp.EnableAutoDepthStencil = true;
pp.BackBufferFormat = SharpDX.Direct3D9.Format.X8R8G8B8;
pp.BackBufferHeight = this.ClientSize.Height;
pp.BackBufferWidth = this.ClientSize.Width;
try
{
device.Reset(pp);
}
catch { }
}
SharpDX.Direct3D9.Surface bb = SC.GetBackBuffer(0);
device.SetRenderTarget(0, bb);
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, properties.GetBackGroundColor(), 1.0f, 0);
device.BeginScene();
//Defining matrices
device.SetTransform(TransformState.World, ref mScale);
device.SetTransform(TransformState.View, ref mView);
device.SetTransform(TransformState.Projection, ref mProj);
device.SetRenderState(RenderState.PointSpriteEnable, true);
device.SetRenderState(RenderState.PointScaleA, 0f);
device.SetRenderState(RenderState.PointScaleB, 0f);
device.SetRenderState(RenderState.PointScaleC, 100f);
device.SetRenderState(RenderState.Lighting, true);
device.SetRenderState(RenderState.Ambient, System.Drawing.Color.White.ToArgb());
device.SetRenderState(RenderState.ZEnable, ZBufferType.UseZBuffer);
device.SetRenderState(RenderState.NormalizeNormals, true);
device.SetRenderState(RenderState.CullMode, Cull.Counterclockwise);
device.SetRenderState(RenderState.AlphaBlendEnable, true);
device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
//Drawing elements
device.EndScene();
try
{
SC.Present(Present.None, new SharpDX.Rectangle(), new SharpDX.Rectangle(), this.Handle);
}
catch { }
bb.Dispose();
}
}
在设备重置时添加断点时,按 ctrl + alt + delete 并继续,捕获到 SharpDXException 消息 HRESULT: [0x8876086C], Module: [SharpDX.Direct3D9], ApiCode: [D3DERR_INVALIDCALL/InvalidCall], Message: Unknown
做同样的事情,但在第 SC.Present(Present.None, new SharpDX.Rectangle(), new SharpDX.Rectangle(), this.Handle);
行,抛出 SharpDXException 并显示以下消息 HRESULT: [0x88760868], Module: [SharpDX.Direct3D9], ApiCode: [D3DERR_DEVICELOST/DeviceLost], Message: Unknown
我想我应该释放资源然后重置设备但是重置方法抛出异常。或者当 SC.Present()
处的异常表明设备丢失时是否应该重新创建设备?
我无法让设备的重置工作,而是我创建了一个新的 SharpDX.Device
与上面相同的 PresentParameters
。然后我重新初始化了图形,这似乎工作正常。可能不是最有效的方法,但在这种情况下有效。