Рендеринг на текстуру не выполняется после изменения размера

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

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

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

Изменить размер меньше Не изменен Увеличьте размер, достаточно 1 пикселя, чтобы изображение исчезло.

Код, который генерирует визуализацию:

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

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

1 ответ

Решение

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

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

В основном в классе 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();
    }

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

Другие вопросы по тегам