【问题标题】:Render to texture fails after resize调整大小后渲染到纹理失败
【发布时间】:2016-10-27 14:28:21
【问题描述】:

在图形应用程序中,我将图像渲染为纹理,然后在 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);
    }

我不明白我做错了什么,我希望你能让我看到我做错了什么。谢谢,抱歉英语不好!

【问题讨论】:

    标签: c# winforms slimdx


    【解决方案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();
        }
    

    也许我发布的代码对尝试渲染纹理的人有帮助,因为我发现总有人无法让它工作:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      相关资源
      最近更新 更多