首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SharpDx windowResize

SharpDx windowResize
EN

Stack Overflow用户
提问于 2013-09-06 13:01:51
回答 1查看 3.7K关注 0票数 2

一旦更改了窗口大小,我正在尝试实现对后台缓冲区的更新。这样我的东西就不会散乱了。所以我试了一下

代码语言:javascript
运行
复制
_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错误_IVALID调用/无效电话

我是不是遗漏了什么?

EN

回答 1

Stack Overflow用户

发布于 2013-09-10 07:42:30

如果依赖于交换链的任何视图仍然处于活动状态,则不允许调整交换链的大小。因此,确保在从后台缓冲区创建的RenderTargetView/ShaderResourceViews上调用Resize /dispose,然后在调用Resize之后创建新的。

还请注意,这些视图需要从管道中分离(因此,如果与您的RenderTargetView关联的SwapChain仍然是绑定的,请确保在此之前解除绑定),当然dx11运行时将等待它们在释放之前将其断开,因此调用仍然会失败。

编辑:为了确保您拥有所需的一切,最简单的方法是为自己构建一个swapchain类,该类拥有所需的所有必要数据(请注意,在我的例子中,DX11Device也只是简单地包装一个设备)。

代码语言:javascript
运行
复制
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; } }
}

下面是构造函数:

代码语言:javascript
运行
复制
    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;

    }

调整大小的方法:

代码语言:javascript
运行
复制
    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);
    }

另外,在调用调整大小之前,调用它是很好的(您最终也可以进行一个小的刷新):

代码语言:javascript
运行
复制
 device.ImmediateContext.ClearState();

确保解开所有的束缚。

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

因此,在这种情况下,您可以向SwapChain类添加一个调整大小的事件(并在画布上听它)。我个人不太喜欢这一点,因为我经常在同一个应用程序中使用多个SwapChains。

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

代码语言:javascript
运行
复制
 ResizeResources(int widh,int height);

到画布类中,并在您的呈现形式调整事件中调用它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18658508

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档