3
votes

I am reading the book, "Practical Rendering and Computation with Direct3D 11" and looking at the DirectX 11 Sample:

CPP: https://github.com/walbourn/directx-sdk-samples/blob/master/Direct3D11Tutorials/Tutorial02/Tutorial02.cpp

HLSL: https://github.com/walbourn/directx-sdk-samples/blob/master/Direct3D11Tutorials/Tutorial02/Tutorial02.fx

What is this?

D3D11_INPUT_ELEMENT_DESC layout[] =
 {
  { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 };

More importantly the Shader -- Where in the program does it set this "Pos"?

float4 VS( float4 Pos : POSITION ) : SV_POSITION
{
    return Pos;
}

I can only see that you are binding the vertex data via:

// Create vertex buffer
SimpleVertex vertices[] =
{
    XMFLOAT3( 0.0f, 0.5f, 0.5f ),
    XMFLOAT3( 0.5f, -0.5f, 0.5f ),
    XMFLOAT3( -0.5f, -0.5f, 0.5f ),
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 3;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) )
    return hr;

// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

And then you are setting the shaders and then drawing the 3 verticies:

// Render a triangle
g_pImmediateContext->VSSetShader( g_pVertexShader, nullptr, 0 );
g_pImmediateContext->PSSetShader( g_pPixelShader, nullptr, 0 );
g_pImmediateContext->Draw( 3, 0 );

This all makes sense. But I am confused on what this Pos input is, how it is generated, and why is it used? Also, there are other examples that do the same thing ... (sample 7) where they used postion and textures, but I can not see where this information is coming from. For example...

struct VS_INPUT
{
  float4 Pos : POSITION;
  float2 Tex : TEXCOORD0;
};

Thank you for your time!

1
In this context, POSITION is vertex position in object spaceAsesh

1 Answers

1
votes

The array of D3D11_INPUT_ELEMENT_DESC determines the layout of data that will be read from a vertex buffer. This array is passed to a ID3D11Device::CreateInputLayout call so that it can be used. It is then set on the rendering context via a call ID3D11DeviceContext::IASetInputLayout (not shown, but in the code you linked).

If you look at the members of D3D11_INPUT_ELEMENT_DESC, the first member is SemanticName (set to "POSITION"), which is how elements of the vertex buffer are matched to inputs in the shader. It also contains data about the offset of the data and the format (in this case, the offset is zero, and the format DXGI_FORMAT_R32G32B32_FLOAT corresponds to 3x 32bit floats). You'll notice that in the shader, after Pos, there's a colon, followed by "POSITION" - this is the semantic, and is matched to the input layout. The shader then knows that it should read the position data from offset zero, and the format of that data.

The data itself is read from the vertex buffer, set with the ID3D11DeviceContext::IASetVertexBuffers call. The stride parameters tells the input assembler the distance in the vertex buffer from one vertex to the next, so it knows where to start reading the next one. The g_pVertexBuffer passed in was initialized from the vertices data, which as you can see is a set of 3x 32-bit floats.

For shaders with additional inputs (eg. TEXCOORD0), there will be more entries in the D3D11_INPUT_ELEMENT_DESC array, corresponding to the semantics used in the shaders.