Exemple #1
0
        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();
        }
Exemple #3
0
        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();
        }
Exemple #5
0
        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();
        }
Exemple #6
0
        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
    }
Exemple #7
0
        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);
        }