Mesh single subset

Started by
14 comments, last by Maxim Skachkov 18 years, 4 months ago
Quote:Original post by Armadon
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.


Pieter!
One week ago I completely saw your site and blog, downloaded tutorials. Today I registered on this site and it was a surprise for me to meet you there and that you answered my question.
Example Normal Mapping was useful to us. As to this example - in Render Monkey 1.6 is shader, allows you to create normal maps effect from texture.
Advertisement
Quote:Original post by Maxim Skachkov
remigius!

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


Good to see it helped. Would you mind posting some code? I went to investigate this further for TheMaskedFace, but I can't get it to work properly for myself :)

Basically I've split up the mesh into vertex and index buffers, but I'm rather confused about the large amount of vertices that seem to be assigned for each attribute range. So, if you could clear things up in turn, that'd be great!
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
Quote:Original post by remigius

Would you mind posting some code? I went to investigate this further for TheMaskedFace, but I can't get it to work properly for myself :)



My code (unit):

using System;using Microsoft.DirectX;using Microsoft.DirectX.Direct3D;using Microsoft.Samples.DirectX.UtilityToolkit;namespace Main{	/// <summary>	/// Summary description for Gynecology.	/// </summary>	public class Andrology	{		VertexBuffer MeshVB = null;		IndexBuffer MeshIB = null;		Mesh Mesh00 = null;		Mesh Mesh01 = null;		Mesh Mesh02 = null;		VertexBuffer VB00 = null;		VertexBuffer VB01 = null;		VertexBuffer VB02 = null;		IndexBuffer IB = null;		Effect effect = null;		EffectHandle WorldViewProjHandle = null; // Effect Handle for the 'world view Proj' matrix		EffectHandle WorldHandle = null; // Effect Handle for the 'world view Proj' matrix		EffectHandle WeightHandle = null;		EffectHandle LightPosHandle = null;//		EffectHandle TextureHandle = null;		int VerticesNum;		int FacesNum;		Texture MeshTexture = null;				VertexDeclaration VertDecl = null;		Material[] meshMaterials;			Texture[] meshTextures;		IndexBuffer[] meshIndBuffs;				AttributeRange[] attributeTable;		double KickFreq;		double Phase;		double BlendWeight;		Vector4 Weight;		public Andrology()		{		}		void Load (Device ADevice)		{			Mesh MeshTemp = null;			int NumIndices;			int[] adjacency;			MeshTexture = TextureLoader.FromFile(ADevice, @"Persons\Gynecology.bmp");						ExtendedMaterial[] materials = null;                        Mesh00 = Mesh.FromFile(@"Persons\kadr00.X", MeshFlags.Managed, ADevice, out materials);			MeshTemp = Mesh00.Clone( Mesh00.Options.Value, VertexFormats.Position | VertexFormats.Normal | VertexFormats.Texture1, ADevice );			MeshTemp.ComputeNormals();			Mesh00.Dispose();			Mesh00 = MeshTemp;			adjacency = new int[3 * Mesh00.NumberFaces];			Mesh00.GenerateAdjacency( 0.01f, adjacency );			Mesh00.OptimizeInPlace( MeshFlags.OptimizeAttributeSort, adjacency ); 			attributeTable = Mesh00.GetAttributeTable();			meshTextures = new Texture[ materials.Length ];			meshMaterials = new Material[ materials.Length ];			meshIndBuffs = new IndexBuffer[ materials.Length ];			//meshEffect = new Effect[materials.Length];			for( int i = 0; i < materials.Length; i++ )			{				meshMaterials = materials.Material3D;				meshMaterials.Ambient = meshMaterials.Diffuse;				if (materials.TextureFilename != null)					meshTextures = TextureLoader.FromFile(ADevice, @"Persons\" + materials.TextureFilename);				else					meshTextures = null;			}			Mesh01 = Mesh.FromFile(@"Persons\kadr01.X", MeshFlags.Managed, ADevice, out materials);			MeshTemp = Mesh01.Clone( Mesh00.Options.Value, VertexFormats.Position | VertexFormats.Normal | VertexFormats.Texture1, ADevice );			MeshTemp.ComputeNormals();			Mesh01.Dispose();			Mesh01 = MeshTemp;			adjacency = new int[3 * Mesh01.NumberFaces];			Mesh01.GenerateAdjacency( 0.01f, adjacency );			Mesh01.OptimizeInPlace( MeshFlags.OptimizeAttributeSort, adjacency ); 			Mesh02 = Mesh.FromFile(@"Persons\kadr02.X", MeshFlags.Managed, ADevice, out materials);			MeshTemp = Mesh02.Clone( Mesh00.Options.Value, VertexFormats.Position | VertexFormats.Normal | VertexFormats.Texture1, ADevice );			MeshTemp.ComputeNormals();			Mesh02.Dispose();			Mesh02 = MeshTemp;			adjacency = new int[3 * Mesh02.NumberFaces];			Mesh02.GenerateAdjacency( 0.01f, adjacency );			Mesh02.OptimizeInPlace( MeshFlags.OptimizeAttributeSort, adjacency ); 			VerticesNum  = Mesh00.NumberVertices;			FacesNum     = Mesh00.NumberFaces;						VB00 = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), VerticesNum, ADevice, 				Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Managed);			VB01 = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), VerticesNum, ADevice, 				Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Managed);			VB02 = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), VerticesNum, ADevice, 				Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Managed);						IB = new IndexBuffer(typeof(ushort), FacesNum * 3, ADevice, Usage.WriteOnly, Pool.Default);						CustomVertex.PositionNormalTextured[] Buff = null;			CustomVertex.PositionNormalTextured[] BuffNew = null;			// Copy vertices for mesh 00			Buff = (CustomVertex.PositionNormalTextured[])Mesh00.LockVertexBuffer(typeof(CustomVertex.PositionNormalTextured), LockFlags.None, VerticesNum);			BuffNew = (CustomVertex.PositionNormalTextured[])VB00.Lock(0,0);			Array.Copy(Buff, BuffNew, Buff.Length );			VB00.Unlock();			Mesh00.UnlockVertexBuffer();			// Copy vertices for mesh 01			Buff = (CustomVertex.PositionNormalTextured[])Mesh01.LockVertexBuffer(typeof(CustomVertex.PositionNormalTextured), LockFlags.None, VerticesNum);			BuffNew = (CustomVertex.PositionNormalTextured[])VB01.Lock(0,0);			Array.Copy(Buff, BuffNew, Buff.Length );			VB01.Unlock();			Mesh01.UnlockVertexBuffer();			// Copy vertices for mesh 03			Buff = (CustomVertex.PositionNormalTextured[])Mesh02.LockVertexBuffer(typeof(CustomVertex.PositionNormalTextured), LockFlags.None, VerticesNum);			BuffNew = (CustomVertex.PositionNormalTextured[])VB02.Lock(0,0);			Array.Copy(Buff, BuffNew, Buff.Length );			VB02.Unlock();			Mesh02.UnlockVertexBuffer();			ushort[] ib;			// Copy indices for the dolphin mesh			ib = (ushort[])Mesh00.LockIndexBuffer(typeof(ushort),  LockFlags.None, FacesNum * 3);			IB.SetData(ib, 0, LockFlags.None);			Mesh00.UnlockIndexBuffer();						// Create vertex shader for the			// Create the vertex element array.			VertexElement[] elements = new VertexElement[]			{				// First stream is first mesh				new VertexElement(0, 0, DeclarationType.Float3,	DeclarationMethod.Default, DeclarationUsage.Position, 0),				new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default,	DeclarationUsage.Normal, 0),    			new VertexElement(0, 24, DeclarationType.Float2, DeclarationMethod.Default,	DeclarationUsage.TextureCoordinate, 0),                // Second stream is second mesh            				new VertexElement(1, 0, DeclarationType.Float3,	DeclarationMethod.Default, DeclarationUsage.Position, 1),				new VertexElement(1, 12, DeclarationType.Float3, DeclarationMethod.Default,	DeclarationUsage.Normal, 1),				new VertexElement(1, 24, DeclarationType.Float2, DeclarationMethod.Default,	DeclarationUsage.TextureCoordinate, 1),				// Third stream is third mesh				new VertexElement(2, 0, DeclarationType.Float3,	DeclarationMethod.Default, DeclarationUsage.Position, 2),				new VertexElement(2, 12, DeclarationType.Float3, DeclarationMethod.Default,	DeclarationUsage.Normal, 2),				new VertexElement(2, 24, DeclarationType.Float2, DeclarationMethod.Default,	DeclarationUsage.TextureCoordinate, 2),				VertexElement.VertexDeclarationEnd			};			// Use the vertex element array to create a vertex declaration.			VertDecl = new VertexDeclaration(ADevice, elements);			string errorMessage;			effect = Effect.FromFile(ADevice, @"Shaders\Tween.fx", null, ShaderFlags.Debug, null, out errorMessage);			if ( errorMessage != null ) return;			WorldViewProjHandle = effect.GetParameter(null, "WorldViewProj");			WorldHandle = effect.GetParameter(null, "World");			LightPosHandle = effect.GetParameter(null, "LightPos");			WeightHandle = effect.GetParameter(null, "Weight");//			TextureHandle  = effect.GetParameter(null, "Texture");		}		public override bool SetPositionNext(double ATime, Way.DrawFlags Flag)		{			KickFreq    = 2*ATime;			Phase       = ATime/3;			BlendWeight = Math.Sin(KickFreq);			double Weight1;			double Weight2;			double Weight3;			if( BlendWeight > 0.0f )			{				Weight1 = Math.Abs(BlendWeight);				Weight2 = 1.0f - Math.Abs(BlendWeight);				Weight3 = 0.0f;			}			else			{				Weight1 = 0.0f;				Weight2 = 1.0f - Math.Abs(BlendWeight);				Weight3 = Math.Abs(BlendWeight);			}			Weight = new Vector4((float)Weight1, (float)Weight2, (float)Weight3, 0);			return true;		}		public override void Draw(Way.DrawFlags Flag, Device ADevice, ModelViewerCamera ACamera, ref Vector3 AShift, Matrix ARotate)		{			if (Mesh00 == null) Load(ADevice);			//			ADevice.Transform.World = ACamera.WorldMatrix * Matrix.Translation(AShift) * Matrix.RotationZ((float)Math.PI);        			Vector4 Diffuse  = new Vector4 (0.9f, 0.9f, 0.9f, 0.9f);			Vector4 Ambient  = new Vector4 (0.1f, 0.1f, 0.1f, 0.1f);			Vector4 Fog      = new Vector4 (0.5f, 50.0f, 1.0f/(50.0f - 1.0f), 0.0f);			Vector4 Light    = new Vector4 (0.0f, 0.0f, -100.0f, 0.0f );			// Setup vertex shader constants			effect.SetValue(WorldViewProjHandle, ACamera.WorldMatrix * Matrix.Translation(AShift) * ACamera.ViewMatrix * ACamera.ProjectionMatrix);			effect.SetValue(WorldHandle, ACamera.WorldMatrix * Matrix.Translation(AShift));			effect.SetValue(WeightHandle, Weight);			effect.SetValue(LightPosHandle, Light);//			effect.SetValue(TextureHandle, meshTextures[0]);			ADevice.VertexDeclaration = VertDecl;			ADevice.SetStreamSource(0, VB00, 0);			ADevice.SetStreamSource(1, VB01, 0);			ADevice.SetStreamSource(2, VB02, 0);			ADevice.Indices = IB;						effect.Technique = "Tweenly";//			effect.Begin(0);//			effect.BeginPass(0);//			ADevice.SetTexture( 0, meshTextures[8] );//			ADevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, VerticesNum, ADevice.RenderState.ZBufferEnable = true;			for (int i = 0; i < meshMaterials.Length; i++)			{				// Set the material and texture for this subset.				ADevice.Material = meshMaterials;				ADevice.SetTexture( 0, meshTextures );        				// Draw the mesh subset.//				ADevice.DrawPrimitives(PrimitiveType.TriangleList, attributeTable.VertexStart,attributeTable.VertexCount);				ADevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, attributeTable.VertexCount, attributeTable.FaceStart * 3, attributeTable.FaceCount);//				Mesh01.DrawSubset(i);			}//			effect.EndPass();//			effect.End();		}	}}


I need separate Indexbuffer for everyone subset in mesh for SHADER tweening animation. The current vertex is calculated by approximation of three vertices (like dolphin sample). But together with shader my code uncorrectly displays object - the triangles are disappeared, code for effect commented

effect.Begin(0);effect.BeginPass(0);...effect.EndPass();effect.End();


And with one IB for mesh the program with shader works correctly (below code is also commented):

ADevice. SetTexture (0, meshTextures [8]);ADevice. DrawIndexedPrimitives (PrimitiveType. TriangleList, 0, 0, VerticesNum, 0, FacesNum);


It is not acceptable for me, since we need to texture everyone subset in mesh using shader.


Where are the triangles disappeared?

[Edited by - Maxim Skachkov on December 26, 2005 12:58:09 PM]
Here two images



with disappearing triangles

good
and good.

[Edited by - Maxim Skachkov on December 26, 2005 12:50:39 PM]
Thanks for posting your code, I think I've found out where I got it wrong. As for your problem, you could try turning off backface culling (device.RenderState.CullMode = Cull.None) to see if that helps. Might be worth a shot.
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
The problem is solved by using Pool.SystemMemory instead Pool.Managed during VB creation.

I'm thinking why?

This topic is closed to new replies.

Advertisement