锐化窗口调整大小
本文关键字:调整 窗口 锐化 | 更新日期: 2023-09-27 18:30:29
一旦我的窗口大小发生变化,我正在尝试对后台缓冲区进行更新。所以我的对象不会被划伤。所以我试了这个
_renderForm.Resize += OnRenderFormOnResize;
private void OnRenderFormOnResize(object sender, EventArgs args)
{
// Resize depth bufer ?
MessageBox.Show("Width: "+_renderForm.ClientSize.Width.ToString() +" | Height: "+ _renderForm.ClientSize.Height.ToString());
_swapChain.ResizeBuffers(_desc.BufferCount, _renderForm.ClientSize.Width, _renderForm.ClientSize.Height, Format.Unknown, SwapChainFlags.None);
DoResize();
}
一旦窗口大小更改,我就会收到此错误。
DXGI_ERROR_IVALID_CALL/无效呼叫
我错过了什么吗?
如果依赖于交换链的任何视图仍处于活动状态,则不允许调整交换链的大小。因此,请确保在从后台缓冲区创建的 RenderTargetView/ShaderResourceViews 上调用 release/dispose,然后在调用 Resize 后创建新的视图。
另请注意,这些视图需要从管道中分离(因此,如果与您的交换链关联的 RenderTargetView 仍然绑定,请确保在之前取消绑定它),othewise dx11 运行时将在释放之前等待它们被取消附加,因此调用仍然会失败。
编辑:为了确保您拥有所需的一切,最简单的方法是为自己构建一个交换链类,该类具有您需要的所有必要数据(请注意,在我的情况下,DX11Device 也只是简单地包装设备)。
public class DX11SwapChain : IDX11RenderTarget
{
private DX11Device device;
private IntPtr handle;
private SwapChain swapchain;
public RenderTargetView RenderView { get; protected set; }
public RenderTargetViewDescription RenderViewDesc { get; protected set; }
public Texture2DDescription TextureDesc { get; protected set; }
private Texture2D resource;
public IntPtr Handle { get { return this.handle; } }
}
下面是构造函数:
public DX11SwapChain(DX11Device device, IntPtr handle, Format format, SampleDescription sampledesc)
{
this.device = device;
this.handle = handle;
SwapChainDescription sd = new SwapChainDescription()
{
BufferCount = 1,
ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), format),
IsWindowed = true,
OutputHandle = handle,
SampleDescription = sampledesc,
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput | Usage.ShaderInput,
Flags = SwapChainFlags.None
};
this.swapchain = new SwapChain(device.Factory, device.Device, sd);
this.resource = Texture2D.FromSwapChain<Texture2D>(this.swapchain, 0);
this.TextureDesc = this.resource.Description;
this.RenderView = new RenderTargetView(device.Device, this.resource);
this.RenderViewDesc = this.RenderView.Description;
}
和调整大小方法:
public void Resize()
{
this.Resize(0, 0);
}
public void Resize(int w, int h)
{
if (this.RenderView != null) { this.RenderView.Dispose(); }
this.resource.Dispose();
this.swapchain.ResizeBuffers(1,w, h, SharpDX.DXGI.Format.Unknown, SwapChainFlags.AllowModeSwitch);
this.resource = Texture2D.FromSwapChain<Texture2D>(this.swapchain, 0);
this.TextureDesc = this.resource.Description;
this.RenderView = new RenderTargetView(device.Device, this.resource);
}
另外,在调用 resize 之前,最好调用(您最终也可以进行小刷新):
device.ImmediateContext.ClearState();
确保解绑所有内容。
请注意,如果使用与大小相关的资源,则还需要通知应用程序(以便重新创建临时渲染目标/深度缓冲区等元素)。
因此,在这种情况下,您可以将 Resize 事件添加到 SwapChain 类中(并在画布上收听它)。我个人不太喜欢这个,因为我经常在同一应用程序中使用多个交换链。
另一种简单的方法是添加一个方法:
ResizeResources(int widh,int height);
进入画布类,并在渲染窗体调整大小事件中调用它。