2013-02-26 53 views
2

用下面的代碼, 1個刷爆網狀平在60 FPS, 2個刷爆網格畫在33〜FPS, 3個刷爆網眼在28〜FPS, 4個刷爆網眼在20〜FPS繪製繪製。 我做錯了什麼,或者我達到某種限制?它似乎並不像我畫很多多邊形,但我仍然是新編程,所以我不太瞭解。請提供一些效率建議。謝謝。XNA - 如何更有效地繪製頂點?

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); 
       } 
      } 
     } 
    } 
} 

回答

4

移動初始化緩衝區並在draw方法之外寫入數據的代碼應該顯着提高性能。

創建頂點和索引緩衝區是一項昂貴的操作。對於靜態網格物體(頂點不變),可以重用緩衝區。

如果頂點/索引經常變化(每幀一次),請使用動態緩衝區。

+0

我發佈了一個關於拖延管道的長篇答案,並且不知何故設法完全錯過了他每幀分配全新緩衝區的事實。這無疑是正確的答案。 – 2013-02-26 20:56:10

+0

非常感謝你,我會嘗試一下。我很高興這個世界有幫助的人。 – BCPowers 2013-02-26 21:10:56

+2

我試過了,它有效。我創建了頂點緩衝區和索引緩衝區列表,以便我創建的網格具有自己的網格,並在創建網格時定義。 FPS用4個最大的網格恢復到60。再次感謝。如果我增加你的聲譽,我會的。 – BCPowers 2013-02-26 21:33:57