/// <summary> /// Init Primitive Collection /// </summary> /// <param name="count"></param> /// <param name="gd"></param> /// <param name="primitive"></param> /// <param name="service"></param> /// <param name="path"></param> public void Init(int count, GraphicsDevice gd, Primitive primitive, IServiceProvider service, string path) { // Check Shader Model 3.0 Support GraphicsDeviceCapabilities gdcap = gd.GraphicsDeviceCapabilities; if (gdcap.MaxPixelShaderProfile < ShaderProfile.PS_3_0 || gdcap.MaxVertexShaderProfile < ShaderProfile.VS_3_0) { isshadermodel3 = false; MessageBox.Show("This GraphicsDevice Does Not Support Shader Model 3.0.", "Warning !"); } else { isshadermodel3 = true; } if (count <= 0) { MessageBox.Show("Collection Number <= 0, Automatically Set To One !"); count = 1; } if (PrimitiveInstance == null) { PrimitiveInstance = primitive.Clone() as Primitive; } InstancePara = new vsBasePara[count]; InstanceMatrix = new Matrix[count]; for (int i = 0; i < count; i++) { InstancePara[i] = PrimitiveInstance.BasePara; } // Randomize Center and Speed of Primitive Instances var center = Random.RandomPosition(InstancePara.Length); var speed = Random.RandomPosition(InstancePara.Length); for (int i = 0; i < InstancePara.Length; i++) { center[i].X = center[i].X * (PrimitiveInstance.BasePara.space / 2) * (float)Math.Sin(Math.PI / 4); center[i].Y = center[i].Y * (PrimitiveInstance.BasePara.space / 2) * (float)Math.Sin(Math.PI / 4); center[i].Z = 0; speed[i].X = speed[i].X * 0.5f; speed[i].Y = speed[i].Y * 0.5f; speed[i].Z = 0; InstancePara[i].center = center[i] + Para.CollectionCenter; InstancePara[i].speed3D = speed[i] + Para.CollectionSpeed; InstanceMatrix[i] = VisionStimulus.GetOri3DMatrix(InstancePara[i].orientation3D) * Matrix.CreateTranslation(InstancePara[i].center); } // Load Hardware Instancing Shader PrimitiveInstance.contentManager = new ContentManager(service, path); try { hiEffect = PrimitiveInstance.contentManager.Load <Effect>("HardwareInstancing"); } catch (Exception e) { MessageBox.Show(e.Message, "Error !"); } hiEffect.Parameters["View"].SetValue(PrimitiveInstance.ViewMatrix); hiEffect.Parameters["Projection"].SetValue(PrimitiveInstance.ProjectionMatrix); PrimitiveInstance.vertexDeclaration = InstancingVDec(gd); ptype = PrimitiveInstance.BasePara.primitivetype; vexn = PrimitiveInstance.VertexArray.Length; pcount = VisionStimulus.CheckPrimitiveCount(ptype, PrimitiveInstance.IndexArray.Length, PrimitiveInstance.IndexArray.Length); InstanceDataStream = new DynamicVertexBuffer(gd, SLConstant.SizeOfMatrix * InstanceMatrix.Length, BufferUsage.WriteOnly); }
/// <summary> /// Optimized Batch Draw /// </summary> /// <param name="gd"></param> public virtual void BatchDraw(GraphicsDevice gd) { switch (Collection[0].VSType) { case VSType.Bar: case VSType.Primitive: PrimitiveType ptype = Collection[0].BasePara.primitivetype; int vexn = Collection[0].VertexArray.Length; int pcount = VisionStimulus.CheckPrimitiveCount(ptype, Collection[0].IndexArray.Length, Collection[0].IndexArray.Length); gd.VertexDeclaration = Collection[0].vertexDeclaration; gd.Vertices[0].SetSource(Collection[0].vertexBuffer, 0, VertexPositionColor.SizeInBytes); gd.Indices = Collection[0].indexBuffer; gd.RenderState.CullMode = CullMode.None; // Begin Draw Collection[0].basicEffect.Begin(); Collection[0].basicEffect.CurrentTechnique.Passes[0].Begin(); for (int i = 0; i < Collection.Count; i++) { if (Collection[i].Visible) { Collection[0].basicEffect.World = Collection[i].Ori3DMatrix * Collection[i].WorldMatrix; Collection[0].basicEffect.CommitChanges(); gd.DrawIndexedPrimitives(ptype, 0, 0, vexn, 0, pcount); } } Collection[0].basicEffect.CurrentTechnique.Passes[0].End(); Collection[0].basicEffect.End(); break; case VSType.Grating: ptype = Collection[0].BasePara.primitivetype; vexn = Collection[0].VertexArray.Length; pcount = VisionStimulus.CheckPrimitiveCount(ptype, Collection[0].IndexArray.Length, Collection[0].IndexArray.Length); gd.VertexDeclaration = Collection[0].vertexDeclaration; gd.Vertices[0].SetSource(Collection[0].vertexBuffer, 0, VertexPositionColor.SizeInBytes); gd.Indices = Collection[0].indexBuffer; gd.RenderState.CullMode = CullMode.None; Grating grating = Collection[0] as Grating; // Begin Draw grating.gratingeffect.Begin(); grating.gratingeffect.CurrentTechnique.Passes[0].Begin(); for (int i = 0; i < Collection.Count; i++) { if (Collection[i].Visible) { grating.eWorld.SetValue(Collection[i].Ori3DMatrix * Collection[i].WorldMatrix); grating.gratingeffect.CommitChanges(); gd.DrawIndexedPrimitives(ptype, 0, 0, vexn, 0, pcount); } } grating.gratingeffect.CurrentTechnique.Passes[0].End(); grating.gratingeffect.End(); break; case VSType.Image: Vector3 Center; float unitFactor = Collection[0].unitFactor; Image image = Collection[0] as Image; // Begin Draw image.spriteBatch.Begin(); for (int i = 0; i < Collection.Count; i++) { if (Collection[i].Visible) { Center = Collection[i].Center; image.spriteBatch.Draw(image.texture, new Vector2(Center.X * unitFactor + gd.Viewport.Width / 2 - image.texture.Width / 2, gd.Viewport.Height / 2 - Center.Y * unitFactor - image.texture.Height / 2), Collection[i].BasePara.color); } } image.spriteBatch.End(); break; case VSType.SLModel: SLModel model = Collection[0] as SLModel; foreach (ModelMesh mesh in model.Model.Meshes) { for (int i = 0; i < Collection.Count; i++) { if (Collection[i].Visible) { foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.GraphicsDevice.RenderState.DepthBufferEnable = true; effect.World = Collection[i].Ori3DMatrix * model.BoneTransforms[mesh.ParentBone.Index] * Collection[i].WorldMatrix; effect.View = model.ViewMatrix; effect.Projection = model.ProjectionMatrix; } mesh.Draw(); } } } break; case VSType.SLQuad: SLQuad quad = Collection[0] as SLQuad; ptype = Collection[0].BasePara.primitivetype; vexn = quad.Para.vertices.Length; pcount = VisionStimulus.CheckPrimitiveCount(ptype, Collection[0].IndexArray.Length, Collection[0].IndexArray.Length); gd.VertexDeclaration = quad.vertexDeclaration; gd.Vertices[0].SetSource(quad.vertexBuffer, 0, VertexPositionNormalTexture.SizeInBytes); gd.Indices = quad.indexBuffer; gd.RenderState.CullMode = CullMode.None; gd.RenderState.AlphaBlendEnable = true; gd.RenderState.AlphaTestEnable = true; gd.RenderState.AlphaFunction = CompareFunction.Greater; // Begin Draw quad.basicEffect.Begin(); quad.basicEffect.CurrentTechnique.Passes[0].Begin(); for (int i = 0; i < Collection.Count; i++) { if (Collection[i].Visible) { quad.basicEffect.World = Collection[i].Ori3DMatrix * Collection[i].WorldMatrix; quad.basicEffect.CommitChanges(); gd.DrawIndexedPrimitives(ptype, 0, 0, vexn, 0, pcount); } } quad.basicEffect.CurrentTechnique.Passes[0].End(); quad.basicEffect.End(); break; case VSType.SLVideo: SLVideo video = Collection[0] as SLVideo; unitFactor = Collection[0].unitFactor; // Begin Draw video.spriteBatch.Begin(); for (int i = 0; i < Collection.Count; i++) { if (Collection[i].Visible) { Center = Collection[i].Center; if (video.MediaState == MediaState.Stopped) { video.Play(); } if (video.MediaState != MediaState.Stopped) { video.texture = video.Player.GetTexture(); } if (video.texture != null) { video.spriteBatch.Draw(video.texture, new Vector2(Center.X * unitFactor + gd.Viewport.Width / 2 - video.texture.Width / 2, gd.Viewport.Height / 2 - Center.Y * unitFactor - video.texture.Height / 2), Collection[i].BasePara.color); } } } video.spriteBatch.End(); break; case VSType.Text: Text text = Collection[0] as Text; Vector2 size = text.spriteFont.MeasureString(SLConstant.Help); unitFactor = Collection[0].unitFactor; // Begin Draw text.spriteBatch.Begin(); for (int i = 0; i < Collection.Count; i++) { if (Collection[i].Visible) { Center = Collection[i].Center; text.spriteBatch.DrawString(text.spriteFont, SLConstant.Help, new Vector2(Center.X * unitFactor + gd.Viewport.Width / 2 - size.X / 2, gd.Viewport.Height / 2 - Center.Y * unitFactor - size.Y / 2), Collection[i].BasePara.color); } } text.spriteBatch.End(); break; } }