XNA - 如何更高效地绘制顶点?

3
使用以下代码, 1个最大化的网格在60 FPS下绘制, 2个最大化的网格在33~ FPS下绘制, 3个最大化的网格在28~ FPS下绘制, 4个最大化的网格在20~ FPS下绘制。 我做错了什么,还是达到了某种极限?看起来我没有绘制很多多边形,但我还是编程新手,不太清楚。请提供一些效率建议。谢谢。
class PolygonManager
{
    List<List<VertexPositionColor>> vertices;
    VertexBuffer vertexBuffer;
    List<List<int>> indices;
    IndexBuffer indexBuffer;
    int meshRef;
    int indexRef;
    Random random;

    public PolygonManager()
    {
        vertices = new List<List<VertexPositionColor>>();
        vertices.Add(new List<VertexPositionColor>());
        indices = new List<List<int>>();
        indices.Add(new List<int>());
        meshRef = -1;
        indexRef = 0;
        random = new Random();
    }

    public void CreateMesh(int length, int width, Vector3 position, Color color)
    {
        meshRef = -1;
        indexRef = 0;
        for (int i = 0; i < vertices.Count; i++)
        {
            if (vertices[i].Count <= 65536 - (length * width))
                meshRef = i;
        }

        if (meshRef == -1)
        {
            vertices.Add(new List<VertexPositionColor>());
            indices.Add(new List<int>());
            meshRef = vertices.Count - 1;
        }

        indexRef = vertices[meshRef].Count;

        for (int y = 0; y < length; y++)
        {
            for (int x = 0; x < width; x++)
            {
                vertices[meshRef].Add(new VertexPositionColor(new Vector3(x, 0, y) + position,
                                      new Color(color.R + (random.Next(-10, 10) / 100), color.G + (random.Next(-10, 10) / 100), color.B + (random.Next(-10, 10) / 100))));
            }
        }

        for (int y = 0; y < length - 1; y++)
        {
            for (int x = 0; x < width - 1; x++)
            {
                int topLeft = x + y * width;
                int topRight = (x + 1) + y * width;
                int lowerLeft = x + (y + 1) * width;
                int lowerRight = (x + 1) + (y + 1) * width;

                indices[meshRef].Add(topLeft + indexRef);
                indices[meshRef].Add(lowerRight + indexRef);
                indices[meshRef].Add(lowerLeft + indexRef);

                indices[meshRef].Add(topLeft + indexRef);
                indices[meshRef].Add(topRight + indexRef);
                indices[meshRef].Add(lowerRight + indexRef);
            }
        }
    }

    public void Draw(GraphicsDevice graphicsDevice, BasicEffect basicEffect)
    {
        for (int v = 0; v < vertices.Count; v++)
        {
            vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), vertices[v].Count, BufferUsage.WriteOnly);
            vertexBuffer.SetData<VertexPositionColor>(vertices[v].ToArray());
            graphicsDevice.SetVertexBuffer(vertexBuffer);
            indexBuffer = new IndexBuffer(graphicsDevice, typeof(int), indices[v].Count, BufferUsage.WriteOnly);
            indexBuffer.SetData<int>(indices[v].ToArray());
            graphicsDevice.Indices = indexBuffer;
            foreach (EffectPass effectPass in basicEffect.CurrentTechnique.Passes)
            {
                effectPass.Apply();
                for (int i = 0; i < 6; i++)
                {
                    graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices[v].Count, 0, indices[v].Count/3);
                }
            }
        }
    }
}
1个回答

4

将初始化缓冲区和写入数据的代码移到绘制方法之外,可以显著提高性能。

创建顶点和索引缓冲区是一项昂贵的操作。对于静态网格(其中顶点不会改变),您可以重用缓冲区。

如果顶点/索引经常更改(每帧一次),请使用动态缓冲区。


我发了一个长答案,关于暂停管线的问题,但不知何故完全没注意到他每一帧都在分配全新的缓冲区。这无疑是正确的答案。 - Cole Campbell
非常感谢,我会尝试一下。我很高兴在这个世界上有乐于助人的人。 - BCPowers
3
我试过了,它有效。我创建了一个顶点缓冲区和索引缓冲区列表,以便我创建的网格有自己的定义,并在创建网格时进行定义。现在FPS恢复到了60,即使使用了4个最大的网格。再次感谢。如果我可以提高你的声望,我会这样做的。 - BCPowers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接