3

I have initialise all of Direct3D 11 but when i come to draw some geometry the geometry doesn't show.

I have created the Pipeline, the Geometry and created a draw function for the geometry to be drawn. My main question is can anyone help me understand why the Triangle isn't 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);
}

The shader (or .fx file) is

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;
}

A link to a pic of the program is here : http://i.imgur.com/JyNkPqQ.png

The calls are made correctly in the execution of the program, but no display.. Just in case my question is forgotten from the top, why isn't the triangle displaying?

i hope someone can help.. :)

Abby Turner
  • 31
  • 1
  • 4
  • Note that all versions of D3DX are deprecated. I would suggest you avoid using the legacy D3DXMath library and use [DirectXMath](http://blogs.msdn.com/b/chuckw/archive/2012/03/27/introducing-directxmath.aspx) instead. You don't need to use D3DX11 to compile your shader, as you can use [D3DCompile](http://blogs.msdn.com/b/chuckw/archive/2012/05/07/hlsl-fxc-and-d3dcompile.aspx) directly. You may want to review this [Direct3D 11 tutorial](https://code.msdn.microsoft.com/Direct3D-Tutorial-Win32-829979ef) as well. – Chuck Walbourn Oct 23 '14 at 19:35

3 Answers3

2

I'm no guru in DirectX11 (in fact I've just started recently) but it seems that even though your vertex shader will be given a D3DXVECTOR3 for the position of the vertex, you're telling it that POSITION is

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

in your input layout. Now that's confusing!

You should use DXGI_FORMAT_R32G32B32_FLOAT.

Thank you for reading.

Nard
  • 1,006
  • 7
  • 8
  • Thank you for replaying, i changed the format to DXGI_FORMAT_R32G32B32_FLOAT. But still nothing, however thank you and i will keep at it until i achieve success. – Abby Turner Oct 19 '14 at 16:58
  • No problem. It is difficult to debug when you're programming graphics because all you know is that it looks wrong, so you have to be extra sure of what you're doing (such as data types and the rendering pipeline). – Nard Oct 19 '14 at 17:02
  • I will admit i didn't exactly follow the tutorial i was reading and kinda of did things my way. I figure best practice would be to stick to the book to the letter. And yes gfx programming is hard, i still cannot get a list of display modes associated with the Output devices either. Ill get there tho. :) – Abby Turner Oct 19 '14 at 17:08
  • Don't worry about it. Everyone has their preferred way of learning. I enjoy messing around with stuff too. :D – Nard Oct 19 '14 at 17:11
0

This might not exactly be the answer, but hopefully it is helpful. It is sometimes difficult to tell why something isn't drawing just from looking at the code. There could be multiple reasons why, and sometimes they might be kind of hidden.

Generally, when I encounter this problem, I load up a graphics debugger like the one included in Visual Studio, and I look at every piece of state sent to the GPU to figure out what went wrong. This may be difficult at first, however, when you don't know exactly what each piece of state does and what it should be. But, eventually you learn and it takes the guesswork out figuring out what went wrong.

Another thing that is usually helpful is to enable debug mode on your ID3D11Device. To do this set the Flags parameter of D3D11CreateDevice or D3D11CreateDeviceAndSwapChain (whichever you are using) to D3D11_CREATE_DEVICE_DEBUG. This will output warnings if something is going wrong.

Eventually you'll want to learn how to use the graphics debugger, but before you get to that point, I would recommend trying to follow the tutorial exactly at first, and then go back and change it more to your liking. With each significant 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 issue I see is that you haven't declared your color element in your input layout. You'll need to add this after your 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 your vertex stream. Note that position must also be DXGI_FORMAT_R32G32B32_FLOAT as mentioned in Nard's answer. Without these two things, CreateInputLayout will return a null input layout because it doesn't match the input signature of the vertex shader.

Also be sure that you are setting up a viewport.

There may be other issues, but it can be hard to tell without seeing every API call made.

megadan
  • 1,823
  • 12
  • 18
  • Thanks, i have used the debug macro's but i dont see enough in the output window.. the graphics debugger do you mean dxdiag? or is there something else i can use as im baffled lol – Abby Turner Oct 26 '14 at 05:51
  • Did you try adding the color element to the input layout like I mentioned and setting the viewport? The graphics debugger is a feature in Visual Studio under Debug->Graphics->Start Diagnostics. It lets you capture a frame and then analyze the D3D state. It's in the Pro version, but I'm not sure if it's in the free Express version. – megadan Oct 27 '14 at 04:23
  • Yes i added it, i also followed the tutorial to the exact letter. Its a mystery.. I set the D3D11_APPEND_ALIGNED_ELEMENT, it was already set debug and i downloaded the free trial for the graphics debugger but still no luck with any of it. Tomorrow i will pull out all the geometry data and the pipeline restart and hope for the best, as i have really put a lot in to this little project. – Abby Turner Oct 28 '14 at 03:44
  • Sorry, I realized I made a typo in my code snippet. The format for the "COLOR" entry should be `DXGI_FORMAT_R32G32B32A32_FLOAT` because you have 4 floating point entries for color. I updated my answer. Also make sure you have "POSITION" set to `DXGI_FORMAT_R32G32B32_FLOAT` as mentioned in Nard's answer. If those don't fix your issue, what values did you use when creating your viewport? – megadan Oct 28 '14 at 05:08
0

Notice that you didn't actually do any transform in vertex shader, according to my experience, add three transform matrix to the vertex shader should do the job.

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

then in 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 a D3D11_BIND_CONSTANT_BUFFER buffer for it, and use ID3D11DeviceContext::VSSetConstantBuffers to bind it.

you can use #include <DirectXMath.h> to control 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 matrix at cpu memory, you need use ID3D11DeviceContext::UpdateSubresource to update the data to gpu memory (the constant buffers that you created above). remember to do XMMatrixTranspose before you pass the matrix.

Clones1201
  • 333
  • 3
  • 17