gpt4 book ai didi

c# - SharpDx 窗口调整大小

转载 作者:太空宇宙 更新时间:2023-11-03 10:58:12 25 4
gpt4 key购买 nike

我正在尝试在我的窗口大小更改后立即对后备缓冲区实现更新。所以我的对象不会被拉伸(stretch)。所以我试了一下

_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/InvalidCall

我错过了什么吗?

最佳答案

如果依赖交换链的任何 View 仍然处于事件状态,则不允许调整交换链的大小。因此,请确保在从后台缓冲区创建的 RenderTargetView/ShaderResourceView 上调用 release/dispose,然后在调用 Resize 后创建新的。

另请注意,这些 View 需要与管道分离(因此,如果与您的 SwapChain 关联的 RenderTargetView 仍处于绑定(bind)状态,请确保您之前已将其解除绑定(bind)),否则 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();

确保解除绑定(bind)。

请注意,如果您使用大小相关的资源,您还需要通知您的应用程序(以便重新创建临时渲染目标/深度缓冲区等元素)。

因此,在这种情况下,您可以将 Resized 事件添加到您的 SwapChain 类(并在您的 Canvas 上收听它)。我个人不太喜欢这个,因为我经常在同一个应用程序中使用多个交换链。

另一种简单的方法,是添加一个方法:

 ResizeResources(int widh,int height);

进入您的 Canvas 类,并在您的渲染表单调整大小事件中调用它。

关于c# - SharpDx 窗口调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18658508/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com