2016-10-27 2 views
2

В графическом приложении я представляю изображение текстуре, затем использую эту текстуру на 3d-модели.Render to texture failed после изменения размера

Моя проблема заключается в следующем: Когда приложение запускается, все нормально, но если я изменяю размер представления, где я делаю рендеринг, и я делаю его больше, текстура на 3d-модели исчезает (она не становится черной, i что все значения становятся 1). Уменьшение размера изображения не приводит к исчезновению текстуры, но отображается неправильно (не изменяется).

Вот некоторые пояснительные изображения:

Изменение размера меньше enter image description here Не изменен enter image description here Изменение размера больше, 1 пиксель больше достаточно, чтобы сделать изображение исчезнет. enter image description here

код, который генерирует RenderView это:

private void CreateRenderToTexture(Panel view) 
    { 
     Texture2DDescription t2d = new Texture2DDescription() 
     { 
      Height = view.Height, 
      Width = view.Width, 
      Format = Format.R32G32B32A32_Float, 
      BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget, //| BindFlags.UnorderedAccess, 
      CpuAccessFlags = CpuAccessFlags.None, 
      OptionFlags = ResourceOptionFlags.None, 
      SampleDescription = new SampleDescription(_multisample, 0), 
      MipLevels = 1, 
      Usage = ResourceUsage.Default, 
      ArraySize = 1, 
     }; 
     _svgTexture = new Texture2D(_device, t2d); 
     _svgRenderView = new RenderTargetView(_device, _svgTexture);   
    } 

private void RenderSVGToTexture() 
    {    
     _camera.SetDefaultProjection(); 
     UpdatePerFrameBuffers(); 
     _dc.OutputMerger.SetTargets(_depthStencil, _svgRenderView);//depth stencil has same dimension as all other buffers 
     _dc.ClearRenderTargetView(_svgRenderView, new Color4(1.0f, 1.0f, 1.0f)); 
     _dc.ClearDepthStencilView(_depthStencil, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); 

     Entity e; 
     if (RenderingManager.Scene.Entity2DExists("svgimage")) 
     { 
      RenderingManager.Scene.GetEntity2D("svgimage", out e); 
      e.Draw(_dc); 
     } 
     _swapChain.Present(0, PresentFlags.None); 
    } 

При рендеринге 3D сцены я называю эту функцию перед отображением модели:

private void SetTexture() 
    { 
     Entity e; 
     if (!RenderingManager.Scene.GetEntity3D("model3d", out e)) 
      return; 

     e.ShaderType = ResourceManager.ShaderType.MAIN_MODEL; 
     if (ResourceManager.SVGTexture == null) 
     { 
      e.ShaderType = ResourceManager.ShaderType.PNUVNOTEX; 
      return; 
     } 
     SamplerDescription a = new SamplerDescription(); 
     a.AddressU = TextureAddressMode.Wrap; 
     a.AddressV = TextureAddressMode.Wrap; 
     a.AddressW = TextureAddressMode.Wrap; 

     a.Filter = Filter.MinPointMagMipLinear; 

     SamplerState b = SamplerState.FromDescription(ResourceManager.Device, a); 

     ShaderResourceView svgTexResourceView = new ShaderResourceView(ResourceManager.Device, Texture2D.FromPointer(ResourceManager.SVGTexture.ComPointer)); 
     ResourceManager.Device.ImmediateContext.PixelShader.SetShaderResource(svgTexResourceView, 0);   

     ResourceManager.Device.ImmediateContext.PixelShader.SetSampler(b, 0); 
     b.Dispose(); 
     svgTexResourceView.Dispose(); 
    } 

Пиксельный шейдер:

Texture2D svg : register(t0); 
    Texture2D errorEstimate : register(t1); 
    SamplerState ss : register(s0); 

    float4 main(float4 position : SV_POSITION, float4 color : COLOR, float2 uv : UV) : SV_Target 
    { 
     return color * svg.Sample(ss, uv);// *errorEstimate.Sample(ss, uv); 
    } 

I dont un что я делаю неправильно, я надеюсь, что вы можете заставить меня увидеть ошибку, которую я делаю. Спасибо, и извините за плохой английский!

ответ

0

Как всегда (всегда), я делал очень тупую ошибку.

Я не вызывал правильную функцию изменения размера.

В основном в классе Renderer2D есть функция DoResize, которая выполняет изменение размера только 2d буферов, в то время как в абстрактном классе Renderer есть остальные размеры буферов. Ошибка в том, что в родительском классе я вызывал неправильную функцию изменения размера!

класс Родитель:

protected override void DoResize(uint width, uint height) 
    { 
     if (width == 0 || height == 0) 
      return; 
     base.DoResize(width, height); //Here i was calling base.Resize (which was deprecated after a change in the application architecture) 
     _camera.Width = width; 
     _camera.Height = height; 

     _svgTexture.Dispose(); 
     _svgRenderView.Dispose(); 

     CreateRenderToTexture(_viewReference); 
     ResizePending = false; 
    } 

Базовый класс

protected virtual void DoResize(uint width, uint height) 
    { 
     Width = width; 
     Height = height; 

     _viewport = new Viewport(0, 0, Width, Height); 

     _renderTarget.Dispose(); 

     if (_swapChain.ResizeBuffers(2, (int)width, (int)height, Format.Unknown, SwapChainFlags.AllowModeSwitch).IsFailure) 
      Console.WriteLine("An error occured while resizing buffers."); 
     using (var resource = Resource.FromSwapChain<Texture2D>(_swapChain, 0)) 
      _renderTarget = new RenderTargetView(_device, resource); 

     _depthStencil.Dispose(); 
     CreateDepthBuffer(); 
    } 

Может быть, код, который я могу быть полезен для тех, кто пытается сделать некоторые воздавать текстуры материала, так как я вижу, что всегда есть люди, которые не могут заставить его работать :)

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