Jump to content
  • Advertisement
Sign in to follow this  
Maxim Skachkov

Mesh single subset

This topic is 4683 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Below an example of a code on C#:



Mesh Mesh00 = null; // Mesh Object
Material[] meshMaterials; // Material for each subset
Texture[] meshTextures; // Texture for each subset
IndexBuffer[] meshIndBuffs; // Index buffers for each subset
ExtendedMaterial[] materials = null; // Array of the expanded materials received from a x-file

// Load Mesh from a file
Mesh00 = Mesh.FromFile(@"Persons\aamSens00.X", MeshFlags.SystemMemory, ADevice, out materials);

// Allocate memory under materials
meshTextures = new Texture[ materials.Length ];
// Allocate memory under structures
meshMaterials = new Material[ materials.Length ];
// Allocate memory under IndexBuffers
meshIndBuffs = new IndexBuffer[ materials.Length ];

// For each subset
for( 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 IndexBuffer
meshIndBuffs = 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]

Share this post


Link to post
Share on other sites
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();
}
}
}
}



Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!