绘制索引基元错误

时间:2013-05-29 06:30:51

标签: c# xna

我从谷歌发现的一个例子中查看了一些代码并将其实现到我的游戏中,但问题是我收到了一个错误:当前的顶点声明不包含当前顶点着色器所需的所有元素。缺少Position0。我查看了MSDN文档,我无法看到我做错了什么

class Cube 
{
    public GraphicsDevice device;

    const int number_of_vertices = 8;
    const int number_of_indices = 36;

    private VertexBuffer vertices;
    private IndexBuffer indices;

    public Cube(GraphicsDevice graphicsDevice) 
    {
        device = graphicsDevice;
    } 

    void CreateCubeVertexBuffer() 
    {
        VertexPositionColor[]cubeVertices = new VertexPositionColor[number_of_vertices];

        cubeVertices[0].Position = new Vector3(-1, -1, -1);
        cubeVertices[1].Position = new Vector3(-1, -1, 1);
        cubeVertices[2].Position = new Vector3(1, -1, 1);
        cubeVertices[3].Position = new Vector3(1, -1, -1);
        cubeVertices[4].Position = new Vector3(-1, 1, -1);
        cubeVertices[5].Position = new Vector3(-1, 1, 1);
        cubeVertices[6].Position = new Vector3(1, 1, 1);
        cubeVertices[7].Position = new Vector3(1, 1, -1);

        cubeVertices[0].Color = Color.Black;
        cubeVertices[1].Color = Color.Red;
        cubeVertices[2].Color = Color.Yellow;
        cubeVertices[3].Color = Color.Green;
        cubeVertices[4].Color = Color.Blue;
        cubeVertices[5].Color = Color.Magenta;
        cubeVertices[6].Color = Color.White;
        cubeVertices[7].Color = Color.Cyan;

        vertices = new VertexBuffer(device, VertexPositionColor.VertexDeclaration, number_of_vertices, BufferUsage.WriteOnly);
        vertices.SetData < VertexPositionColor > (cubeVertices);
    }

    void CreateCubeIndexBuffer() {
    UInt16[]cubeIndices = new UInt16[number_of_indices];

    //bottom face
    cubeIndices[0] = 0;
    cubeIndices[1] = 2;
    cubeIndices[2] = 3;
    cubeIndices[3] = 0;
    cubeIndices[4] = 1;
    cubeIndices[5] = 2;

    //top face
    cubeIndices[6] = 4;
    cubeIndices[7] = 6;
    cubeIndices[8] = 5;
    cubeIndices[9] = 4;
    cubeIndices[10] = 7;
    cubeIndices[11] = 6;

    //front face
    cubeIndices[12] = 5;
    cubeIndices[13] = 2;
    cubeIndices[14] = 1;
    cubeIndices[15] = 5;
    cubeIndices[16] = 6;
    cubeIndices[17] = 2;

    //back face
    cubeIndices[18] = 0;
    cubeIndices[19] = 7;
    cubeIndices[20] = 4;
    cubeIndices[21] = 0;
    cubeIndices[22] = 3;
    cubeIndices[23] = 7;

    //left face
    cubeIndices[24] = 0;
    cubeIndices[25] = 4;
    cubeIndices[26] = 1;
    cubeIndices[27] = 1;
    cubeIndices[28] = 4;
    cubeIndices[29] = 5;

    //right face
    cubeIndices[30] = 2;
    cubeIndices[31] = 6;
    cubeIndices[32] = 3;
    cubeIndices[33] = 3;
    cubeIndices[34] = 6;
    cubeIndices[35] = 7;

    indices = new IndexBuffer(device, IndexElementSize.SixteenBits, number_of_indices, BufferUsage.WriteOnly);
    indices.SetData < UInt16 > (cubeIndices);

    }

    public void Draw(BasicEffect effect) 
    {
        device.SetVertexBuffer(vertices);
        device.Indices = indices;

        foreach(EffectPass pass in effect.CurrentTechnique.Passes) 
        {
            pass.Apply();
            device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, number_of_vertices, 0, number_of_indices / 3);
        }
    }
}

编辑:

public override void Draw(GameTime gameTime)
{
    cube.CreateCubeIndexBuffer();
    cube.CreateCubeVertexBuffer();

    foreach (var item in entities)
    {
        effect.VertexColorEnabled = false;
        effect.TextureEnabled = true;
        effect.Texture = item.Texture;

        Matrix center = Matrix.CreateTranslation(new Vector3(-0.5f, -0.5f, -0.5f));
        Matrix scale = Matrix.CreateScale(1f);
        Matrix translate = Matrix.CreateTranslation(item.Position);

        effect.World = center * scale * translate;
        effect.View = camera.View;
        effect.Projection = camera.Projection;

        cube.Draw(effect);
    }

    base.Draw(gameTime);
}

这可行,但FPS很慢。

构造

public Cube(GraphicsDevice graphicsDevice)
{
    device = graphicsDevice;
    CreateCubeIndexBuffer();
    CreateCubeVertexBuffer();
}

protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);
    font = Content.Load<SpriteFont>("font");
    grass = Content.Load<Texture2D>("grass");

    // TODO: use this.Content to load your game content here
    Components.Add(cubes);
    cube.CreateCubeIndexBuffer();
    cube.CreateCubeVertexBuffer();

    for (int x = 0; x < 50; x++)
    {
        for (int z = 0; z < 50; z++)
        {
            cubes.Add(new Vector3(mapX[x], 0f, mapZ[z]), Matrix.Identity, grass);
        }
    }
}

这是我的主要游戏类。这不起作用,并且我没有将Object引用设置为指向我的cube类中的行的对象错误的实例:

indices = new IndexBuffer(device, IndexElementSize.SixteenBits, number_of_indices, BufferUsage.WriteOnly);

1 个答案:

答案 0 :(得分:1)

以下是我的 RenderObject 的代码,其中多维数据集已添加为对象以及我自己的多维数据集实现。

XNA RenderObject with 2 types of Cubes

这是我实施此测试的测试游戏。

您可以简单地更改defaultCube = false,尝试使用您的。但你应该将它调整为0.5,因为它应该是x start = -0.5f,x end = 0.5f,大小等于1。你可以轻松改变世界规模。

Test game for XNA RenderObject

由于以上都不起作用,或者因为代码中的其他内容可能阻碍了性能,我做了一个我用于早期引擎的例子。

为了最小化每个对象的数据量,我只需创建一个几乎可以处理任何类型顶点的抽象类,这样就可以创建颜色立方体,普通立方体,纹理立方体等等。

首先,我有一个RenderObject,它存储了一个对象渲染所需的所有字段; VertexBuffer,IndexBuffer,World matrix,BoundingBox。

然后我创建一个特定的类来处理每种类型,Normal,Color,Texture。在这种情况下,我只包含一个版本的PrimitiveColor,它创建一个Color渲染对象。

你甚至可以进一步扩展它而不仅仅是一个PrimitiveColor类,它可以是一个只采用一种类型(颜色/正常/纹理)的Cube类,你可以最小化你的代码来创建不同类型的多维数据集,因为在在这种情况下,立方体将始终是具有36个顶点和6个面的立方体。这是静态的。

无论如何,这不是必需的。但是就像任何游戏编程或面向对象编程一样,良好的结构很重要并且会增加工作流程。为100个课程重新创建相同的属性并不是那么有趣。这使得调试和查找错误变得更加容易。

所以,简化:RenderObject - &gt; PrimitiveColor / PrimitiveNormal - &gt; ColorCube / ColorNormal,您可以使用多维数据集而不是其余的。

我不知道你是否渲染“一个”立方体或一千个立方体。但在我的情况下,我渲染了50 * 50个立方体,我不得不使用平截头体来剔除相机视野内的立方体,以免降低性能。如果你这样做并且仍然无法正常工作,那么错误就在于另一个代码。

我认为这是解决这个问题的最佳方法。因为每个渲染对象共享一个缓冲区,一个矩阵,也许还有一个渲染方法(并不总是必须),这样你只能处理重要的代码 - 创建多维数据集。它不会重新创建任何效果,它们在初始化后不会重新创建任何缓冲区(虽然它们可以在更新方法中相当快速地更改 - 我已经用地形完成了这个,只记得在更改之前处理旧的顶点缓冲区说出顶点中的颜色,然后重新创建缓冲区)

我的立方体,缩放正确。添加白色,黑色,白色,黑色立方体,以查看它们的起点和终点。 enter image description here

您的多维数据集,缩放错误。添加默认颜色。 enter image description here

但重要的是,在跳过截锥体剔除立方体之前,帧速率没有错。如果你不这样做,它将导致framedrop。但如果你只绘制一个立方体,这不应该发生。