Search code examples
c++directxdirect3dvertexvertex-buffer

Direct3D multiple vertex buffers, non interleaved elements


I'm trying to create 2 vertex buffers, one that only stores positions and another that only stores colors. This is just an exercise from Frank Luna's book to become familiar with vertex description, layouts and buffer options. The problem is that I feel like I have made all the relevant changes and although I am getting the geometry to show, the color buffer is not working. To complete the exercise, instead of using the book's Vertex vertices[]={{...},{...},...} from the example code where each Vertex stores the position and the color, I am using XMFLOAT3 pos[]={x,y,z...} for positions and XMFLOAT4 colors[]={a,b,c,...}. I have modified the vertex description to make each element reference the correct input spot:

D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
    {
        {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
        {"COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
    };

I've also changed the vertex buffer on the device to expect two vertex buffers instead of just mBoxVB which previously was a resource based on Vertex vertices[]:

ID3D11Buffer* mBoxVB;
ID3D11Buffer* mBoxVBCol;
ID3D11Buffer* combined[2];
...
combined[0]=mBoxVB;
combined[1]=mBoxVBCol;
...
UINT stride[] = {sizeof(XMFLOAT3), sizeof(XMFLOAT4)};
UINT offset = 0;
md3dImmediateContext->IASetVertexBuffers(0, 2, combined, stride, &offset);

If of any help, this is the buffer creation code:

    D3D11_BUFFER_DESC vbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof(XMFLOAT3)*8;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    vbd.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = Shapes::boxEx1Pos;
    HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB));

    D3D11_BUFFER_DESC cbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof(XMFLOAT4)*8;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    vbd.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA cinitData;
    cinitData.pSysMem = Shapes::boxEx1Col;
    HR(md3dDevice->CreateBuffer(&vbd, &cinitData, &mBoxVBCol));

If I use combined[0]=mBoxVBCol, instead of combined[0]=mBoxVB I get a different shape so I know there is some data there but I'm not sure why the Color element is not getting sent through to the vertex shader, it seems to me that the second slot is being ignored in the operation.


Solution

  • I found the answer to the problem. It was simply that although I was specifying the stride array for both buffers, I was only giving one offset, so once I changed UINT offset=0; to UINT offset[]={0,0}; it worked.