Custom vertices not drawing

Hi.
I’m trying to implement this Tilemap renderer with the tile fx being declared as follows:

#if OPENGL
    #define SV_POSITION POSITION
    #define VS_SHADERMODEL vs_3_0
    #define PS_SHADERMODEL ps_3_0
#else
    #define VS_SHADERMODEL vs_4_0_level_9_1
    #define PS_SHADERMODEL ps_4_0_level_9_1
#endif

matrix World;
matrix View;
matrix Projection;

int InputTextureCount;
Texture2D InputTexture[4];

float AlphaGrayScale;
float4 InputColour;
float4 ShadowColour;
int InputFilter;
float InputFilterAmount;

float4 InputClipRectangle;

sampler FirstTextureSampler = sampler_state
{
    Texture = <InputTexture0>;
};

sampler SecondTextureSampler = sampler_state
{
    Texture = <InputTexture1>;
};

sampler ThirdTextureSampler = sampler_state
{
    Texture = <InputTexture2>;
};

sampler FourthTextureSampler = sampler_state
{
    Texture = <InputTexture3>;
};

struct VertexShaderInput
{
    float4 VertexPosition : POSITION0;
    float4 Color : COLOR0;
    float2 VertexTextureMapping : TEXCOORD0;
    float VertexTextureIndex : TEXCOORD1;
    float VertexOpacity : TEXCOORD2;
};

struct VertexShaderOutput
{
    float4 Position : SV_POSITION;
    float4 Color : COLOR0;
    float2 FragmentTextureMapping : TEXCOORD0;
    float2 FragmentPosition : TEXCOORD1;
    float FragmentTextureIndex : TEXCOORD2;
    float FragmentOpacity : TEXCOORD3;

};

struct PixelShaderOutput
{
    float4 Color : COLOR0;
};

VertexShaderOutput MainVS(in VertexShaderInput input)
{
    VertexShaderOutput output;

    float4x4 wvp = mul(World, mul(View, Projection));

    output.Position = mul(input.VertexPosition, wvp); // Transform by WorldViewProjection
    output.Color = input.Color;
    output.FragmentTextureMapping = input.VertexTextureMapping;
    output.FragmentPosition = mul(input.VertexPosition, World).xy;
    output.FragmentTextureIndex = input.VertexTextureIndex;
    output.FragmentOpacity = input.VertexOpacity;
    return output;
}


float4 applyNightFilter(in float4 colour, in float amount)
{
    float redGreenAmount = 0.5;
    float desaturateAmount = 0.5;
    float lightness = 0.8;
    
    // Get luma value
    float luma = (colour.r * 0.21) + (colour.g * 0.71) + (colour.b * 0.07);
 
    // Darken slightly
    luma = luma * lightness;
 
    // Desaturate
    float4 result = float4(
        lerp(colour.rgb, float3(luma, luma, luma), desaturateAmount),
        colour.a
    );

    float3 blueTint = result.rgb;
    blueTint.r *= redGreenAmount * 0.21;
    blueTint.g *= redGreenAmount * 0.71;

    float mixAmount = amount;
    result.rgb = lerp(result.rgb, blueTint.rgb, mixAmount);

    // Transition between original colour and night colour
    result.rgb = lerp(colour.rgb, result.rgb, amount);
    return result;
}

float4 applyDarkFilter(in float4 colour, in float amount)
{    
    float desaturateAmount = 0.5;
    float lightness = 0;
    // Get luma value
    float luma = (colour.r * 0.21) + (colour.g * 0.71) + (colour.b * 0.07);
 
    // Darken slightly
    luma = luma * lightness;
 
    // Desaturate
    float4 result = float4(
        lerp(colour.rgb, float3(luma, luma, luma), desaturateAmount),
        colour.a
    );

    // Transition between original colour and night colour
    return float4(lerp(colour.rgb, result.rgb, amount), 1.0);
}

float4 applyFilter(in float4 colour, in int filterType, in float amount)
{
    if(filterType == 1) {
        return applyNightFilter(colour, amount);
    }
    else if(filterType == 2){
        return applyDarkFilter(colour, amount);
    }
    else{
        return colour;
    }
}

