Search code examples
c#winformsslimdx

Render to texture fails after resize


In a graphic application i am rendering an image to a texture, then i use that texture on a 3d model.

My problem is the following: When the application starts everything is fine, but if i resize the view where i do the rendering and i make it bigger, the texture on the 3d model disappear (it doesnt turn black, i think that all values become 1). Making the image smaller doesnt make the texture to disappear, but it is shown incorrectly (not resized).

Here are some explanatory images:

Resize smaller enter image description here Not resized enter image description here Resize bigger, 1 pixel bigger is enough to make image disappear. enter image description here

The code that generate the renderview is this:

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

When rendering the 3D scene i call this function before rendering the model:

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

Pixel shader:

    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 understand what i am doing wrong, i hope that you can make me see the mistake that i am doing. Thank you, and sorry for the bad english!


Solution

  • As it (almost) always turn out i was making a very stupid mistake.

    I wasn't calling the correct resize function.

    Basically in the Renderer2D class there is a DoResize function that does the resize of the 2d only buffers, while in the abstract Renderer class there is the rest of the buffers resizing. The mistake is that in the parent class i was calling the wrong base resize function!

    Parent class:

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

    Base class

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

    Maybe the code i posted can be of help for someone who is trying to do some render to texture stuff, since i see that there is always people that can't make it work :)