public void Shader(string effectName) { PrepareFrameCapture(); var spriteBatch = new SpriteBatch(gd); var effect = AssetTestUtility.LoadEffect(content, effectName); // A background texture to test that the effect doesn't // mess up other textures var background = content.Load <Texture2D>(Paths.Texture("fun-background")); // The texture to apply the effect to var surge = content.Load <Texture2D>(Paths.Texture("Surge")); spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend); spriteBatch.Draw(background, Vector2.Zero, Color.White); effect.CurrentTechnique.Passes[0].Apply(); spriteBatch.Draw( surge, new Vector2(300, 200), null, Color.White, 0f, Vector2.Zero, 2.0f, SpriteEffects.None, 0f); spriteBatch.End(); CheckFrames(); spriteBatch.Dispose(); effect.Dispose(); background.Dispose(); surge.Dispose(); }
public void TextureArrayAsRenderTargetAndShaderResource() { PrepareFrameCapture(); var solidColorTexture = new Texture2D(gd, 1, 1); solidColorTexture.SetData(new[] { Color.White }); const int arraySize = 4; // Create texture array. var textureArray = new RenderTarget2D(gd, 1, 1, false, SurfaceFormat.Color, DepthFormat.None, 1, RenderTargetUsage.PlatformContents, false, arraySize); var colors = new[] { Color.Red, Color.Green, Color.Blue, Color.Yellow }; var originalRenderTargets = gd.GetRenderTargets(); // Bind each slice of texture array as render target, and render (different) solid color to each slice. var spriteBatch = new SpriteBatch(gd); for (var i = 0; i < arraySize; i++) { gd.SetRenderTarget(textureArray, i); spriteBatch.Begin(); spriteBatch.Draw(solidColorTexture, gd.Viewport.Bounds, colors[i]); spriteBatch.End(); } // Unbind texture array. gd.SetRenderTargets(originalRenderTargets); // Now render into backbuffer, using texture array as a shader resource. var effect = AssetTestUtility.LoadEffect(content, "TextureArrayEffect"); effect.Parameters["Texture"].SetValue(textureArray); effect.CurrentTechnique.Passes[0].Apply(); gd.SamplerStates[0] = SamplerState.LinearClamp; // Vertex buffer is not actually used, but currently we need to set a // vertex buffer before calling DrawPrimitives. var vb = new VertexBuffer(gd, typeof(VertexPositionColor), 3, BufferUsage.WriteOnly); gd.SetVertexBuffer(vb); gd.DrawPrimitives(PrimitiveType.TriangleList, 0, 1); CheckFrames(); solidColorTexture.Dispose(); spriteBatch.Dispose(); textureArray.Dispose(); effect.Dispose(); vb.Dispose(); }
public void DrawInstancedPrimitivesParameterValidation() { var vertexBuffer = new VertexBuffer( gd, VertexPositionColorTexture.VertexDeclaration, 3, BufferUsage.None); VertexDeclaration instanceVertexDeclaration = 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) ); var instanceBuffer = new VertexBuffer( gd, instanceVertexDeclaration, 10, BufferUsage.None); var indexBuffer = new IndexBuffer(gd, IndexElementSize.SixteenBits, 3, BufferUsage.None); // No vertex shader or pixel shader. Assert.Throws <InvalidOperationException>(() => gd.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 3, 0, 1, 10)); var effect = AssetTestUtility.LoadEffect(content, "Instancing"); effect.Techniques[0].Passes[0].Apply(); // No vertexBuffers. Assert.Throws <InvalidOperationException>(() => gd.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 3, 0, 1, 10)); gd.SetVertexBuffers( new VertexBufferBinding(vertexBuffer, 0, 0), new VertexBufferBinding(instanceBuffer, 0, 1)); // No indexBuffer. Assert.Throws <InvalidOperationException>(() => gd.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 3, 0, 1, 10)); gd.Indices = indexBuffer; // Success - "normal" usage. Assert.DoesNotThrow(() => gd.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 3, 0, 1, 10)); // primitiveCount too small / large. Assert.Throws <ArgumentOutOfRangeException>(() => gd.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 3, 0, 0, 10)); effect.Dispose(); vertexBuffer.Dispose(); instanceBuffer.Dispose(); indexBuffer.Dispose(); }
public void DrawWithCustomEffectAndTwoTextures() { var customSpriteEffect = AssetTestUtility.LoadEffect(content, "CustomSpriteBatchEffect"); var texture2 = new Texture2D(gd, 1, 1, false, SurfaceFormat.Color); customSpriteEffect.Parameters["SourceTexture"].SetValue(texture2); customSpriteEffect.Parameters["OtherTexture"].SetValue(texture2); _spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, null, null, null, customSpriteEffect); _spriteBatch.Draw(_texture, new Vector2(20, 20), Color.White); _spriteBatch.End(); Assert.That(gd.Textures[0], Is.SameAs(_texture)); Assert.That(gd.Textures[1], Is.SameAs(texture2)); customSpriteEffect.Dispose(); texture2.Dispose(); }
public void DrawWithCustomEffectAndTwoTextures() { Game.DrawWith += (sender, e) => { var customSpriteEffect = AssetTestUtility.CompileEffect(Game.GraphicsDevice, "CustomSpriteBatchEffect.fx"); var texture2 = new Texture2D(Game.GraphicsDevice, 1, 1, false, SurfaceFormat.Color); customSpriteEffect.Parameters["SourceTexture"].SetValue(texture2); customSpriteEffect.Parameters["OtherTexture"].SetValue(texture2); _spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, null, null, null, customSpriteEffect); _spriteBatch.Draw(_texture, new Vector2(20, 20), Color.White); _spriteBatch.End(); Assert.That(Game.GraphicsDevice.Textures[0], Is.SameAs(_texture)); Assert.That(Game.GraphicsDevice.Textures[1], Is.SameAs(texture2)); }; Game.Run(); }
public void VisualTestComparisonFunction() { var compares = new[] { CompareFunction.Always, CompareFunction.Equal, CompareFunction.Greater, CompareFunction.GreaterEqual, CompareFunction.Less, CompareFunction.LessEqual, CompareFunction.Never, CompareFunction.NotEqual }; SpriteBatch spriteBatch = null; Texture2D texture = null; SamplerState[] samplerStates = null; Effect customEffect = null; Game.LoadContentWith += (sender, e) => { spriteBatch = new SpriteBatch(Game.GraphicsDevice); // Texture contains a horizontal gradient [0..1]. // In the shader, we compare samples from this texture to a hardcoded "0.5" value, // and run the test once for each comparison function. texture = new Texture2D(Game.GraphicsDevice, 16, 1, false, SurfaceFormat.Single); var textureData = new float[texture.Width]; for (var x = 0; x < texture.Width; x++) { textureData[x] = x / (float)texture.Width; } texture.SetData(textureData); samplerStates = new SamplerState[compares.Length]; for (var i = 0; i < compares.Length; i++) { samplerStates[i] = new SamplerState { AddressU = TextureAddressMode.Clamp, AddressV = TextureAddressMode.Clamp, AddressW = TextureAddressMode.Clamp, ComparisonFunction = compares[i] } } ; customEffect = AssetTestUtility.CompileEffect(Game.GraphicsDevice, "CustomSpriteBatchEffectComparisonSampler.fx"); }; Game.DrawWith += (sender, e) => { var size = new Vector2(100, 100); var offset = new Vector2(10, 10); Game.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1.0f, 0); for (var i = 0; i < compares.Length; i++) { var x = i % 4; var y = (i > 3) ? 1 : 0; var pos = offset + new Vector2(x * size.X, y * size.Y); spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: samplerStates[i], effect: customEffect); spriteBatch.Draw(texture, new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y), Color.White); spriteBatch.End(); } }; RunSingleFrameTest(); } #endif }
public void VisualTestComparisonFunction() { PrepareFrameCapture(); var compares = new[] { CompareFunction.Always, CompareFunction.Equal, CompareFunction.Greater, CompareFunction.GreaterEqual, CompareFunction.Less, CompareFunction.LessEqual, CompareFunction.Never, CompareFunction.NotEqual }; var spriteBatch = new SpriteBatch(gd); // Texture contains a horizontal gradient [0..1]. // In the shader, we compare samples from this texture to a hardcoded "0.5" value, // and run the test once for each comparison function. var texture = new Texture2D(gd, 16, 1, false, SurfaceFormat.Single); var textureData = new float[texture.Width]; for (var x = 0; x < texture.Width; x++) { textureData[x] = x / (float)texture.Width; } texture.SetData(textureData); var samplerStates = new SamplerState[compares.Length]; for (var i = 0; i < compares.Length; i++) { samplerStates[i] = new SamplerState { AddressU = TextureAddressMode.Clamp, AddressV = TextureAddressMode.Clamp, AddressW = TextureAddressMode.Clamp, ComparisonFunction = compares[i], FilterMode = TextureFilterMode.Comparison } } ; var customEffect = AssetTestUtility.LoadEffect(content, "CustomSpriteBatchEffectComparisonSampler"); var size = new Vector2(100, 100); var offset = new Vector2(10, 10); gd.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1.0f, 0); for (var i = 0; i < compares.Length; i++) { var x = i % 4; var y = (i > 3) ? 1 : 0; var pos = offset + new Vector2(x * size.X, y * size.Y); spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: samplerStates[i], effect: customEffect); spriteBatch.Draw(texture, new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y), Color.White); spriteBatch.End(); } CheckFrames(); spriteBatch.Dispose(); texture.Dispose(); customEffect.Dispose(); foreach (var state in samplerStates) { state.Dispose(); } } #endif }
public void VertexTextureVisualTest() { // Implements an extremely simple terrain that reads from a heightmap in the vertex shader. Game.DrawWith += (sender, e) => { const int heightMapSize = 64; var heightMapTexture = new Texture2D(Game.GraphicsDevice, heightMapSize, heightMapSize, false, SurfaceFormat.Single); var heightMapData = new float[heightMapSize * heightMapSize]; for (var y = 0; y < heightMapSize; y++) { for (var x = 0; x < heightMapSize; x++) { heightMapData[(y * heightMapSize) + x] = (float)Math.Sin(x / 2.0f) + (float)Math.Sin(y / 3.0f); } } heightMapTexture.SetData(heightMapData); var viewMatrix = Matrix.CreateLookAt(new Vector3(32, 10, 60), new Vector3(32, 0, 30), Vector3.Up); var projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Game.GraphicsDevice.Viewport.AspectRatio, 1.0f, 100.0f); var effect = AssetTestUtility.CompileEffect(Game.GraphicsDevice, "VertexTextureEffect.fx"); effect.Parameters["WorldViewProj"].SetValue(viewMatrix * projectionMatrix); effect.Parameters["HeightMapTexture"].SetValue(heightMapTexture); effect.Parameters["HeightMapSize"].SetValue((float)heightMapSize); effect.CurrentTechnique.Passes[0].Apply(); const int numVertices = heightMapSize * heightMapSize; var vertexBuffer = new VertexBuffer(Game.GraphicsDevice, typeof(VertexPosition2), numVertices, BufferUsage.WriteOnly); var vertices = new VertexPosition2[numVertices]; for (var y = 0; y < heightMapSize; y++) { for (var x = 0; x < heightMapSize; x++) { vertices[(y * heightMapSize) + x] = new VertexPosition2 { Position = new Vector2(x, y) } } } ; vertexBuffer.SetData(vertices); Game.GraphicsDevice.SetVertexBuffer(vertexBuffer); const int numIndices = (heightMapSize - 1) * (heightMapSize - 1) * 2 * 3; var indexBuffer = new IndexBuffer(Game.GraphicsDevice, IndexElementSize.SixteenBits, numIndices, BufferUsage.WriteOnly); var indexData = new short[numIndices]; var indexIndex = 0; for (short y = 0; y < heightMapSize - 1; y++) { for (short x = 0; x < heightMapSize - 1; x++) { var baseIndex = (short)((y * heightMapSize) + x); indexData[indexIndex++] = baseIndex; indexData[indexIndex++] = (short)(baseIndex + heightMapSize); indexData[indexIndex++] = (short)(baseIndex + 1); indexData[indexIndex++] = (short)(baseIndex + 1); indexData[indexIndex++] = (short)(baseIndex + heightMapSize); indexData[indexIndex++] = (short)(baseIndex + heightMapSize + 1); } } indexBuffer.SetData(indexData); Game.GraphicsDevice.Indices = indexBuffer; Game.GraphicsDevice.RasterizerState = RasterizerState.CullNone; Game.GraphicsDevice.Clear(Color.CornflowerBlue); Game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numVertices, 0, numIndices / 3); }; RunSingleFrameTest(); }
public void DrawInstancedPrimitivesVisualTest() { VertexBuffer vertexBuffer = null; IndexBuffer indexBuffer = null; VertexBuffer instanceVertexBuffer = null; Matrix[] worldTransforms = null; EffectPass pass = null; Game.LoadContentWith += (sender, e) => { // Create vertex and index buffer for a quad. var vertices = new[] { new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0)), new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0)), new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1)), new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1)), }; vertexBuffer = new VertexBuffer( Game.GraphicsDevice, VertexPositionTexture.VertexDeclaration, 4, BufferUsage.None); vertexBuffer.SetData(vertices); var indices = new ushort[] { 0, 1, 2, 1, 3, 2 }; indexBuffer = new IndexBuffer(Game.GraphicsDevice, IndexElementSize.SixteenBits, 6, BufferUsage.None); indexBuffer.SetData(indices); // Create vertex buffer with instance data. worldTransforms = new Matrix[8 * 4]; for (int i = 0; i < worldTransforms.Length; i++) { worldTransforms[i] = Matrix.CreateScale(0.4f) * Matrix.CreateRotationZ(0.05f * i) * Matrix.CreateTranslation(-3.5f + (i % 8), -1.5f + (int)(i / 8), 0); } VertexDeclaration instanceVertexDeclaration = 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) ); instanceVertexBuffer = new VertexBuffer(Game.GraphicsDevice, instanceVertexDeclaration, worldTransforms.Length, BufferUsage.None); instanceVertexBuffer.SetData(worldTransforms); var view = Matrix.CreateLookAt(new Vector3(0, 0, 6), new Vector3(0, 0, 0), Vector3.Up); var projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver4, Game.GraphicsDevice.Viewport.AspectRatio, 0.1f, 100); var effect = AssetTestUtility.CompileEffect(Game.GraphicsDevice, "Instancing.fx"); effect.Parameters["View"].SetValue(view); effect.Parameters["Projection"].SetValue(projection); pass = effect.Techniques[0].Passes[0]; }; Game.DrawWith += (sender, e) => { Game.GraphicsDevice.Clear(Color.CornflowerBlue); Game.GraphicsDevice.SetVertexBuffers( new VertexBufferBinding(vertexBuffer, 0, 0), new VertexBufferBinding(instanceVertexBuffer, 0, 1)); Game.GraphicsDevice.Indices = indexBuffer; pass.Apply(); Game.GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 6, 0, 2, worldTransforms.Length); }; //Game.Run(until: frameInfo => false); // There is a minor difference in the rasterization between XNA and DirectX. var similarity = 0.98f; RunSingleFrameTest(similarity); }