Use of Attribute Table

Started by
8 comments, last by DrGUI 19 years, 4 months ago
Generally, DirectX samples do not use an attribute table. The SkinnedMesh sample uses an attribute table for software skinning but not for normal meshes. Why? It did not call Optimize or anything which generates the attribute table, indeed since it was loaded it is only cloned. Should I be using an attribute table for all meshes that I can? (indexed skinning + attribute table no no) Thanks,
Advertisement
As I understand it the attribute table is used to cut the mesh up into subsets that may require different render states, bone configurations or textures. I must admit that I have had very poor luck getting the attribute table to work at all ( becuase of this I am moving away from using meshes -- for rendering anyway). If you can get it to work it could be very usefull, that is if you need to render different parts of your mesh with different render states or bone combinations.

In the Skinning example they also seem to use the attribute table to deal with lack of available blending caps (that is not enough blending matricies) by splitting the mesh down into subsets that only require the limited number of mats available.

It will make things more complicated. Like most DX things, only use it if it gets you something that you need -- compatibility, flexability, speed , etc..

hope this helps.
Thanks + ur ratings up for writing long post, but the attr table is only used with software skinning, so lack of blending is not an issue there.
I suppose you are already aware that you must call Optimize to generate the attr table.
What did you move from meshes to?

Thanks
The documentation suggests that you can specify the attribute table yourself -- that is use it to subset your mesh. The index that you pass to DrawSubset corresponds to the id of the attribute table group. I have loaded meshes from X files that contain attribute information and I believe that some of the meshes internally generated also contain attribute info (the teapot has one group for the lid and one for the body). Optimize should create attribute groups for you, but those groups will should be based on a reordering of the index to support somehting like the move from a triangle list to a strip and not a logical ordering. I had hoped that Optimize would respect the existing table so I could use it to "identify areas of the mesh that need to be drawn with different textures, render states and materials. " (as the docs say).

What I have been unable to do myself is to specify that information using the SetAttributeTable and LockAttributeBuffer methods on meshes that I generate. Regardless of my calls to Optimize before or after the table information is simply ignored and the entire mesh is regarded by DX as a single group.

It may be that I am simply thnking about and trying to use the table in the wrong way.

A mesh is a index buffer, a vetex buffer and an attribute buffer(table). What I am moving towards using in place of a mesh is a vertex buffer, an index buffer and a grouping consturct of my own (instead of using a mesh for each subset).

Not that any of this is really addressing your orignal question ... but we are all trying to understand this stuff.
Thanks, I will consider making my own structure.
Do you know if you need to apply the attribute table yourself when calling DrawSubset or if DrawSubset uses the table for you?
If your mesh has an attribute table you will have to call DrawSubset for each attribute range in the table. I am not sure, but I think that the attribute ids need to be consecutive and if that is the case

for(int attrId = 0; attrId< mesh.NumberAttributes; attrId++){
mesh.DrawSubset(attrId);
}

should work. If your table is correct anyway. I have managed to create an invalid mesh that reported 132 attributes, but rendered everything on the first DrawSubset call and then choked.
Thanks, turnpast - you're always very helpful.

The SkinnedMesh sample, for software skinning renders with something like:

for (int attrId = 0; attrId < mesh.NumberAttributes; attrId++) {
mesh.DrawSubset(attributeTable[attrId].AttributeId);
}

of course, tiny is probably already optimized and everything corresponds 1:1, but I need to account for when attrId != attributeTable[attrId].AttributeId don't I?
as far as i understand attrId == attributeTable[attrId].AttributeId is always true. I dont know what AttributeId is needed, but i guess it is for dx internaly knowing its index in the array for some reason.

Anyway, creating a attrib table manualy looks like this, so attrId == attributeTable[attrId].AttributeId should always be true, i dont see any other way to do it.
(this table is for a skybox of 6 quads)

if(FAILED(hr = m_d3dx_mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL)))			logprintf(LOG_FILE, "Error: %s\nLine: %d\nFile: %s", DXGetErrorString9(hr), __LINE__, __FILE__);		// generate attribute table		D3DXATTRIBUTERANGE attribute_table[m_num_attributes];		memset(attribute_table, 0, sizeof(D3DXATTRIBUTERANGE)*m_num_attributes);		for(int i = 0; i < m_num_attributes; ++i)		{			attribute_table.AttribId = i;			attribute_table.FaceCount = 2;			attribute_table.FaceStart = i*2;			attribute_table.VertexCount = 6;			attribute_table.VertexStart = i*6;		}				// set attribute table		if(FAILED(hr = m_d3dx_mesh->SetAttributeTable(attribute_table, m_num_attributes)))			logprintf(LOG_FILE, "Error: %s\nLine: %d\nFile: %s", DXGetErrorString9(hr), __LINE__, __FILE__);
Shields up! Rrrrred alert!
Even if it is consecutive this:
Quote:
for (int attrId = 0; attrId < mesh.NumberAttributes; attrId++) {
mesh.DrawSubset(attributeTable[attrId].AttributeId);
}

looks much better to me.
Thanks, although I didn't want to known how to make one manually.
Ratings 4u!

So DrawSubset uses the attribute table for you? That's all.

This topic is closed to new replies.

Advertisement