Mesh single subset

Started by
14 comments, last by Maxim Skachkov 18 years, 3 months ago
How to receive mesh single subset IndexBuffer(VertexBuffer)?
Advertisement
Maybe,
LPDIRECT3DINDEXBUFFER9 ib;LPDIRECT3DVERTEXBUFFER9 vb; mesh->GetIndexBuffer(&ib);mesh->GetVertexBuffer(&vb);

and see this topic: Click

[Edited by - gymisi on December 20, 2005 2:13:05 AM]
Blog(Hungarian)MDX - C# - C++
Quote:Original post by gymisi
Maybe,
*** Source Snippet Removed ***
and see this topic: Click


I mean the separate Indexbuffer for everyone subset in mesh!
Before you can get an index buffer and vertex buffer for each subset you will need to know what a subset is. A subset is the division of a mesh into a set of data for each material used.
From the SDK Documentation
"It is divided into a subset for each material that was loaded for the mesh"
You could probably poke around in the mesh data for the information you are looking for and extracting the vertex and index data per subset. I am sure there are easier ways to do this but you'll have to wait for someone with more experience in the field to reply.

I hope this helps.
Take care.
I don't have any experience with this myself, but a quick look at the docs reveals the ID3DXBaseMesh::GetAttributeTable method. This method gives you an array of D3DXATTRIBUTERANGE structs from which you can retrieve the vertex and face information you need to get the data out of the mesh buffers.
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
A combination of what Armadon and remigius said is the only way I know of doing what you want.

You'll have to query the attribute table to get the details for the specific subset, then lock the vertex/index buffer and extract the data as indicated by the values you got from the attribute table.

If you want a VB/IB rather than just a list of vertices and indices then you'll have to create them and copy the data yourself.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Below an example of a code on C#:


Mesh Mesh00 = null;  // Mesh ObjectMaterial[] meshMaterials;  // Material for each subsetTexture[] meshTextures;  // Texture for each subsetIndexBuffer[] meshIndBuffs;  // Index buffers for each subsetExtendedMaterial[] materials = null;  // Array of the expanded materials received from a x-file// Load Mesh from a fileMesh00 = Mesh.FromFile(@"Persons\aamSens00.X", MeshFlags.SystemMemory, ADevice, out materials);// Allocate memory under materialsmeshTextures = new Texture[ materials.Length ];// Allocate memory under structuresmeshMaterials = new Material[ materials.Length ];// Allocate memory under IndexBuffersmeshIndBuffs = new IndexBuffer[ materials.Length ];// For each subsetfor( int i = 0; i < materials.Length; i++ ){  // Write in a array a materials from the expanded materials  meshMaterials = materials.Material3D;  // Write in a array an ambient colors for a materials  meshMaterials.Ambient = meshMaterials.Diffuse;  // If the subset has the texture  if (materials.TextureFilename != null)    // Load the texture    meshTextures = TextureLoader.FromFile(ADevice, @"Persons\" + materials.TextureFilename);  else    meshTextures = null;  // Write in a array the IndexBuffermeshIndBuffs = Mesh.ConvertMeshSubsetToSingleStrip(Mesh00, i, MeshFlags.SystemMemory, out NumIndices);...}

Call function ConvertMeshSubsetToSingleStrip for Mesh gives out error message InvalidCallException if mesh consist of several subsets and does not give out it, if mesh consist of one subset. I.e. the question is reduced to use of functions ConvertMeshSubsetToSingleStrip and ConvertMeshSubsetToStrips.
Whether there is other alternative, as in Managed DirectX for .Net 2.0 couple " ConvertMeshSubsetToSingleStrip/ToStrips - removed " as Tom Miller (<http://www.thezbuffer.com/articles/294.aspx>) informs us.

[Edited by - Maxim Skachkov on December 22, 2005 5:17:54 PM]
Argh, couldn't you have posted that method earlier? :)

Below is my aproach, untested and made utterly redundant due to these methods in the MDX 1.1 API. Maybe it's still useful for creating a similar method for MDX 2.0, so here it is:

[source lang=c#]private IndexBuffer[] indexBuffers;private VertexBuffer[] vertexBuffers;private void CreateSubsetBuffers(Mesh mesh){	// generate adjecency for optimization	int[] adj = new int[mesh.NumberFaces * 3];	mesh.GenerateAdjacency(0, adj);	// optimize as recommended by the docs	Mesh optimizedMesh = mesh.Optimize( MeshFlags.OptimizeAttributeSort, adj );	// get attribute ranges and init buffer arrays	AttributeRange[] ranges = optimizedMesh.GetAttributeTable();	indexBuffers = new IndexBuffer[ ranges.Length ];	vertexBuffers = new VertexBuffer[ ranges.Length ];	for(int i = 0; i < ranges.Length; i++)	{		// we'll use the ID as the array index, just to make sure		int id = ranges.AttributeId;		int vStart = ranges.VertexStart;		int vCount = ranges.VertexCount;		int fStart = ranges.FaceStart;		int fCount = ranges.FaceCount;		// convert face info to indices for use later		int iStart = 3 * fStart;		int iCount = 3 * fCount;		// create vertex buffer		int vertexSize = mesh.NumberBytesPerVertex;        vertexBuffers[ id ] = new VertexBuffer( mesh.Device, vCount * vertexSize, 0, mesh.VertexFormat, Pool.Default );				// get graphics streams		using (GraphicsStream meshStream = mesh.VertexBuffer.Lock( vStart * vertexSize, vCount * vertexSize, LockFlags.ReadOnly ) )		{			using (GraphicsStream subsetStream = vertexBuffers[ id ].Lock( 0, vCount * vertexSize, LockFlags.None ))			{				// create io buffer				byte[] buffer = new byte[vertexSize];				for (int v = 0; v < vCount; v++)				{					meshStream.Read( buffer, v * vertexSize, vertexSize );					subsetStream.Write( buffer, v * vertexSize, vertexSize );				}				subsetStream.Flush();			}		}		// size in bytes, 2 for shorts, 4 for ints (16/32 bit)		int indexSize = 2;		indexBuffers[ id ] = new IndexBuffer( mesh.Device, iCount * indexSize, 0, Pool.Default, indexSize == 2);		// get graphics streams		using (GraphicsStream meshStream = mesh.IndexBuffer.Lock( iStart * indexSize, iCount * indexSize, LockFlags.ReadOnly ))		{			using (GraphicsStream subsetStream = indexBuffers[ id ].Lock( 0, iCount * indexSize, LockFlags.None ))			{				// create io buffer				byte[] buffer = new byte[indexSize];				for (int j = 0; j < iCount; j++)				{					meshStream.Read( buffer, j * indexSize, indexSize );					subsetStream.Write( buffer, j * indexSize, indexSize );				}				subsetStream.Flush();			}		}	}}


Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
byte[] buffer = new byte[vertexSize];
for (int v = 0; v < vCount; v++)
{
meshStream.Read( buffer, v * vertexSize, vertexSize );
subsetStream.Write( buffer, v * vertexSize, vertexSize );
}


gives an error about the array???
I can not find why?
wake up your sleepin' brains...
remigius!

Thanks for the first post - it was a key ! And for example. Now I use MDX 1.1 API.

This topic is closed to new replies.

Advertisement