简体   繁体   中英

Unable to draw a triangle in DirectX 11

I am learning DirectX 11 and trying to render a triangle, but nothing show up except the background color. There is no errors, no warnings. Here is my main file:

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

This is the vertex shader(named VertexShader.hlsl):

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

And here is the pixel shader(named PixelShader.hlsl):

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

I appreciate any hint to solve this. Thank you for helping.

EDIT Thanks @IWonderWhatThisAPIDoes for helping me with this problem. The solution is changing the coordinate of the vertices to

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

As @IWonderWhatThisAPIDoes noted, the primary reason you see nothing is the 'winding order' of the triangles due to back-face culling . This is because you are using the 'default' DirectX 11 "Rasterizer State object" which is as follows from Microsoft Docs :

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

You can make your triangle visible by:

  1. Changing the vertices so they have a different winding-order

  2. You can create and set a new RasterizerState object with a cull mode of D3D11_CULL_FRONT or D3D11_CULL_NONE instead of D3D11_CULL_BACK .

  3. You can create and set a new RasterizerState object with a FrontCounterClockwise of TRUE instead of FALSE.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM