I am practicing drawing in Direct3D9, and ran into a little problem.
For example, the first parameter in d3ddev->SetStreamSource(1, NULL, 0, sizeof(CUSTOMVERTEX));
is to specify the "data stream", but I don't know what that is.
I've got it drawing the shape I want, but I still don't understand what "data stream" means.
This was called "Multistream" Vertex Buffers back in the day. This basically lets the GPU build up each vertex during drawing from more than one Vertex Buffer.
A simple example using Direct3D 11 (the concept is the same) would be different VBs for each component:
struct VertexStream1
{
float pos[3];
};
struct VertexStream2
{
float norm[3];
};
struct VertexStream3
{
float color[4];
}
can be described by an input layout:
const D3D11_INPUT_ELEMENT_DESC InputElements[] =
{
// Semantic, SemanticIndex, Format, InputSlot, ...
{ "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 2, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
Which internally maps to a Vertex Shader input like:
struct VSInputNmTx
{
float4 Position : SV_Position;
float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD0;
};
At runtime this requires you bind THREE VertexBuffers each of which can have their own 'vertex stride'. Each Vertex Buffer has to have enough entries to match the number of vertices you are drawing.
ID3D11VertexBuffer* vertexBuffer[3] = …;
UINT vertexStride[3] = { sizeof(VertexStream1), sizeof(VertexStream2), sizeof(VertexStream3) };
UINT vertexOffset[3] = { 0, 0, 0 };
context->IASetVertexBuffers(0, 3, vertexBuffer, &vertexStride, &vertexOffset);
This isn't a great example of real-world usage, but it gets the point across. This is also the syntax used for "Instancing" where basically you can set up a 'loop' for one or more of the streams.