2013-09-06 4 views
2

Я пытаюсь реализовать обновление для backbuffer, как только изменится размер моего окна. Итак, мои объекты не будут растянуты. Так что я попробовал этотSharpDx windowResize

_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

ли я что-то отсутствует?

+0

Я читал много о том, как избавиться от backbuffer, поэтому я тоже это сделал «_backbuffer.Dispose()», но он не имеет эффекта – Rey

+0

Вы работаете [в режиме отладки] (http://sharpdx.org/forum/4- general/1774-how-to-debug-a-sharpdxexception), чтобы получить всю информацию, которую вы можете? – shoelzer

+0

Если вы имеете в виду, если я запустил его в Debug вместо Release, то да. – Rey

ответ

2

Вам не разрешается изменять размер подкачки, если какие-либо виды в зависимости от нее по-прежнему активны. Поэтому убедитесь, что вы вызываете release/распоряжение в RenderTargetView/ShaderResourceViews, созданные из вашего буфера, затем создайте новые, как только вызывается Resize.

Обратите внимание, что эти виды необходимо отделить от конвейера (так что если RenderTargetView, связанный с вашим SwapChain, все еще привязан, убедитесь, что вы отвязали его раньше), иначе dx11 runtime будет ждать их отсоединения перед удалением, поэтому вызов будет по-прежнему терпеть неудачу.

EDIT: Чтобы убедиться, что у вас есть все, что вам нужно, проще всего создать класс swapchain, в котором есть все необходимые данные (обратите внимание, что 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; 

    } 

И метод Resize:

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); 
    } 

Кроме того, как раз перед вызовом изменять размер, это хорошо, чтобы позвонить (в конечном итоге вы можете также сделать малая промывка):

device.ImmediateContext.ClearState(); 

Чтобы отключить все.

Обратите внимание, что если вы используете ресурсы, зависящие от размера, вам также необходимо уведомить ваше приложение (чтобы воссоздать такие элементы, как временный буфер визуализации рендеринга/глубины).

Итак, в этом случае вы можете либо добавить событие Resized в свой класс SwapChain (и прослушать его на вашем холсте). Я не большой поклонник этого лично, так как часто использую несколько SwapChains в одном приложении.

Другой простой способ, чтобы добавить метод:

ResizeResources(int widh,int height); 

В классе холст, и вызвать его на renderform размер событие.

+0

Итак, если я правильно понял, это не сработает. Я создаю backBuffer, depthBuffer, depthView и renderView в классе, называемом canvas.cs Я создаю там также renderForm и вызываю renderLoop. В моем классе context.cs, чье наследие от canvas.cs Я называю «context.ClearRenderTargetView» и «context.ClearDepthStencilView» Итак, когда я удаляю все те, что есть в Canvas, они все еще существуют в контексте, которые приводят к ошибке. Итак, я должен найти способ связать их так или иначе, чтобы они работали правильно? Дело в том, что это невозможно, поэтому я должен вставить их в вызовы на мой canvas.cs правильно? – Rey

+0

отредактировал ответ с небольшим количеством кода для объяснения. – catflier

+0

спасибо за это объяснение, но я не получаю значение этой композиции. Потому что они такие же, не так ли? ! [Сравнение] (http://abload.de/img/composition2ksfm.png) В вашем конструкторе SwapChain вы имели в виду 'Device.CreateWithSwapChain (DriverType.Hardware, DeviceCreationFlags.Debug, sd, out_device, out this.swapchain); вместо 'this.swapchain = new SwapChain (device.Factory, device.Device, sd);' right? – Rey

 Смежные вопросы

  • Нет связанных вопросов^_^