\\ Home : Articoli : Stampa
Primitives
Di RobyDx (del 22/04/2007 @ 15:30:19, in English, linkato 2125 volte)

Now let's talk about buffers. A buffer used for vertices it's called vertex buffer
At first we must define a structure for vertex that will contain position, color, texture coord and other. We will use the same structure of previous tutorial

struct VertexType
{
D3DXVECTOR3 position;
D3DXVECTOR4 color;
};

D3DXVECTOR are types defined in DirectX10: D3DXVECTOR3 contains 3 floats (xyz), while VECTOR4 has got 4 floats (xyzw). If you remember in the shader we defined the position as a float4 but now we have got only 3 floats. If you remember in first tutorial i explained you that vertices are used as omogeneus (then last value = 1). If we use a vector3 passing a float4 in the shader, directx automatically will set last value to 1.
A vertex requires a description using a struct called VertexLayout that will let us to specify what semantics will have each value.
ID3D10InputLayout* vertexLayout;

D3D10_INPUT_ELEMENT_DESC layout[] =
{
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0, D3D10_INPUT_PER_VERTEX_DATA,0},
{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,12, D3D10_INPUT_PER_VERTEX_DATA,0 },
};

The description is contained in the ID3D10InputLayout interface. At first we describe vertex data. In this case we have got 2 informations: position and color. These information will be inserted with an array of D3D10_INPUT_ELEMENT_DESCThe Element_Desc struct has got this fields:

  • SemanticName: name to associe in the shader. That data in the shader will have got that name
  • SemanticIndex: An index for element. In this mode we can have POSITION1, POSITION2...
  • Format: format of element
  • InputSlot: It's possibile to use more slot in same time. Here we have to specify what.
  • AlignedByteOffset: The memory point from which directx will start read data (in bytes)
  • InputSlotClass: data type
  • InstanceDataStepRate: Information for instancing type. This will be explained later, VERY later!

In first case we set first 12 bytes of structure at POSITION variable, saying that it's first data of struct (the the offset is 0, and 12 becouse 3 * sizeof(float) = 12). The second case there will be COLOR, with R32G32B32A32_FLOAT format becouse it's formed by float4 and will have offset = 12 becouse we must read after the position. From shader now we will take its description to associe vertex to the shader.
D3D10_PASS_DESC PassDesc;
effect->GetTechniqueByIndex(0)->GetPassByIndex( 0 )->GetDesc( &PassDesc );

Now we can finally create InputLayout
HRESULT hr= device->CreateInputLayout( layout, 2, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &vertexLayout );

Now vertexLayout has got all information for association. Now we can create VertexBuffer that will contain our vertices. We must remeber that our shader does not multiplicate position and matrices. It just give us position. Then we must use DirectX coordinates (then in the range -1,1)

ID3D10Buffer* vertexBuffer;

VertexType vertices[3];
vertices[0].position=D3DXVECTOR3(0.5F,-0.5F,0);
vertices[0].color=D3DXVECTOR4(1,0,0,0);
vertices[1].position=D3DXVECTOR3(-0.5F,-0.5F,0);
vertices[1].color=D3DXVECTOR4(0,1,0,0);
vertices[2].position=D3DXVECTOR3(0,0.5F,0);
vertices[2].color=D3DXVECTOR4(1,1,0,0);

D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = stride * vertexCount;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = data;
HRESULT hr=device->CreateBuffer( &bd, &vertices, &vertexBuffer );

With these istructions we create a vertex buffer. Very important is ByteWidth in which we must set the size of our buffer (in our case the struct it's a vector3+vector4 (= 7 floats) * sizeof(float) = 28 bytes. 28 (sizeof 1 structure) * 3 (becouse we have created 3 vertices) = 84 bytes) that it's value to assing. Other parameter it's pSysMem that it's a pointer that contains buffer data (that in our case it's vertices array)
Now we are ready to use buffer.

device->IASetInputLayout(vertexLayout);
device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
device->IASetVertexBuffers( 0, 1, &vertexBuffer, &stride, &offset );


With there 4 istruction we set buffer into device. First istruction sets layout, second one what kind of polygon are we going to render (a triangle, for now), third one the buffer (slot position,how much buffers contains the buffer, on our case 1, and buffer with stride values into device)
Apply also the shader now it's all ready.
device->Draw(vertexCount,0);

This will send to video the result to the screen. The Draw function takes in input number of vertices and from what vertex it must start to render.

Here is the demo. In next tutorial we will continue our lessons with shaders.

Demo

A special thanks goes to Vincent who translate this lesson.