Ejemplo n.º 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();
        }
Ejemplo n.º 2
0
        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();
        }
Ejemplo n.º 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();
        }
Ejemplo n.º 5
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
    }
Ejemplo n.º 6
0
        public void VertexTextureVisualTest()
        {
            // Implements an extremely simple terrain that reads from a heightmap in the vertex shader.
            PrepareFrameCapture();

            const int heightMapSize    = 64;
            var       heightMapTexture = new Texture2D(gd, 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,
                                                                       gd.Viewport.AspectRatio, 1.0f, 100.0f);

            var effect = AssetTestUtility.LoadEffect(content, "VertexTextureEffect");

            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(gd, 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);
            gd.SetVertexBuffer(vertexBuffer);

            const int numIndices  = (heightMapSize - 1) * (heightMapSize - 1) * 2 * 3;
            var       indexBuffer = new IndexBuffer(gd, 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);
            gd.Indices = indexBuffer;

            gd.RasterizerState = RasterizerState.CullNone;

            gd.Clear(Color.CornflowerBlue);

            gd.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                                     0, 0, numVertices, 0, numIndices / 3);

            CheckFrames();

            effect.Dispose();
            vertexBuffer.Dispose();
            indexBuffer.Dispose();
        }
Ejemplo n.º 7
0
        public void DrawInstancedPrimitivesVisualTest()
        {
            VertexBuffer vertexBuffer         = null;
            IndexBuffer  indexBuffer          = null;
            VertexBuffer instanceVertexBuffer = null;

            Matrix[]   worldTransforms = null;
            EffectPass pass            = null;

            // 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(
                gd, VertexPositionTexture.VertexDeclaration,
                4, BufferUsage.None);
            vertexBuffer.SetData(vertices);

            var indices = new ushort[] { 0, 1, 2, 1, 3, 2 };

            indexBuffer = new IndexBuffer(gd, 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(gd, 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, gd.Viewport.AspectRatio, 0.1f, 100);

            var effect = AssetTestUtility.LoadEffect(content, "Instancing");

            effect.Parameters["View"].SetValue(view);
            effect.Parameters["Projection"].SetValue(projection);
            pass = effect.Techniques[0].Passes[0];

            PrepareFrameCapture();

            gd.Clear(Color.CornflowerBlue);

            gd.SetVertexBuffers(
                new VertexBufferBinding(vertexBuffer, 0, 0),
                new VertexBufferBinding(instanceVertexBuffer, 0, 1));

            gd.Indices = indexBuffer;

            pass.Apply();

            gd.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 6, 0, 2, worldTransforms.Length);

            // There is a minor difference in the rasterization between XNA and DirectX.
            Similarity = 0.98f;

            CheckFrames();

            effect.Dispose();
            vertexBuffer.Dispose();
            instanceVertexBuffer.Dispose();
            indexBuffer.Dispose();
        }