So here is the premise:
I have 2 vertex buffers buffers whose data and corresponding definition is as follows:
Vertex 1: This one contains the per instance data
// Somewhere defined in the header
std::vector<XMMATRIX> instancedMeshTransformMatrixArray;
...// Following code is in a function called loading data
// We will compute and setup the buffer with the information of the indexed mesh here
static float angle = 0.0f;
//angle += 90.0f * deltaTime;
XMVECTOR rotationAxis = XMVectorSet(0, 1, 1, 0);
g_WorldMatrix = XMMatrixIdentity();
XMMATRIX scale = XMMatrixScaling(1.0f, 1.0f, 1.0f);
XMMATRIX rotate = XMMatrixRotationAxis(rotationAxis, XMConvertToRadians(angle));
XMMATRIX translate = XMMatrixTranslation(0.8, 0.0f, 0.0f);
g_WorldMatrix *= translate * rotate * scale;
// We will also fill/process the matrix buffer here that will be used to index into to rendered indexed mesh
instancedMeshTransformMatrixArray.push_back(g_WorldMatrix);
// create and initialize the instanced data buffer
D3D11_BUFFER_DESC vertexInstancedBufferDesc = {};
vertexInstancedBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexInstancedBufferDesc.ByteWidth = sizeof(XMMATRIX) * instancedMeshTransformMatrixArray.size();
vertexInstancedBufferDesc.CPUAccessFlags = 0;
vertexInstancedBufferDesc.Usage = D3D11_USAGE_DEFAULT;
D3D11_SUBRESOURCE_DATA resourceData = {};
//ZeroMemory(&resourceData, sizeof(D3D11_SUBRESOURCE_DATA));
resourceData.pSysMem = &instancedMeshTransformMatrixArray[0];
HRESULT hr = g_d3dDevice->CreateBuffer(&vertexInstancedBufferDesc, &resourceData, &g_d3dIndexedVertexBuffer);
if (FAILED(hr))
{
return false;
}
Vertex 2: This contains the per model data
// Somewhere in the header
// Vertex data for a colored cube.
struct VertexPosColor
{
XMFLOAT3 Position;
XMFLOAT3 Color;
};
VertexPosColor g_Vertices[8] =
{
{ XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f) }, // 0
{ XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f) }, // 1
{ XMFLOAT3(0.5f, 0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f) }, // 2
{ XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f) }, // 3
{ XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f) }, // 4
{ XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f) }, // 5
{ XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f) }, // 6
{ XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f) } // 7
};
...//Following code is in a function called loading data
//It is followed by the loading of data for Vertex 1
// Create and initialize the vertex buffer.
D3D11_BUFFER_DESC vertexBufferDesc = {};
//ZeroMemory(&vertexBufferDesc, sizeof(D3D11_BUFFER_DESC));
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.ByteWidth = sizeof(VertexPosColor) * _countof(g_Vertices);
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
resourceData.pSysMem = g_Vertices;
hr = g_d3dDevice->CreateBuffer(&vertexBufferDesc, &resourceData, &g_d3dVertexBuffer);
if (FAILED(hr))
{
return false;
}
I also load data for the index buffer and constant buffer. I have tested it with the VS Graphics debugger and the data seems to have loaded correctly. However, I can provide how I do that as well if needed.
Following is how is create the Input Desc for the 2 buffers:
// Create the input layout for the vertex shader.
D3D11_INPUT_ELEMENT_DESC vertexLayoutDesc[] = {
// Per vertex data
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(VertexPosColor,Position), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(VertexPosColor,Color), D3D11_INPUT_PER_VERTEX_DATA, 0 },
// Instanced Data
{ "INSTANCED_MATS", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1},
{ "INSTANCED_MATS", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1},
{ "INSTANCED_MATS", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D11_INPUT_PER_INSTANCE_DATA, 1},
{ "INSTANCED_MATS", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 64, D3D11_INPUT_PER_INSTANCE_DATA, 1}
};
hr = g_d3dDevice->CreateInputLayout(vertexLayoutDesc, _countof(vertexLayoutDesc), vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_d3dInputLayout);
if (FAILED(hr)) {
return false;
}
Finally in another function called Draw I attach the data to the IA and call DrawInstanced as follows. :
...
const UINT vertexStride = sizeof(VertexPosColor);
const UINT offset = 0;
const UINT instancedVetexStride = sizeof(XMMATRIX);
g_d3dDeviceContext->IASetVertexBuffers(0, 1, &g_d3dVertexBuffer, &vertexStride, &offset);
g_d3dDeviceContext->IASetVertexBuffers(1, 1, &g_d3dIndexedVertexBuffer, &instancedVetexStride, &offset);
g_d3dDeviceContext->IASetInputLayout(g_d3dInputLayout);
...
// Draw the cube
g_d3dDeviceContext->DrawIndexed(std::size(g_Indicies), 0, 0);
//g_d3dDeviceContext->DrawIndexedInstanced(std::size(g_Indicies), 1, 0, 0, 0);
The following is my vertex shader as is:
//VERTEX SHADER
cbuffer PerApplication : register(b0)
{
matrix projectionMatrix;
}
cbuffer PerFrame : register(b1)
{
matrix viewMatrix;
}
cbuffer PerObject : register(b2)
{
matrix worldMatrix;
}
struct AppData
{
float3 position : POSITION;
float3 color: COLOR;
matrix instancedMatrix : INSTANCED_MATS;
};
struct VertexShaderOutput
{
float4 color : COLOR;
float4 position : SV_POSITION;
};
VertexShaderOutput SimpleVertexShader(AppData IN, uint instanceID : SV_InstanceID)
{
VertexShaderOutput OUT;
uint p = instanceID;
matrix mvp = mul(projectionMatrix, mul(viewMatrix, IN.instancedMatrix));// worldMatrix));
float4 pos = float4(IN.position, 1.0f);
OUT.position = mul(mvp, pos);
OUT.color = float4(IN.color, 1.0f);
return OUT;
}
I am not sure if I am setting the offsets incorrectly or if I am incorrectly attaching the slots for the VB's to the IA. Or is it something to do with my input description for the BV's.
But I get the following D3D11 Warning, which to me is vague as I do not know what offset of 80 it is talking of.
D3D11 WARNING: ID3D11DeviceContext::DrawIndexed: Input vertex slot 1 has stride 64 which is less than the minimum stride logically expected from the current Input Layout (80 bytes). This is OK, as hardware is perfectly capable of reading overlapping data. However the developer probably did not intend to make use of this behavior. [ EXECUTION WARNING #355: DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL]
D3D11 WARNING: ID3D11DeviceContext::DrawIndexed: Vertex Buffer at the input vertex slot 1 is not big enough for what the Draw*() call expects to traverse. This is OK, as reading off the end of the Buffer is defined to return 0. However the developer probably did not intend to make use of this behavior. [ EXECUTION WARNING #356: DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL]
I have been stuck here for hours. Any help, hints is greatly appreciated!!