PixelShaderOutput MainPS(VertexShaderOutput input) 
{

    if (input.FragmentPosition.x < InputClipRectangle.x || input.FragmentPosition.y < InputClipRectangle.y ||
        input.FragmentPosition.x >= InputClipRectangle.z || input.FragmentPosition.y >= InputClipRectangle.w
    ) {
        discard;
    }


    PixelShaderOutput output;

    float4 TextureColour = float4(1.0, 1.0, 1.0, 1.0);

    float4 texel;
    if(input.FragmentTextureIndex == 0) {
        texel = tex2D(FirstTextureSampler, input.FragmentTextureMapping.xy);
    }
    else if(input.FragmentTextureIndex == 1){
        texel = tex2D(SecondTextureSampler, input.FragmentTextureMapping.xy);

    }
    else if(input.FragmentTextureIndex == 2){
        texel = tex2D(ThirdTextureSampler, input.FragmentTextureMapping.xy);

    }
    else if(input.FragmentTextureIndex == 3){
        texel = tex2D(FourthTextureSampler, input.FragmentTextureMapping.xy);

    }
    else{
        texel = float4(1.0, 1.0, 1.0, 1.0);

    }

    TextureColour = texel;
    TextureColour = (input.Color * TextureColour);

    float4 result = applyFilter(texel * InputColour, InputFilter, InputFilterAmount);
    result.a *= input.FragmentOpacity;

    if (AlphaGrayScale == 0.0) {
        output.Color = result;
    } else {
        output.Color = result * (1 - AlphaGrayScale) + float4(0+ShadowColour.r, 0 + ShadowColour.g, 0 + ShadowColour.b, result.a* ShadowColour.a ) * AlphaGrayScale;
        if (output.Color.a < 0.01)
            discard;
    }

    if (output.Color.a < 0.001)
        discard;

    return output;
}

technique BasicColorDrawing
{
    pass P0
    {
        VertexShader = compile VS_SHADERMODEL MainVS();
        PixelShader = compile PS_SHADERMODEL MainPS();
    }
};

