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
And with one IB for mesh the program with shader works correctly (below code is also commented):
It is not acceptable for me, since we need to texture everyone subset in mesh using shader.