无法在 DirectX 11 中绘制三角形

Unable to draw a triangle in DirectX 11

我正在学习 DirectX 11 并尝试渲染三角形,但除了背景颜色外什么都没有显示。没有错误,没有警告。这是我的主文件:

while (true)
    {
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        if (msg.message == WM_QUIT)
        {
            break;
        }
        // Rendering here
        ID3D11Buffer* vertex_buffer;

        const float color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
        device_context->ClearRenderTargetView(render_target_view, color);

        Vertex vertices[]{
            { 0.0f, -0.5f},
            { 0.5f,  0.5f},
            {-0.5f, -0.5f}
        };

        D3D11_BUFFER_DESC vb_desc;
        ZeroMemory(&vb_desc, sizeof(vb_desc));
        vb_desc.ByteWidth = sizeof(vertices);
        vb_desc.Usage = D3D11_USAGE_DEFAULT;
        vb_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        vb_desc.CPUAccessFlags = 0;
        vb_desc.MiscFlags = 0;
        vb_desc.StructureByteStride = sizeof(Vertex);

        D3D11_SUBRESOURCE_DATA vb_data;
        ZeroMemory(&vb_data, sizeof(vb_data));
        vb_data.pSysMem = vertices;

        device->CreateBuffer(&vb_desc, &vb_data, &vertex_buffer);

        const UINT stride = sizeof(Vertex);
        const UINT offset = 0;

        device_context->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);

        ID3D11VertexShader *vertex_shader;
        ID3D11PixelShader* pixel_shader;
        ID3DBlob* result_blob;
        ID3DBlob* error_blob;
        D3DCompileFromFile(L"PixelShader.hlsl", NULL, NULL, "main", "ps_4_0", D3DCOMPILE_DEBUG, 0, &result_blob, &error_blob);
        device->CreatePixelShader(result_blob->GetBufferPointer(), result_blob->GetBufferSize(), nullptr, &pixel_shader);
        device_context->PSSetShader(pixel_shader, nullptr, 0);

        D3DCompileFromFile(L"VertexShader.hlsl", NULL, NULL, "main", "vs_4_0", D3DCOMPILE_DEBUG, 0, &result_blob, &error_blob);
        
        device->CreateVertexShader(result_blob->GetBufferPointer(), result_blob->GetBufferSize(), nullptr, &vertex_shader);

        device_context->VSSetShader(vertex_shader, nullptr, 0);

        ID3D11InputLayout *input_layout;

        D3D11_INPUT_ELEMENT_DESC element_desc[] =
        {
            {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
        };

        device->CreateInputLayout(element_desc, 1, result_blob->GetBufferPointer(), result_blob->GetBufferSize(), &input_layout);

        device_context->IASetInputLayout(input_layout);

        result_blob->Release();
        if (error_blob != nullptr) error_blob->Release();


        device_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        device_context->OMSetRenderTargets(1u, &render_target_view, nullptr);

        D3D11_VIEWPORT vp;
        vp.Width = 800;
        vp.Height = 600;
        vp.MinDepth = 0;
        vp.MaxDepth = 1;
        vp.TopLeftX = 0;
        vp.TopLeftY = 0;
        device_context->RSSetViewports(1u, &vp);


        device_context->Draw(3, 0);

        vertex_buffer->Release();
        vertex_shader->Release();
        pixel_shader->Release();
        input_layout->Release();

        swap_chain->Present(1u, 0u);

    }

    ////////////////////////////////////////////////////////////////////////////////

    device->Release();
    device_context->Release();
    swap_chain->Release();
    render_target_view->Release();

这是顶点着色器(名为VertexShader.hlsl):

float4 main(float2 pos : Position) : SV_Position
{
    return float4(pos.x, pos.y, 0.0f, 1.0f);
}

这里是像素着色器(名为 PixelShader.hlsl):

float4 main() : SV_Target
{
    return float4(0.0f, 1.0f, 0.0f, 1.0f);
}

感谢任何解决此问题的提示。 谢谢你的帮助。

编辑 感谢@IWonderWhatThisAPIDoes 帮助我解决了这个问题。解决方案是将顶点的坐标更改为

    Vertex vertices[]{
            { 0.0f, 0.5f},
            { 0.5f,-0.5f},
            {-0.5f, -0.5f}
        };

正如@IWonderWhatThisAPIDoes 指出的那样,您什么都看不到的主要原因是由于 back-face culling. This is because you are using the 'default' DirectX 11 "Rasterizer State object" which is as follows from Microsoft Docs:

导致的三角形 'winding order'
State Default Value
FillMode Solid
CullMode Back
FrontCounterClockwise FALSE
DepthBias 0
SlopeScaledDepthBias 0.0f
DepthBiasClamp 0.0f
DepthClipEnable TRUE
ScissorEnable FALSE
MultisampleEnable FALSE
AntialiasedLineEnable FALSE

您可以通过以下方式使三角形可见:

  1. 更改顶点使它们具有不同的缠绕顺序

  2. 您可以创建并设置一个新的 RasterizerState 对象,剔除模式为 D3D11_CULL_FRONTD3D11_CULL_NONE 而不是 D3D11_CULL_BACK

  3. 您可以创建并设置 FrontCounterClockwise 为 TRUE 而不是 FALSE 的新 RasterizerState 对象。

Your loop currently creates and destroys the buffers, shaders objects, input layout every frame. You should reuse them each frame instead.

You should take a look at the DirectX Tool Kit as well as directx-vs-templates.