And the tile renderer class looking like so:

    public sealed class TileRenderer : ITileRenderer
    {
        private const int MaxTextures = 4;

        /*private static readonly Dictionary<Renderer, TileRenderer> RendererDictionary =
            new Dictionary<Renderer, TileRenderer>();*/

        public static Colour ShadowColour;
        private readonly IGraphicsContext _graphicsContext;

        private TileBlendMode _tempLastBlendMode;

        //private readonly List<Vertex> _vertices = new List<Vertex>();
        private const int VerticesArrayLength = 256;
        private static Vertex[] _vertices = new Vertex[VerticesArrayLength];
        public int NumVertices;
        private static readonly Vector2[] VertexPositions = new Vector2[4];
        private static readonly Vector2[] VertexUVs = new Vector2[4];

        private Effect _effect;

        public TileRenderer(ContentManager content, IGraphicsContext graphicsContext)
        {

            _graphicsContext = graphicsContext;

            _effect = content.Load<Effect>("shaders/tile");

            // Set defaults
            ModelMatrix = Matrix4.Identity;
            Colour = Colours.White;
            ClipRectangle = new Rectangle(0, 0, 1920, 1080);
        }

        public Colour Colour { get; set; }

        // Input options
        public Matrix4 ModelMatrix { get; set; }
        public ITexture[] Textures { get; set; }
        public Rectangle ClipRectangle { get; set; }

        public int Filter { get; set; }
        public double FilterAmount { get; set; }

        public bool Rendering { get; private set; }

        public int NumTiles { get; private set; }

        public void Dispose()
        {
        }

        public void Deactivate() { }

        public void BeginRender()
        {
            if(Rendering)
                throw new InvalidOperationException("Already renderering.");
            Rendering = true;

            NumTiles = 0;
            NumVertices = 0;
        }

        public void AddTile(
            Rectanglei source,
            Rectanglei destination,
            int textureIndex,
            bool flipX = false,
            bool flipY = false,
            float opacity = 1.0f,
            TileBlendMode blend = TileBlendMode.Alpha
        )
        {
            if(!Rendering)
                throw new Exception("Not currently renderering");

            var texture = Textures[textureIndex];

        // Add the vertices
        // Renderer.GetVertices(destination, VertexPositions);
        Array.Copy(destination.Vertices, 0, VertexPositions, 0, 4);
            Renderer.GetTextureMappings(texture, source, VertexUVs, flipX, flipY);
            for(var i = 0; i < 4; i++)
            {
                _vertices[NumVertices].VertexPosition.X = (float) VertexPositions[i].X;
                _vertices[NumVertices].VertexPosition.Y = (float) VertexPositions[i].Y;
                _vertices[NumVertices].VertexTextureMapping.X = (float) VertexUVs[i].X;
                _vertices[NumVertices].VertexTextureMapping.Y = (float) VertexUVs[i].Y;
                _vertices[NumVertices].VertexTextureIndex = textureIndex;
                _vertices[NumVertices].VertexOpacity = opacity;

                NumVertices++;

                if(NumVertices >= _vertices.Length)
                {
                    var tempVertex = new Vertex[_vertices.Length + VerticesArrayLength];
                    Array.Copy(_vertices, tempVertex, _vertices.Length);
                    _vertices = tempVertex;
                }
            }

            NumTiles++;

            _tempLastBlendMode = blend;
        }

        public void SetUpEffect()
        {
            var graphicsContext = _graphicsContext;
            var graphics = (graphicsContext as MonoGameGraphicsContext);

            var GraphicsDevice = graphics.WindowContext.Graphics.GraphicsDevice;

            var viewport = GraphicsDevice.Viewport;

            //var World = SimpleRenderer._modelMatrix;

            var ortho = ModelMatrix;
            var World = new Microsoft.Xna.Framework.Matrix(
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row1.X, (float)ortho.Row1.Y, (float)ortho.Row1.Z, (float)ortho.Row1.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row2.X, (float)ortho.Row2.Y, (float)ortho.Row2.Z, (float)ortho.Row2.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row3.X, (float)ortho.Row3.Y, (float)ortho.Row3.Z, (float)ortho.Row3.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row4.X, (float)ortho.Row4.Y, (float)ortho.Row4.Z, (float)ortho.Row4.W));


            var View = Microsoft.Xna.Framework.Matrix.CreateLookAt(new Microsoft.Xna.Framework.Vector3(0, 0, -1), new Microsoft.Xna.Framework.Vector3(0, 0, 0), new Microsoft.Xna.Framework.Vector3(0, -1, 0));
            //var Projection2 = Microsoft.Xna.Framework.Matrix.CreateScale(1, -1, 1) * Microsoft.Xna.Framework.Matrix.CreateOrthographicOffCenter(0, 1920, 1080, 0, 0, 1); // nans

            ortho = _graphicsContext.CurrentFrameBuffer.CreateOrthographic() * Matrix4.CreateScale(1, -1, 1);
            var Projection = new Microsoft.Xna.Framework.Matrix(
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row1.X, (float)ortho.Row1.Y, (float)ortho.Row1.Z, (float)ortho.Row1.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row2.X, (float)ortho.Row2.Y, (float)ortho.Row2.Z, (float)ortho.Row2.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row3.X, (float)ortho.Row3.Y, (float)ortho.Row3.Z, (float)ortho.Row3.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row4.X, (float)ortho.Row4.Y, (float)ortho.Row4.Z, (float)ortho.Row4.W));

            var wvp = World * View * Projection;

            _effect.Parameters["World"].SetValue(World);
            _effect.Parameters["View"].SetValue(View);
            _effect.Parameters["Projection"].SetValue(Projection);

            for (var i = 0; i < Textures.Length; i++)
            {
                var texture = (Textures[i] as MonoGameTexture).Texture;
                _effect.Parameters["InputTexture" + i.ToString()].SetValue(texture);
            }

            _effect.Parameters["AlphaGrayScale"].SetValue(ShadowRenderer.IsShadowing ? 1.0f : 0.0f);

            _effect.Parameters["InputColour"].SetValue(new Microsoft.Xna.Framework.Vector4(Colour.Red / 255.0f, Colour.Green / 255.0f, Colour.Blue / 255.0f, Colour.Alpha / 255.0f));
            _effect.Parameters["ShadowColour"].SetValue(new Microsoft.Xna.Framework.Vector4(ShadowColour.Red / 255.0f, ShadowColour.Green / 255.0f, ShadowColour.Blue / 255.0f, ShadowColour.Alpha / 255.0f));
            _effect.Parameters["InputFilter"].SetValue(Filter);
            _effect.Parameters["InputFilterAmount"].SetValue((float)FilterAmount);

            _effect.Parameters["InputClipRectangle"].SetValue(new Microsoft.Xna.Framework.Vector4((float)ClipRectangle.X, (float)ClipRectangle.Y, (float)ClipRectangle.Right, (float)ClipRectangle.Bottom));

            //_effect.Parameters["FragmentTextureIndex"].SetValue(_vertices[0].VertexTextureIndex);
            //_effect.Parameters["FragmentOpacity"].SetValue(_vertices[0].VertexOpacity);

            _effect.Parameters["InputFilter"].SetValue(Filter);

        }

        private void DrawQuad(Vertex[] destination)
        {
            var graphicsContext = _graphicsContext;
            var graphics = (graphicsContext as MonoGameGraphicsContext);
            var GraphicsDevice = graphics.WindowContext.Graphics.GraphicsDevice;

            Vertex[] quad = new Vertex[destination.Length];

            for (var i = 0; i < destination.Length; i++)
            {
                var color = Microsoft.Xna.Framework.Color.White;
                quad[i].Color = new Microsoft.Xna.Framework.Vector4(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A /255.0f);
            }

            short[] indices = new short[6];
            if (GraphicsDevice.RasterizerState == RasterizerState.CullClockwise)
            {
                indices[0] = 0; indices[1] = 1; indices[2] = 2;
                indices[3] = 2; indices[4] = 3; indices[5] = 0;
            }
            else
            {
                indices[0] = 0; indices[1] = 2; indices[2] = 1;
                indices[3] = 2; indices[4] = 0; indices[5] = 3;
            }

            var vb = new Microsoft.Xna.Framework.Graphics.VertexBuffer(GraphicsDevice, typeof(Vertex), quad.Length, BufferUsage.None);
            foreach (EffectPass pass in _effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                vb.SetData(quad);
                GraphicsDevice.SetVertexBuffer(vb);
                GraphicsDevice.DrawUserIndexedPrimitives(Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList, quad, 0, 4, indices, 0, 2, Vertex.VertexDeclaration);
            }
        }


        public void SetStates()
        {
            var graphicsContext = _graphicsContext;
            var graphics = (graphicsContext as MonoGameGraphicsContext);

            var GraphicsDevice = graphics.WindowContext.Graphics.GraphicsDevice;

            // Alpha blending
            graphics.BlendMode = _tempLastBlendMode == TileBlendMode.Additive ? BlendMode.Additive : BlendMode.Alpha;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap;
            GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
        }

        public void EndRender()
        {
            if(!Rendering)
                throw new Exception("Not currently renderering");

            SetStates();

            // Prepare textures
            foreach(var texture in Textures)
                texture.Filtering = TextureFiltering.NearestNeighbour;

            SetUpEffect();
            DrawQuad(_vertices);

            Rendering = false;
        }

        private struct Vertex : IVertexType
        {
            public Microsoft.Xna.Framework.Vector4 VertexPosition;

            public Microsoft.Xna.Framework.Vector4 Color;
            public Microsoft.Xna.Framework.Vector2 VertexTextureMapping;

            public float VertexTextureIndex;

            public float VertexOpacity;

            public readonly static VertexDeclaration VertexDeclaration =
              new VertexDeclaration(new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.Position, 0),
                                    new VertexElement(sizeof(float) * 4, VertexElementFormat.Vector4, VertexElementUsage.Color, 0),
                                    new VertexElement(sizeof(float) * 8, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
                                    new VertexElement(sizeof(float) * 10, VertexElementFormat.Single, VertexElementUsage.TextureCoordinate, 1),
                                    new VertexElement(sizeof(float) * 11, VertexElementFormat.Single, VertexElementUsage.TextureCoordinate, 2));
            VertexDeclaration IVertexType.VertexDeclaration
            {
                get { return Vertex.VertexDeclaration; }
            }

        }


    }

