barkas
14-10-2008 12:04:50
The version in the wiki doesn't work right, it causes Exceptions later in Garbage Collection.
The important changes are vbuf.Dispose() and ibuf.Dispose()
The important changes are vbuf.Dispose() and ibuf.Dispose()
// Get the mesh information for the given mesh.
public static unsafe void GetMeshInformation(MeshPtr mesh,
ref uint vertex_count,
ref Vector3[] vertices,
ref uint index_count,
ref UInt64[] indices,
Matrix4 transform)
{
bool added_shared = false;
uint current_offset = 0;
uint shared_offset = 0;
uint next_offset = 0;
uint index_offset = 0;
vertex_count = index_count = 0;
for (ushort i = 0; i < mesh.NumSubMeshes; ++i)
{
SubMesh submesh = mesh.GetSubMesh(i);
if (submesh.useSharedVertices)
{
if (!added_shared)
{
vertex_count += mesh.sharedVertexData.vertexCount;
added_shared = true;
}
}
else
{
vertex_count += submesh.vertexData.vertexCount;
}
index_count += submesh.indexData.indexCount;
}
vertices = new Vector3[vertex_count];
indices = new UInt64[index_count];
added_shared = false;
for (ushort i = 0; i < mesh.NumSubMeshes; ++i)
{
SubMesh submesh = mesh.GetSubMesh(i);
VertexData vertex_data = submesh.useSharedVertices ? mesh.sharedVertexData : submesh.vertexData;
if (!submesh.useSharedVertices || (submesh.useSharedVertices && !added_shared))
{
if (submesh.useSharedVertices)
{
added_shared = true;
shared_offset = current_offset;
}
VertexElement posElem =
vertex_data.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION);
HardwareVertexBufferSharedPtr vbuf =
vertex_data.vertexBufferBinding.GetBuffer(posElem.Source);
byte* vertex = (byte*)vbuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
float* pReal;
for (int j = 0; j < vertex_data.vertexCount; ++j, vertex += vbuf.VertexSize)
{
posElem.BaseVertexPointerToElement(vertex, &pReal);
Vector3 pt = new Vector3(pReal[0], pReal[1], pReal[2]);
vertices[current_offset + j] = transform * pt;
}
vbuf.Unlock();
vbuf.Dispose();
next_offset += vertex_data.vertexCount;
}
IndexData index_data = submesh.indexData;
uint numTris = index_data.indexCount / 3;
HardwareIndexBufferSharedPtr ibuf = index_data.indexBuffer;
bool use32bitindexes = (ibuf.Type == HardwareIndexBuffer.IndexType.IT_32BIT);
UInt32* pLong = (UInt32*)ibuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
ushort* pShort = (ushort*)pLong;
uint offset = submesh.useSharedVertices ? shared_offset : current_offset;
if (use32bitindexes)
{
for (int k = 0; k < index_data.indexCount; ++k)
{
indices[index_offset++] = (UInt64)pLong[k] + (UInt64)offset;
}
}
else
{
for (int k = 0; k < index_data.indexCount; ++k)
{
indices[index_offset++] = (UInt64)pShort[k] + (UInt64)offset;
}
}
ibuf.Unlock();
ibuf.Dispose();
current_offset = next_offset;
}
}