[SOLVED] Missing Vertex Elements on Draw Call with own IVertexType decleration

Hi all,

I want to create my own vertex buffer as the shader I wrote takes a position, color, normal and texcord, so created a new Vertex type to do this.

I loaded my shader, set all my stuff up, but then on the draw call I get this error:-

“Additional information: An error occurred while preparing to draw. This is probably because the current vertex declaration does not include all the elements required by the current vertex shader. The current vertex declaration includes these elements: SV_Position0, COLOR1, NORMAL2, TEXCOORD3.”

Hoping you can see how I have the decleration set up as well as the error. Thanks for taking a look, and hope you can help.

My new vertex structure looks like this:-

    public struct VertexPositionColorNormalTexture : IVertexType
    {
        public Vector3 Position;
        public Color Color;
        public Vector3 Normal;
        public Vector2 TexCoord;

        public VertexPositionColorNormalTexture(Vector3 position, Color color, Vector3 normal, Vector2 texCoord)
        {
            Position = position;
            Color = color;
            Normal = normal;
            TexCoord = texCoord;
        }

        public VertexDeclaration VertexDeclaration
        {
            get
            {
                return new VertexDeclaration
                (
                    new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
                    new VertexElement(sizeof(float) * 3, VertexElementFormat.Color, VertexElementUsage.Color, 1),
                    new VertexElement(sizeof(float) * 4, VertexElementFormat.Vector3, VertexElementUsage.Normal, 2),
                    new VertexElement(sizeof(float) * 7, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 3)
                );
            }
        }
    }

I am creating my verts like this:-

    protected override void LoadContent()
    {
        base.LoadContent();            

        vpc = new[]
        {
            new VertexPositionColorNormalTexture(new Vector3(.5f, -.5f,0), Color.White, Vector3.Backward,new Vector2(1,1)),
            new VertexPositionColorNormalTexture(new Vector3(-.5f,-.5f,0), Color.White, Vector3.Backward,new Vector2(0,1)),
            new VertexPositionColorNormalTexture(new Vector3(-.5f, .5f,0), Color.White, Vector3.Backward,new Vector2(0,0)),
            new VertexPositionColorNormalTexture(new Vector3(.5f, .5f,0), Color.White, Vector3.Backward,new Vector2(1,0)),
        };

        idx = new int[] 
        {
            0,1,2,
            2,3,0,
        };

        effect = Game.Content.Load<Effect>("Shaders/VertextLitTexture");

        vb = new VertexBuffer(Game.GraphicsDevice, typeof(VertexPositionColorNormalTexture), vpc.Length, BufferUsage.None);

    }

And my draw call looks like this:-

    public override void Draw(GameTime gameTime)
    {
        effect.Parameters["World"].SetValue(world);
        effect.Parameters["View"].SetValue(Camera.View);
        effect.Parameters["Projection"].SetValue(Camera.Projection);
        effect.Parameters["WorldInverseTranspose"].SetValue(Matrix.Invert(Matrix.Transpose(world)));

        effect.Parameters["ModelTexture"].SetValue(Game.Content.Load<Texture2D>("Textures/SBGTest"));

        EffectTechnique effectTechnique = effect.Techniques[0];
        EffectPassCollection effectPassCollection = effectTechnique.Passes;
        foreach (EffectPass pass in effectPassCollection)
        {
            pass.Apply();
            vb.SetData(vpc);
            Game.GraphicsDevice.SetVertexBuffer(vb);
            Game.GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vpc, 0, 4, idx, 0, 2);
        }
    }

And the expected vertex structure for my shader is this:-

struct vIn
{
float4 pos : SV_POSITION;
float4 color : COLOR0;
float4 normal : NORMAL0;
float2 texcoord : TEXCOORD0;
};

I have also included a screen shot of the exception being thrown. I must be doing something daft, but for the life of me can’t see what it is :frowning:

You should be addressing your vertex elements like this:

new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3, VertexElementFormat.Color, VertexElementUsage.Color, 0),
new VertexElement(sizeof(float) * 4, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
new VertexElement(sizeof(float) * 7, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)

not like this:

new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3, VertexElementFormat.Color, VertexElementUsage.Color, 1),
new VertexElement(sizeof(float) * 4, VertexElementFormat.Vector3, VertexElementUsage.Normal, 2),
new VertexElement(sizeof(float) * 7, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 3)

And you should increment the usage index only when there are more than one elements with the same usage type.

1 Like

Ahh, yes!

I knew I must be doing something daft like that, it’s been a while since I have played with XNA :slight_smile:

Ill give this a try now and let you know how I get on, thanks for taking the time to look at this and comment :slight_smile:

That worked :smiley:

Thank you!

There’s a PR up that adds this vertex type, but it’s mostly about testing BasicEffect and there are some issues there. But once those are resolved and it gets merged VertexPositionNormalColorTexture and VertexPositionNormalColor will be added too.

2 Likes

Cool, I like to be able to create my own, I like to have control over the vertex structure like this, it gives a lot of flexibility :slight_smile:

I have a few old XNA shaders that need me to build my own structures, I have just not used XNA in such a long time that I make silly mistakes like this and need someoen to point them out :slight_smile:

Good to know other structure types will be added by default though.