0
\$\begingroup\$

In the code below, I want to draw a box on my screen. But when I run it, there is an error message:

The current vertex declaration does not include all the elements required by the current vertex shader. Color0 is missing.

Here is the code in question:

    private SpriteBatch _sb;
    private Vector3 _position;

    public Vector3 Position
    {
        get { return _position; }
    }
    private Matrix _world;

    public Matrix World
    {
        get { return _world; }
    }
    private Texture2D _image;
    private VertexPositionColor[] _vertices;
    private short[] _indices;
    private Game _game;
    private IndexBuffer _ib;
    private VertexBuffer _vb;
    private BasicEffect _basicEffect;
    private BoundingBox _boundingBox;

    public BoundingBox BoundingBox
    {
        get { return _boundingBox; }
    }

    public Blackhole(Game game, Vector3 position, Matrix view, Matrix projection)
    {
        _game = game;

        _vertices = new VertexPositionColor[4];
        _vertices[0] = new VertexPositionColor(new Vector3(-100, 100, 0), Color.Red);
        _vertices[1] = new VertexPositionColor(new Vector3(100, 100, 0), Color.Green);
        _vertices[2] = new VertexPositionColor(new Vector3(100, -100, 0), Color.Blue);
        _vertices[3] = new VertexPositionColor(new Vector3(-100, -100, 0), Color.Yellow);

        _indices = new short[6];
        _indices[0] = 0; _indices[1] = 1; _indices[2] = 2;
        _indices[3] = 0; _indices[4] = 2; _indices[5] = 3;

        _vb = new VertexBuffer(game.GraphicsDevice, VertexPositionColor.VertexDeclaration, 4, BufferUsage.WriteOnly);
        _vb.SetData<VertexPositionColor>(_vertices);

        _ib = new IndexBuffer(game.GraphicsDevice, typeof(short), 6, BufferUsage.WriteOnly);
        _ib.SetData<short>(_indices);

        game.GraphicsDevice.SetVertexBuffer(_vb);
        game.GraphicsDevice.Indices = _ib;

        _basicEffect = new BasicEffect(game.GraphicsDevice);
        _basicEffect.View = view;
        _basicEffect.Projection = projection;
        _basicEffect.World = _world;
        _basicEffect.VertexColorEnabled = true;
        _basicEffect.TextureEnabled = false;

        RasterizerState newState = new RasterizerState();
        newState.CullMode = CullMode.None;
        game.GraphicsDevice.RasterizerState = newState;
        _boundingBox = new BoundingBox(new Vector3(_position.X, _position.Y, -1), new Vector3(-_position.X, -_position.Y, 1));
    }

    public void Update(GameTime gt)
    {
        _world = Matrix.Identity * Matrix.CreateTranslation(_position);
    }

    public void Draw(Matrix view, Matrix projection)
    {
        _basicEffect.View = view;
        _basicEffect.Projection = projection;

        foreach (EffectPass f in _basicEffect.CurrentTechnique.Passes)
        {
            f.Apply();

            _game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 4, 0, 2);
        }
    }

What is the cause of my error?

\$\endgroup\$
1
\$\begingroup\$

You never initialize _vb (your vertex buffer) anywhere in the code you provided.

If you do not construct the vertex buffer, it will be null and have no corresponding vertex declaration (the runtime will try to match the vertex declaration against the shader you've selected, fail to do so, and report that error).

\$\endgroup\$
  • \$\begingroup\$ sorry, the vertex buffer initialization got deleted when i copied my code into stackexchange. now it's included again. located just before the _ib initialization. \$\endgroup\$ – Moses Aprico Dec 17 '13 at 7:32
  • \$\begingroup\$ i mean, the _vb initialization was originally there when the error popped \$\endgroup\$ – Moses Aprico Dec 17 '13 at 7:48
0
\$\begingroup\$

It seems that you forgot to add the colors of the BasicEffect. In Microsoft's tutorial ( http://msdn.microsoft.com/en-us/library/bb203926.aspx), section 3 it is shown how to do that:

 basicEffect = new BasicEffect(graphics. GraphicsDevice);

basicEffect.World = worldMatrix;
basicEffect.View = viewMatrix;
basicEffect.Projection = projectionMatrix;

// primitive color
basicEffect.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f);
basicEffect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
basicEffect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f);
basicEffect.SpecularPower = 5.0f;
basicEffect.Alpha = 1.0f; 
\$\endgroup\$
  • \$\begingroup\$ I never tried that before, since in my class, there is no lesson on this. I mean, on the other project, it works fine even without it. But, I'll try it. Thanks. \$\endgroup\$ – Moses Aprico Dec 18 '13 at 4:59