But no matter what I do the drawing calls render nothing, I tried using VertexPositionColorTexture and it works good for other effects/shaders, but I have to explicitly set the texture index for each set of vertices on this one.
I don’t know what is going on. I recently added the VertexBuffer to set the GraphicsDevice VertexBuffer but I’m not sure if it should go there,

I’m also concerned I’m not declaring correctly my vertex structure.

Thanks in advance!

In the end, the resulting class ended up like this:

    public sealed class TileRenderer : ITileRenderer
    {
        private const int MaxTextures = 4;

        /*private static readonly Dictionary<Renderer, TileRenderer> RendererDictionary =
            new Dictionary<Renderer, TileRenderer>();*/

        public static Colour ShadowColour;
        private readonly IGraphicsContext _graphicsContext;

        private TileBlendMode _tempLastBlendMode;

        //private readonly List<Vertex> _vertices = new List<Vertex>();
        private const int VerticesArrayLength = 256;
        private static Vertex[] _vertices = new Vertex[VerticesArrayLength];
        public int NumVertices;
        private static readonly Vector2[] VertexPositions = new Vector2[4];
        private static readonly Vector2[] VertexUVs = new Vector2[4];

        private Effect _effect;

        public TileRenderer(ContentManager content, IGraphicsContext graphicsContext)
        {

            _graphicsContext = graphicsContext;

            _effect = content.Load<Effect>("shaders/tile");

            // Set defaults
            ModelMatrix = Matrix4.Identity;
            Colour = Colours.White;
            ClipRectangle = new Rectangle(0, 0, 1920, 1080);
        }

        public Colour Colour { get; set; }

        // Input options
        public Matrix4 ModelMatrix { get; set; }
        public ITexture[] Textures { get; set; }
        public Rectangle ClipRectangle { get; set; }

        public int Filter { get; set; }
        public double FilterAmount { get; set; }

        public bool Rendering { get; private set; }

        public int NumTiles { get; private set; }

        public void Dispose()
        {
        }

        public void Deactivate() { }

        public void BeginRender()
        {
            if(Rendering)
                throw new InvalidOperationException("Already renderering.");
            Rendering = true;

            NumTiles = 0;
            NumVertices = 0;
        }

        public void AddTile(
            Rectanglei source,
            Rectanglei destination,
            int textureIndex,
            bool flipX = false,
            bool flipY = false,
            float opacity = 1.0f,
            TileBlendMode blend = TileBlendMode.Alpha
        )
        {
            if(!Rendering)
                throw new Exception("Not currently renderering");

            var texture = Textures[textureIndex];

        // Add the vertices
        // Renderer.GetVertices(destination, VertexPositions);
        Array.Copy(destination.Vertices, 0, VertexPositions, 0, 4);
            Renderer.GetTextureMappings(texture, source, VertexUVs, flipX, flipY);
            for(var i = 0; i < 4; i++)
            {
                _vertices[NumVertices].VertexPosition.X = (float) VertexPositions[i].X;
                _vertices[NumVertices].VertexPosition.Y = (float) VertexPositions[i].Y;
                _vertices[NumVertices].VertexTextureMapping.X = (float) VertexUVs[i].X;
                _vertices[NumVertices].VertexTextureMapping.Y = (float) VertexUVs[i].Y;
                _vertices[NumVertices].VertexTextureIndex = textureIndex;
                _vertices[NumVertices].VertexOpacity = opacity;

                NumVertices++;

                if(NumVertices >= _vertices.Length)
                {
                    var tempVertex = new Vertex[_vertices.Length + VerticesArrayLength];
                    Array.Copy(_vertices, tempVertex, _vertices.Length);
                    _vertices = tempVertex;
                }
            }

            NumTiles++;

            _tempLastBlendMode = blend;
        }

        public void SetUpEffect()
        {
            var graphicsContext = _graphicsContext;
            var graphics = (graphicsContext as MonoGameGraphicsContext);

            var GraphicsDevice = graphics.WindowContext.Graphics.GraphicsDevice;

            var viewport = GraphicsDevice.Viewport;

            //var World = SimpleRenderer._modelMatrix;

            var ortho = ModelMatrix;
            var World = new Microsoft.Xna.Framework.Matrix(
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row1.X, (float)ortho.Row1.Y, (float)ortho.Row1.Z, (float)ortho.Row1.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row2.X, (float)ortho.Row2.Y, (float)ortho.Row2.Z, (float)ortho.Row2.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row3.X, (float)ortho.Row3.Y, (float)ortho.Row3.Z, (float)ortho.Row3.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row4.X, (float)ortho.Row4.Y, (float)ortho.Row4.Z, (float)ortho.Row4.W));


            var View = Microsoft.Xna.Framework.Matrix.CreateLookAt(new Microsoft.Xna.Framework.Vector3(0, 0, -1), new Microsoft.Xna.Framework.Vector3(0, 0, 0), new Microsoft.Xna.Framework.Vector3(0, -1, 0));
            //var Projection2 = Microsoft.Xna.Framework.Matrix.CreateScale(1, -1, 1) * Microsoft.Xna.Framework.Matrix.CreateOrthographicOffCenter(0, 1920, 1080, 0, 0, 1); // nans

            ortho = _graphicsContext.CurrentFrameBuffer.CreateOrthographic() * Matrix4.CreateScale(1, -1, 1);
            var Projection = new Microsoft.Xna.Framework.Matrix(
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row1.X, (float)ortho.Row1.Y, (float)ortho.Row1.Z, (float)ortho.Row1.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row2.X, (float)ortho.Row2.Y, (float)ortho.Row2.Z, (float)ortho.Row2.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row3.X, (float)ortho.Row3.Y, (float)ortho.Row3.Z, (float)ortho.Row3.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row4.X, (float)ortho.Row4.Y, (float)ortho.Row4.Z, (float)ortho.Row4.W));

            var wvp = World * View * Projection;

            _effect.Parameters["World"].SetValue(World);
            _effect.Parameters["View"].SetValue(View);
            _effect.Parameters["Projection"].SetValue(Projection);

            for (var i = 0; i < Textures.Length; i++)
            {
                var texture = (Textures[i] as MonoGameTexture).Texture;
                _effect.Parameters["InputTexture" + i.ToString()].SetValue(texture);
            }

            _effect.Parameters["AlphaGrayScale"].SetValue(ShadowRenderer.IsShadowing ? 1.0f : 0.0f);

            _effect.Parameters["InputColour"].SetValue(new Microsoft.Xna.Framework.Vector4(Colour.Red / 255.0f, Colour.Green / 255.0f, Colour.Blue / 255.0f, Colour.Alpha / 255.0f));
            _effect.Parameters["ShadowColour"].SetValue(new Microsoft.Xna.Framework.Vector4(ShadowColour.Red / 255.0f, ShadowColour.Green / 255.0f, ShadowColour.Blue / 255.0f, ShadowColour.Alpha / 255.0f));
            _effect.Parameters["InputFilter"].SetValue(Filter);
            _effect.Parameters["InputFilterAmount"].SetValue((float)FilterAmount);

            _effect.Parameters["InputClipRectangle"].SetValue(new Microsoft.Xna.Framework.Vector4((float)ClipRectangle.X, (float)ClipRectangle.Y, (float)ClipRectangle.Right, (float)ClipRectangle.Bottom));

            //_effect.Parameters["FragmentTextureIndex"].SetValue(_vertices[0].VertexTextureIndex);
            //_effect.Parameters["FragmentOpacity"].SetValue(_vertices[0].VertexOpacity);

            _effect.Parameters["InputFilter"].SetValue(Filter);

        }

        private void DrawQuad(Vertex[] destination)
        {
            var graphicsContext = _graphicsContext;
            var graphics = (graphicsContext as MonoGameGraphicsContext);
            var GraphicsDevice = graphics.WindowContext.Graphics.GraphicsDevice;

            Vertex[] quad = destination;

            short[] indices = new short[6];
            if (GraphicsDevice.RasterizerState == RasterizerState.CullClockwise)
            {
                indices[0] = 0; indices[1] = 1; indices[2] = 2;
                indices[3] = 2; indices[4] = 3; indices[5] = 0;
            }
            else
            {
                indices[0] = 0; indices[1] = 2; indices[2] = 1;
                indices[3] = 2; indices[4] = 0; indices[5] = 3;
            }

            foreach (EffectPass pass in _effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                GraphicsDevice.SetVertexBuffer(null);
                GraphicsDevice.DrawUserIndexedPrimitives(Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList, quad, 0, 4, indices, 0, 2, Vertex.VertexDeclaration);
            }
        }


        public void SetStates()
        {
            var graphicsContext = _graphicsContext;
            var graphics = (graphicsContext as MonoGameGraphicsContext);

            var GraphicsDevice = graphics.WindowContext.Graphics.GraphicsDevice;

            // Alpha blending
            graphics.BlendMode = _tempLastBlendMode == TileBlendMode.Additive ? BlendMode.Additive : BlendMode.Alpha;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap;
            GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
        }

        public void EndRender()
        {
            if(!Rendering)
                throw new Exception("Not currently renderering");

            SetStates();

            // Prepare textures
            foreach(var texture in Textures)
                texture.Filtering = TextureFiltering.NearestNeighbour;

            SetUpEffect();
            DrawQuad(_vertices);

            Rendering = false;
        }

        private struct Vertex : IVertexType
        {
            public Microsoft.Xna.Framework.Vector3 VertexPosition;

            public Microsoft.Xna.Framework.Vector2 VertexTextureMapping;

            public float VertexTextureIndex;

            public float VertexOpacity;

            public static int currentByteSize = 0;
            public static int Offset(float n) { var s = sizeof(float); currentByteSize += s; return currentByteSize - s; }
            public static int Offset(Microsoft.Xna.Framework.Vector2 n) { var s = sizeof(float) * 2; currentByteSize += s; return currentByteSize - s; }
            public static int Offset(Microsoft.Xna.Framework.Color n) { var s = sizeof(int); currentByteSize += s; return currentByteSize - s; }
            public static int Offset(Microsoft.Xna.Framework.Vector3 n) { var s = sizeof(float) * 3; currentByteSize += s; return currentByteSize - s; }
            public static int Offset(Microsoft.Xna.Framework.Vector4 n) { var s = sizeof(float) * 4; currentByteSize += s; return currentByteSize - s; }

            public readonly static VertexDeclaration VertexDeclaration =
              new VertexDeclaration(new VertexElement(Offset(Microsoft.Xna.Framework.Vector3.Zero), VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
                                    new VertexElement(Offset(Microsoft.Xna.Framework.Vector2.Zero), VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
                                    new VertexElement(Offset(0.0f), VertexElementFormat.Single, VertexElementUsage.TextureCoordinate, 1),
                                    new VertexElement(Offset(0.0f), VertexElementFormat.Single, VertexElementUsage.TextureCoordinate, 2));
            VertexDeclaration IVertexType.VertexDeclaration
            {
                get { return Vertex.VertexDeclaration; }
            }

        }


    }

It looks like the correct way of specifying positions is with the usage of Vector3 not Vector4, I have some other errors but those are unrelated to drawing.