From dfa2a4665a736fe5b7e948714863ea3af8bb4ef8 Mon Sep 17 00:00:00 2001 From: Glatzemann Date: Fri, 16 Dec 2011 09:21:39 +0000 Subject: [PATCH] Finished the Primitives-Sample, but there are still rendering errors in hardware instancing part. The sample currently works with plain XNA to have a working base. --- Samples/Primitives/Game1.cs | 175 ++++++++++++++++-- .../Effects/HardwareInstancing.fx | 54 ++++++ .../SampleContent/SampleContent.contentproj | 8 +- 3 files changed, 220 insertions(+), 17 deletions(-) create mode 100644 Samples/SampleContent/Effects/HardwareInstancing.fx diff --git a/Samples/Primitives/Game1.cs b/Samples/Primitives/Game1.cs index 830a9917..3d44f915 100644 --- a/Samples/Primitives/Game1.cs +++ b/Samples/Primitives/Game1.cs @@ -23,11 +23,19 @@ namespace Primitives Texture2D bgTexture; BasicEffect basicEffect; + Effect hardwareInstanceEffect; + Matrix viewMatrix; Matrix projectionMatrix; + Matrix instancedProjectionMatrix; Matrix worldMatrix; + float rotation = 0.0f; + + DynamicVertexBuffer instanceVertexBuffer; VertexBuffer cubeNoIndicesBuffer; + VertexBuffer cubeVertexBuffer; + IndexBuffer cubeIndexBuffer; #region Corners of cube static Vector3 topLeftFront = new Vector3( -1.0f, 1.0f, 1.0f ); @@ -41,21 +49,90 @@ namespace Primitives #endregion - VertexPositionColor[] cubeNoIndices = new VertexPositionColor[] { new VertexPositionColor(topLeftFront, Color.White), - new VertexPositionColor(bottomRightFront, Color.White), - new VertexPositionColor(bottomLeftFront, Color.White), + Matrix[] instanceTransformMatrices = new Matrix[] { Matrix.CreateTranslation(0.0f, 0.0f, 0.0f), + Matrix.CreateTranslation(5.0f, 0.0f, 0.0f), + Matrix.CreateTranslation(10.0f, 0.0f, 0.0f), + }; - new VertexPositionColor(topLeftFront, Color.White), - new VertexPositionColor(topRightFront, Color.White), - new VertexPositionColor(bottomRightFront, Color.White), + VertexDeclaration instanceDecl = new VertexDeclaration + ( + new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 0), + new VertexElement(16, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 1), + new VertexElement(32, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 2), + new VertexElement(48, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 3) + ); - new VertexPositionColor(topLeftBack, Color.White), - new VertexPositionColor(bottomLeftBack, Color.White), - new VertexPositionColor(bottomRightBack, Color.White), + VertexPositionColor[] cubeVertices = new VertexPositionColor[] { new VertexPositionColor(topLeftFront, Color.White), + new VertexPositionColor(bottomLeftFront, Color.White), + new VertexPositionColor(topRightFront, Color.White), + new VertexPositionColor(bottomRightFront, Color.White), + new VertexPositionColor(topLeftBack, Color.White), + new VertexPositionColor(topRightBack, Color.White), + new VertexPositionColor(bottomLeftBack, Color.White), + new VertexPositionColor(bottomRightBack, Color.White) + }; + + short[] cubeIndices = new short[] { 0, 3, 1, + 0, 2, 3, + 4, 6, 7, + 4, 7, 5, + 0, 4, 2, + 2, 4, 5, + 1, 3, 6, + 3, 7, 6, + 0, 1, 6, + 6, 4, 0, + 2, 7, 3, + 7, 2, 5 }; + + VertexPositionColor[] cubeNoIndices = new VertexPositionColor[] { new VertexPositionColor(topLeftFront, Color.White), // 0 + new VertexPositionColor(bottomRightFront, Color.White), // 3 + new VertexPositionColor(bottomLeftFront, Color.White), // 1 + + new VertexPositionColor(topLeftFront, Color.White), // 0 + new VertexPositionColor(topRightFront, Color.White), // 2 + new VertexPositionColor(bottomRightFront, Color.White), // 3 + + new VertexPositionColor(topLeftBack, Color.White), // 4 + new VertexPositionColor(bottomLeftBack, Color.White), // 6 + new VertexPositionColor(bottomRightBack, Color.White), // 7 + + new VertexPositionColor(topLeftBack, Color.White), // 4 + new VertexPositionColor(bottomRightBack, Color.White), // 7 + new VertexPositionColor(topRightBack, Color.White), // 5 + + new VertexPositionColor(topLeftFront, Color.White), // 0 + new VertexPositionColor(topLeftBack, Color.White), // 4 + new VertexPositionColor(topRightFront, Color.White), // 2 + + new VertexPositionColor(topRightFront, Color.White), // 2 + new VertexPositionColor(topLeftBack, Color.White), // 4 + new VertexPositionColor(topRightBack, Color.White), // 5 + + new VertexPositionColor(bottomLeftFront, Color.White), // 1 + new VertexPositionColor(bottomRightFront, Color.White), // 3 + new VertexPositionColor(bottomLeftBack, Color.White), // 6 + + new VertexPositionColor(bottomRightFront, Color.White), // 3 + new VertexPositionColor(bottomRightBack, Color.White), // 7 + new VertexPositionColor(bottomLeftBack, Color.White), // 6 + + new VertexPositionColor(topLeftFront, Color.White), // 0 + new VertexPositionColor(bottomLeftFront, Color.White), // 1 + new VertexPositionColor(bottomLeftBack, Color.White), // 6 + + new VertexPositionColor(bottomLeftBack, Color.White), // 6 + new VertexPositionColor(topLeftBack, Color.White), // 4 + new VertexPositionColor(topLeftFront, Color.White), // 0 + + new VertexPositionColor(topRightFront, Color.White), // 2 + new VertexPositionColor(bottomRightBack, Color.White), // 7 + new VertexPositionColor(bottomRightFront, Color.White), // 3 + + new VertexPositionColor(bottomRightBack, Color.White), // 7 + new VertexPositionColor(topRightFront, Color.White), // 2 + new VertexPositionColor(topRightBack, Color.White), // 5 - new VertexPositionColor(topLeftBack, Color.White), - new VertexPositionColor(bottomRightBack, Color.White), - new VertexPositionColor(topRightBack, Color.White) }; public Game1() @@ -82,9 +159,11 @@ namespace Primitives spriteBatch = new SpriteBatch(GraphicsDevice); this.basicEffect = new BasicEffect(GraphicsDevice); - + this.hardwareInstanceEffect = Content.Load(@"Effects/HardwareInstancing"); + this.worldMatrix = Matrix.Identity; - this.projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 0.1f, 10.0f); + this.projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 300f/200f, 0.1f, 50.0f); + this.instancedProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 600f / 200f, 0.1f, 50.0f); this.viewMatrix = Matrix.CreateLookAt(new Vector3(5, 5, 5), new Vector3(0, 0, 0), Vector3.Up); this.font = Content.Load(@"Fonts/Debug"); @@ -98,6 +177,20 @@ namespace Primitives this.cubeNoIndicesBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), cubeNoIndices.Length, BufferUsage.None); this.cubeNoIndicesBuffer.SetData(cubeNoIndices); + + // + // create a Vertex- and IndexBuffer for a cube with indexed primitives + // + this.cubeVertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), cubeVertices.Length, BufferUsage.None); + this.cubeVertexBuffer.SetData(cubeVertices); + + this.cubeIndexBuffer = new IndexBuffer(GraphicsDevice, typeof(short), this.cubeIndices.Length, BufferUsage.None); + this.cubeIndexBuffer.SetData(this.cubeIndices); + + // + // create a VertexBuffer for the transformation matrices used by DrawInstancedPrimitives + // + this.instanceVertexBuffer = new DynamicVertexBuffer(GraphicsDevice, instanceDecl, 3, BufferUsage.WriteOnly); } protected override void UnloadContent() @@ -111,6 +204,9 @@ namespace Primitives Keyboard.GetState().IsKeyDown(Keys.Escape)) this.Exit(); + rotation += 1.0f * (float)gameTime.ElapsedGameTime.TotalSeconds; + + this.worldMatrix = Matrix.CreateRotationY(rotation); base.Update(gameTime); } @@ -118,6 +214,7 @@ namespace Primitives protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); + this.GraphicsDevice.Viewport = new Viewport(0, 0, 600, 600); spriteBatch.Begin(); @@ -135,17 +232,63 @@ namespace Primitives spriteBatch.End(); - this.GraphicsDevice.RasterizerState = new RasterizerState() { CullMode = CullMode.None, FillMode = FillMode.WireFrame }; + this.GraphicsDevice.RasterizerState = new RasterizerState() { CullMode = CullMode.CullCounterClockwiseFace, FillMode = FillMode.WireFrame }; - this.basicEffect.World = this.worldMatrix; + this.basicEffect.VertexColorEnabled = true; this.basicEffect.View = this.viewMatrix; + this.basicEffect.World = this.worldMatrix; this.basicEffect.Projection = this.projectionMatrix; this.basicEffect.CurrentTechnique.Passes[0].Apply(); + + #region DrawPrimitives + GraphicsDevice.Viewport = new Viewport(0, 200, 300, 200); + GraphicsDevice.SetVertexBuffer(this.cubeNoIndicesBuffer); GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, cubeNoIndices.Length / 3); + #endregion // DrawPrimitives + + #region DrawIndexedPrimitives + GraphicsDevice.Viewport = new Viewport(300, 200, 300, 200); + + GraphicsDevice.SetVertexBuffer(this.cubeVertexBuffer); + GraphicsDevice.Indices = this.cubeIndexBuffer; + GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, cubeVertices.Length, 0, cubeNoIndices.Length / 3); + + #endregion + + #region DrawUserPrimitives + GraphicsDevice.Viewport = new Viewport(0, 400, 300, 200); + + GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, this.cubeNoIndices, 0, this.cubeNoIndices.Length / 3); + + #endregion + + #region DrawUserIndexedPrimitives + GraphicsDevice.Viewport = new Viewport(300, 400, 300, 200); + + GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, this.cubeVertices, 0, this.cubeVertices.Length, this.cubeIndices, 0, this.cubeIndices.Length / 3); + + #endregion + + #region DrawInstancedPrimitives + GraphicsDevice.Viewport = new Viewport(0, 0, 600, 200); + + this.hardwareInstanceEffect.Parameters["View"].SetValue(this.viewMatrix); + this.hardwareInstanceEffect.Parameters["Projection"].SetValue(this.instancedProjectionMatrix); + this.hardwareInstanceEffect.Parameters["World"].SetValue(this.worldMatrix); + this.hardwareInstanceEffect.CurrentTechnique.Passes[0].Apply(); + + instanceVertexBuffer.SetData(this.instanceTransformMatrices, 0, this.instanceTransformMatrices.Length, SetDataOptions.Discard); + GraphicsDevice.SetVertexBuffers(cubeVertexBuffer, new VertexBufferBinding(instanceVertexBuffer, 0, 1)); + GraphicsDevice.Indices = this.cubeIndexBuffer; + GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, this.cubeVertices.Length, 0, this.cubeIndices.Length / 3, 3); + + #endregion + base.Draw(gameTime); + } private void DrawShadowText(SpriteBatch spriteBatch, SpriteFont font, String text, Vector2 position, Color foreground, Color shadow) diff --git a/Samples/SampleContent/Effects/HardwareInstancing.fx b/Samples/SampleContent/Effects/HardwareInstancing.fx new file mode 100644 index 00000000..09e49712 --- /dev/null +++ b/Samples/SampleContent/Effects/HardwareInstancing.fx @@ -0,0 +1,54 @@ +float4x4 World; +float4x4 View; +float4x4 Projection; + +struct VertexShaderInput +{ + float4 Position : POSITION0; + float4 Color : COLOR0; +}; + +struct VertexShaderOutput +{ + float4 Position : POSITION0; + float4 Color : COLOR0; +}; + +VertexShaderOutput HardwareInstancingVertexShader(VertexShaderInput input, float4x4 instanceTransform : BLENDWEIGHT) +{ + VertexShaderOutput output; + + // Apply the world and camera matrices to compute the output position. + float4 worldPosition = mul(input.Position, instanceTransform); + float4 viewPosition = mul(worldPosition, View); + output.Position = mul(viewPosition, Projection); + + output.Color = input.Color; + + return output; +} + +float4 PixelShaderFunction(VertexShaderOutput input) : SV_Target +{ + return input.Color; +} + +/* +technique10 HardwareInstancing +{ + pass Pass1 + { + VertexShader = compile vs_4_0 HardwareInstancingVertexShader(); + PixelShader = compile ps_4_0 PixelShaderFunction(); + } +} +*/ + +technique HardwareInstancing +{ + pass Pass1 + { + VertexShader = compile vs_2_0 HardwareInstancingVertexShader(); + PixelShader = compile ps_2_0 PixelShaderFunction(); + } +} \ No newline at end of file diff --git a/Samples/SampleContent/SampleContent.contentproj b/Samples/SampleContent/SampleContent.contentproj index 01e50eb5..c5464156 100644 --- a/Samples/SampleContent/SampleContent.contentproj +++ b/Samples/SampleContent/SampleContent.contentproj @@ -96,7 +96,13 @@ TextureProcessor - + + + HardwareInstancing + EffectImporter + EffectProcessor + + Cube