0
\$\begingroup\$

I somehow solve it by re-writing my code from different reference, even though I can't find the difference that caused this code didn't work.

This is the new one (in whole class version), in case someone can locate the difference.

PS : Just tweak a bit from VertexPositionTexture to VertexPositionColor and change some code. Maybe this isn't a correct answer to my question though, I posted it because mine succeeded with this (I originally want to achieve Texture, using color only to check my vertex first)

public class Blackhole
{
    Texture2D _texture;
    Matrix _view, _world, _projection;
    Vector3 _position;
    VertexPositionTexture[] _vertices;
    short[] _indices;
    IndexBuffer _ib;
    VertexBuffer _vb;
    BasicEffect _basicEffect;
    Game _game;
    float _scale;
    float _rotation;

    public Blackhole(Game game)
    {
        _game = game;
        Initialize();
    }

    public void Initialize()
    {
        _view = Matrix.CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), new Vector3(0, 10, 0));
        _projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 100);
        _world = Matrix.Identity;
        _scale = 2;
        _rotation = 0;
        _position = new Vector3(0, 0, 100);
        LoadContent();
    }

    protected void LoadContent()
    {
        _texture = _game.Content.Load<Texture2D>("blackhole");
        _game.GraphicsDevice.BlendState = BlendState.NonPremultiplied;
        _vertices = new VertexPositionTexture[4];
        _vertices[0] = new VertexPositionTexture(new Vector3(-1f * _scale, 1 * _scale, 0), new Vector2(0, 0));
        _vertices[1] = new VertexPositionTexture(new Vector3(1f * _scale, 1 * _scale, 0), new Vector2(1, 0));
        _vertices[2] = new VertexPositionTexture(new Vector3(1f * _scale, -1 * _scale, 0), new Vector2(1, 1));
        _vertices[3] = new VertexPositionTexture(new Vector3(-1f * _scale, -1 * _scale, 0), new Vector2(0, 1));

        _indices = new short[6];
        _indices[0] = 0; _indices[1] = 1; _indices[2] = 2;
        _indices[3] = 0; _indices[4] = 2; _indices[5] = 3;

        _vb = new VertexBuffer(_game.GraphicsDevice, VertexPositionTexture.VertexDeclaration, 4, BufferUsage.WriteOnly);
        _vb.SetData<VertexPositionTexture>(_vertices);

        _ib = new IndexBuffer(_game.GraphicsDevice, typeof(short), 6, BufferUsage.WriteOnly);
        _ib.SetData<short>(_indices);

        _game.GraphicsDevice.SetVertexBuffer(_vb);
        _game.GraphicsDevice.Indices = _ib;

        _basicEffect = new BasicEffect(_game.GraphicsDevice);
        _basicEffect.TextureEnabled = true;
        _basicEffect.World = _world;
        _basicEffect.Texture = _texture;

    }

    public void Update(GameTime gameTime, Matrix view, Matrix projection)
    {
        _rotation -= 1f;
        _world = 
            Matrix.Identity * 
            Matrix.CreateRotationZ(MathHelper.ToRadians(_rotation)) * 
            Matrix.CreateTranslation(_position);

        _basicEffect.World = _world;
        _basicEffect.View = view;
        _basicEffect.Projection = projection;
    }

    public void Draw(GameTime gameTime)
    {
        foreach (EffectPass item in _basicEffect.CurrentTechnique.Passes)
        {
            item.Apply();
            _game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 4, 0, 2);
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ Is this all your code? It's possible that in re-writing it you added or removed something elsewhere that wasn't in the original. \$\endgroup\$ – user1430 Dec 19 '13 at 20:08
  • \$\begingroup\$ Also, even if you are unsure this was the "right" thing to do (usually rewriting isn't, because it hides the problem), my answer was pretty clearly not the solution after your recent edit... so why did you accept mine? \$\endgroup\$ – user1430 Dec 19 '13 at 20:12
  • \$\begingroup\$ Yes it's all mine. I don't think so, since originally it's in a separate class from my main class. And I compare it many times, and technically nothing different. The only difference I can spot is the existence of Initialize() and LoadContent() in the error one. I accept your solution before I make my answer, since I don't think mine is the correct one too, I didn't make a change at all. Thanks for reminding, I'll remove my "check". :) \$\endgroup\$ – Moses Aprico Dec 21 '13 at 3:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.