Direct3D 11 - Draw a triangle

I am initializing all Direct3D 11, but when I come to drawing some geometry, the geometry is not displayed.

I created Piping, Geometry and created a draw function to draw geometry. My main question is, can anyone help me understand why the Triangle is not drawn in the window?

void cSystem::Draw(UINT count)
{
    // draw stuff...    
    UINT stride = sizeof(Vertex);
    UINT offset = 0;
    p_D3D11DeviceContext->IASetVertexBuffers(0, 1, &p_VertextBuffer, &stride, &offset);

    p_D3D11DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    p_D3D11DeviceContext->Draw(3, 0);

    if (count == 0)
    {
        INFO(L"Draw() Complete");
    }   
}

void cSystem::InitGeometry() // initialise the geometry for the scene
{   
    Vertex vertices[] =
    {
        { D3DXVECTOR3(0.0f, 0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) },
        { D3DXVECTOR3(0.5f, -0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) },
        { D3DXVECTOR3(-0.5f, -0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) }
    };

    D3D11_BUFFER_DESC bdsc;
    ZeroMemory(&bdsc, sizeof(D3D11_BUFFER_DESC));
    bdsc.Usage = D3D11_USAGE_IMMUTABLE;
    bdsc.ByteWidth = sizeof(Vertex) * 3;
    bdsc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bdsc.CPUAccessFlags = 0;
    bdsc.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA vinitdata;
    ZeroMemory(&vinitdata, sizeof(D3D11_SUBRESOURCE_DATA));
    vinitdata.pSysMem = vertices;

    p_D3D11Device->CreateBuffer(&bdsc, &vinitdata, &p_VertextBuffer);   

    /*D3D11_MAPPED_SUBRESOURCE ms;
    p_D3D11DeviceContext->Map(p_VertextBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
    memcpy(ms.pData, vertices, sizeof(Vertex));
    p_D3D11DeviceContext->Unmap(p_VertextBuffer, NULL);*/

    INFO(L"InitGeometry() Complete");
}

void cSystem::InitPipeline(void)
{   
#if defined(DEBUG) || (_DEBUG)
    DWORD shaderflags = 0;
#endif
    //p_D3D11Device->GetFeatureLevel() == D3D_FEATURE_LEVEL_11_0;
    ID3D10Blob *VS_, *PS_ = NULL;
    D3DX11CompileFromFile(L"Shader.shader", 0, 0, "VS", "vs_5_0", 0, 0, 0, &VS_, 0, 0);
    D3DX11CompileFromFile(L"Shader.shader", 0, 0, "PS", "ps_5_0", 0, 0, 0, &PS_, 0, 0);

    p_D3D11Device->CreateVertexShader(VS_->GetBufferPointer(), VS_->GetBufferSize(), NULL, &p_VS);
    p_D3D11Device->CreatePixelShader(PS_->GetBufferPointer(), PS_->GetBufferSize(), NULL, &p_PS);

    p_D3D11DeviceContext->VSSetShader(p_VS, 0, 0);
    p_D3D11DeviceContext->PSSetShader(p_PS, 0, 0);

    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT NumElements = ARRAYSIZE(layout);

    p_D3D11Device->CreateInputLayout(layout, NumElements, VS_->GetBufferPointer(),
    VS_->GetBufferSize(), &p_InputLayout);

    p_D3D11DeviceContext->IASetInputLayout(p_InputLayout);

    VS_->Release();
    PS_->Release();

    INFO(L"InitPipeline() Complete");
}

void cSystem::D3D11RenderFrame_(void)
{
    // clear the back buffer
    p_D3D11DeviceContext->ClearRenderTargetView(p_D3D11RenderTargetView, m_BackBufferColour[0]);
    // clear the depth buffer
    p_D3D11DeviceContext->ClearDepthStencilView(p_D3D11DepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0.0f);  

    // draw 
    Draw(count++);

    // switch the back buffer and the front buffer
    p_D3D11SwapChain->Present(0, 0);
}

      

Shader (or .fx file)

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut VS(float4 position : POSITION, float4 color : COLOR)
{
    VOut output;

    output.position = position;
    output.color = color;

    return output;
}


float4 PS(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

      

Link to fig. the program is given here: http://i.imgur.com/JyNkPqQ.png

Calls are executed correctly while the program is running, but are not displayed. Just in case, my question is forgotten from above, why isn't the triangle displayed?

Hope someone can help .. :)

+3


source to share


3 answers


I'm not a DirectX11 guru (actually I just started recently), but it seems that even if your vertex shader is given D3DXVECTOR3

for a vertex position, you say that POSITION

is

An unsigned, 32-bit, 32-bit, normalized integer format that supports 8 bits per channel, including alpha.

in the input layout. Now this is confusing!



You must use DXGI_FORMAT_R32G32B32_FLOAT

.

Thanks for reading.

+2


source


This may not be exactly the answer, but hopefully it's helpful. Sometimes it can be hard to tell why something isn't drawing just by looking at the code. There can be several reasons, and sometimes they can be hidden.

Typically, when I run into this problem, I load a graphical debugger, such as the one included in Visual Studio, and I look at each piece of state sent to the GPU to figure out what went wrong. It can be difficult at first when you don't know exactly what each part of the state is doing and what should be. But in the end, you learn and take the guesswork out of figuring out what went wrong.

Another useful thing is to enable debug mode on ID3D11Device

. To do this, set the Flags

parameter D3D11CreateDevice

or D3D11CreateDeviceAndSwapChain

(whichever you are using) to D3D11_CREATE_DEVICE_DEBUG

. This will display warnings if something goes wrong.

Eventually you will want to know how to use the graphics debugger, but before you get to this point, I would suggest that you first try following the tutorial and then go back and modify it to your liking. For every major change you make, run your program to make sure it still works. When it doesn't, you know what went wrong.

To your problem. One of the problems I see is that you haven't specified your colored element in your input layout. You need to add this after the position element:



{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }

      

Otherwise, your shader doesn't know where to find the color in the vertex stream. Note that the position must also be DXGI_FORMAT_R32G32B32_FLOAT

as stated in Nard's answer. Without these two, CreateInputLayout

will return the I / O pool because it does not match the vertex shader input signature.

Also make sure you create a viewport.

Other problems can arise, but it can be difficult to tell without seeing every API call made.

0


source


Note that you haven't actually done any transformation in the vertex shader, in my experience, add three transformation matrices to the vertex shader to get the job done.

 cbuffer Transform
 {
     matrix mWorld;
     matrix mView;
     matrix mProjection;
 }

      

then in the vertex shader do this

output.position= mul(position, mWorld);
output.position= mul(output.position, mView);
output.position= mul(output.position, mProjection);

      

you need to create D3D11_BIND_CONSTANT_BUFFER buffer for it and use ID3D11DeviceContext::VSSetConstantBuffers

to bind it.

you can use #include <DirectXMath.h>

to manipulate the matrix, for example use XMMatrixTranslation

and XMMatrixRotation

to change mWorld, use XMMatrixLookAtLH

to change mView, use XMMatrixPerspective

to change mProjection.

after you get the cpu memory matrix, you need to use ID3D11DeviceContext::UpdateSubresource

to update the data in the gpu memory (the constant buffers you created). do not forget to do it XMMatrixTranspose

before transferring the matrix.

0


source







All Articles