无法在Windows 10通用应用程序上使用SharpDX绘制基元(但仍能清除背景)

本文关键字:绘制 背景 清除 SharpDX Windows 10通 应用 程序上 应用程序 | 更新日期: 2023-09-27 17:59:09

对不起,我的英语不好。我正试图用SharpDX在Windows 10应用程序上编写一个非常简单的DirectX 11,它在窗口中间画一个三角形。问题是三角形没有显示,而我仍然可以更改背景颜色(使用ClearRenderTargetView)。我验证了渲染函数是定期调用的,我的三角形是正面(顺时针)。我尝试过的:

  • 禁用背面剔除
  • 设置静态宽度和高度
  • 尝试其他基本体(直线、三角形带)
  • 将顶点着色器输入从float3更改为float4,反之亦然

我发现这个帖子有非常相似的症状,但仍然不起作用!

我已经在GitHub上发布了我的代码:https://github.com/minhcly/UWP3DTest

这是我的初始化代码(我认为问题所在):

    D3D11.Device2 device;
    D3D11.DeviceContext deviceContext;
    DXGI.SwapChain2 swapChain;
    D3D11.Texture2D backBufferTexture;
    D3D11.RenderTargetView backBufferView;
    private void InitializeD3D()
    {
        using (D3D11.Device defaultDevice = new D3D11.Device(D3D.DriverType.Hardware, D3D11.DeviceCreationFlags.Debug))
            this.device = defaultDevice.QueryInterface<D3D11.Device2>();
        this.deviceContext = this.device.ImmediateContext2;
        DXGI.SwapChainDescription1 swapChainDescription = new DXGI.SwapChainDescription1()
        {
            AlphaMode = DXGI.AlphaMode.Ignore,
            BufferCount = 2,
            Format = DXGI.Format.R8G8B8A8_UNorm,
            Height = (int)(this.swapChainPanel.RenderSize.Height),
            Width = (int)(this.swapChainPanel.RenderSize.Width),
            SampleDescription = new DXGI.SampleDescription(1, 0),
            Scaling = SharpDX.DXGI.Scaling.Stretch,
            Stereo = false,
            SwapEffect = DXGI.SwapEffect.FlipSequential,
            Usage = DXGI.Usage.RenderTargetOutput
        };
        using (DXGI.Device3 dxgiDevice3 = this.device.QueryInterface<DXGI.Device3>())
        using (DXGI.Factory3 dxgiFactory3 = dxgiDevice3.Adapter.GetParent<DXGI.Factory3>())
        {
            DXGI.SwapChain1 swapChain1 = new DXGI.SwapChain1(dxgiFactory3, this.device, ref swapChainDescription);
            this.swapChain = swapChain1.QueryInterface<DXGI.SwapChain2>();
        }
        using (DXGI.ISwapChainPanelNative nativeObject = ComObject.As<DXGI.ISwapChainPanelNative>(this.swapChainPanel))
            nativeObject.SwapChain = this.swapChain;
        this.backBufferTexture = this.swapChain.GetBackBuffer<D3D11.Texture2D>(0);
        this.backBufferView = new D3D11.RenderTargetView(this.device, this.backBufferTexture);
        this.deviceContext.OutputMerger.SetRenderTargets(this.backBufferView);
        deviceContext.Rasterizer.State = new D3D11.RasterizerState(device, new D3D11.RasterizerStateDescription()
        {
            CullMode = D3D11.CullMode.None,
            FillMode = D3D11.FillMode.Solid,
            IsMultisampleEnabled = true
        });
        deviceContext.Rasterizer.SetViewport(0, 0, (int)swapChainPanel.Width, (int)swapChainPanel.Height);
        CompositionTarget.Rendering += CompositionTarget_Rendering;
        Application.Current.Suspending += Current_Suspending;
        isDXInitialized = true;
    }

InitScene()函数:

    D3D11.Buffer triangleVertBuffer;
    D3D11.VertexShader vs;
    D3D11.PixelShader ps;
    D3D11.InputLayout vertLayout;
    RawVector3[] verts;
    private void InitScene()
    {
        D3D11.InputElement[] inputElements = new D3D11.InputElement[]
        {
            new D3D11.InputElement("POSITION", 0, DXGI.Format.R32G32B32_Float, 0)
        };
        using (CompilationResult vsResult = ShaderBytecode.CompileFromFile("vs.hlsl", "main", "vs_4_0"))
        {
            vs = new D3D11.VertexShader(device, vsResult.Bytecode.Data);
            vertLayout = new D3D11.InputLayout(device, vsResult.Bytecode, inputElements);
        }
        using (CompilationResult psResult = ShaderBytecode.CompileFromFile("ps.hlsl", "main", "ps_4_0"))
            ps = new D3D11.PixelShader(device, psResult.Bytecode.Data);
        deviceContext.VertexShader.Set(vs);
        deviceContext.PixelShader.Set(ps);
        verts = new RawVector3[] {
            new RawVector3( 0.0f, 0.5f, 0.5f ),
            new RawVector3( 0.5f, -0.5f, 0.5f ),
            new RawVector3( -0.5f, -0.5f, 0.5f )
        };
        triangleVertBuffer = D3D11.Buffer.Create(device, D3D11.BindFlags.VertexBuffer, verts);
        deviceContext.InputAssembler.InputLayout = vertLayout;
        deviceContext.InputAssembler.PrimitiveTopology = D3D.PrimitiveTopology.TriangleList;
    }

渲染功能:

    private void RenderScene()
    {
        this.deviceContext.ClearRenderTargetView(this.backBufferView, new RawColor4(red, green, blue, 0));
        deviceContext.InputAssembler.SetVertexBuffers(0,
            new D3D11.VertexBufferBinding(triangleVertBuffer, Utilities.SizeOf<RawVector3>(), 0));
        deviceContext.Draw(verts.Length, 0);
        this.swapChain.Present(0, DXGI.PresentFlags.None);
    }

谢谢你的帮助。

无法在Windows 10通用应用程序上使用SharpDX绘制基元(但仍能清除背景)

我已经解决了这个问题。我在Visual Studio中使用了图形调试器,并检测到OutputMerger没有RenderTarget。所以我移动

this.deviceContext.OutputMerger.SetRenderTargets(this.backBufferView);

到RenderScene()函数,它就可以工作了。然而,我不明白为什么我必须在每一帧都重置这个。我是Direct3D的新手,所以如果有人有问题,请评论。非常感谢。

p/s:我已经在GitHub上为任何遇到同样问题的人提交了工作项目。