1

我查看了从谷歌找到的示例中的一些代码并将其实现到我的游戏中,但问题是我收到错误:当前顶点声明不包括当前顶点着色器所需的所有元素。位置 0 丢失。我查看了 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);
        }
    }
}

这是我的主要游戏课。这不起作用,并为我提供了未设置为对象错误实例的对象引用,该对象错误指向我的多维数据集类中的行:

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

1 回答 1

1

这是我的RenderObject的代码,其中您的Cube作为对象添加到其中,以及我自己对我的多维数据集的实现。

XNA RenderObject 具有 2 种类型的 Cubes

这是我执行此操作的测试游戏。

您可以简单地更改 defaultCube = false,以尝试使用您的。但是你应该把它调整为 0.5,因为它应该是 x start = -0.5f, x end = 0.5f,它的大小等于 1。那么你可以很容易地改变世界比例。

XNA RenderObject 的测试游戏

由于上述方法均无效,或者代码中的其他内容可能会影响性能,因此我举了一个用于早期引擎的示例。

为了最小化每个对象的数据量,我简单地创建了一个抽象类,它可以处理几乎任何类型的顶点,因此您可以创建颜色立方体、普通立方体、纹理立方体等。

首先,我有一个 RenderObject,它存储了要渲染的对象所需的所有字段;VertexBuffer、IndexBuffer、世界矩阵、BoundingBox。

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

您甚至可以进一步扩展它而不仅仅是一个 PrimitiveColor 类,它可以是一个只接受一个类型(颜色/法线/纹理)的 Cube 类,并且您可以最小化创建不同类型立方体的代码,因为在这种情况下立方体将始终是具有 36 个顶点和 6 个面的立方体。它是静态的。

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

因此,为了简化:RenderObject -> PrimitiveColor/PrimitiveNormal -> ColorCube / ColorNormal,然后您可以使用立方体而不是其余的。

我不知道你是渲染“一个”立方体还是一千个立方体。但在我的例子中,我渲染了 50*50 的立方体,我不得不使用截锥体来剔除摄像机视野内的立方体,以免降低性能。如果您这样做并且仍然无法正常工作,则错误可能存在于另一个代码中。

我认为这是处理此问题的最佳方法。因为每个渲染对象共享一个缓冲区、一个矩阵,也许还有一个渲染方法(不一定),这样你就可以只处理重要的代码——创建立方体。它不会重新创建任何效果,它不会在初始化后重新创建任何缓冲区(尽管它们可以在更新方法中相当快地更改 - 我已经使用地形完成了此操作,只需记住在更改之前处理旧的顶点缓冲区在顶点中说一种颜色,然后重新创建缓冲区)

我的立方体,正确缩放。添加一个白色、黑色、白色、黑色立方体以查看它们的开始和结束位置。 在此处输入图像描述

你的立方体,缩放不正确。添加您的默认颜色。 在此处输入图像描述

但重要的是,在跳到截头剔除立方体之前,帧速率没有问题。如果不这样做,会导致丢帧。但如果你只画一个立方体,这不应该发生。

于 2013-05-31T11:59:47.027 回答