views:

478

answers:

1

Hi all,

I wrote a program to render a wavefront obj model in DirectX 10

I loaded the vertexes data as following desc

D3D10_INPUT_ELEMENT_DESC defaultLayout[] =
{
    {"POSITION",    0, DXGI_FORMAT_R32G32B32_FLOAT,  0, 0,        D3D10_INPUT_PER_VERTEX_DATA, 0},  
    {"NORMAL",   0, DXGI_FORMAT_R32G32B32_FLOAT,  0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0}, 
    {"COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0}, 
    {"TEXCOORD",    0, DXGI_FORMAT_R32G32_FLOAT,  0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0}, 
}; 
r = D3DX10CreateMesh(Graphics()->GetDevice(),defaultLayout,4,
                        "POSITION",NumVerts(),12,D3DX10_MESH_32_BIT,
                        &mpMesh);
    if(FAILED(r))
    {
        throw cGameError(L"Can not create mesh");
    }
    r= mpMesh->SetVertexData(0,&m_verts[0]);
    if(FAILED(r))
    {
        throw cGameError(L"Can not Set VertexData");
    }
    //mpMesh->SetIndexData(&m_tris[0],m_tris.size()*3);
    mpMesh->CommitToDevice();

As you can see, I didn't set up index buffer for mpMesh. I don't know how to calculate Vertexes index. As you can see, my vertex format include normal, which means the same vertex position might has different normal. For example, a cube contains 36 vertexes but only 8 different position. the wavefront obj file only use 8 position index.

The program generates the following error in run-time

DrawIndexed: Vertex Buffer Stride (15) at the input vertex slot 0 is not aligned properly. The current Input Layout imposes an alignment of (4) because of the Formats used with this slot.

EXECUTION ERROR #367: DEVICE_DRAW_VERTEX_STRIDE_UNALIGNED

I am not sure whether it's cause by not setting up mesh index or other problems. Any comment is welcome.

Thanks all.

+1  A: 

You can't use the OBJ data in its native form, because some data is shared between vertices as you mentioned. D3D only allows one index per vertex, not one index per attribute per vertex. So while you're loading the data, for each output vertex you need to copy all the data it uses (there are other options but this is the simplest). Once you do this, there's no need for an index buffer, since you're not reusing any vertices -- just use Draw().

The specific error is due to something you specified in the ID3D10Device::SetVertexBuffers() call, which you didn't show. It claims that you set the stride between vertices to be 15 bytes. That's not a multiple of 4 (required by the element formats you're using), and is also not the size of your vertex data. From the declaration, your vertex size is 48 bytes.

Jesse Hall
Thank you very much. Btw, I want to know if there's any benefit to create a mesh for those vertexes? I heard that using mesh is fast when I want to draw multiple objects with the same vertexes data.
LNK2019
Using the ID3DX10Mesh::Optimize() call can help performance significantly on large or complex models. Unless you optimize meshes as a preprocess (probably not, if you're reading OBJ directly), then this call alone makes using ID3DX10Mesh a good idea.
Jesse Hall