2013-02-16 34 views
1

我在通過XNA 4.0書籍工作之後創建了一個遊戲。這將是3D的,但我已經陷在創建地形...錯誤XNA框架VertexBuffer IndexBuffer用法

UPDATE:一切從這裏開始的是一個更新... 地形更新:

public void Update(Matrix view, Matrix projection) 
    { 
     View = view; 
     Projection = projection; 
     World = Matrix.CreateTranslation(-Width/2f, 0, Height/2f); 
    } 

地形繪製:

public void Draw(GraphicsDevice g) 
    { 
     effect.CurrentTechnique = effect.Techniques["ColoredNoShading"]; 
     effect.Parameters["xView"].SetValue(View); 
     effect.Parameters["xProjection"].SetValue(Projection); 
     effect.Parameters["xWorld"].SetValue(World); 
     foreach (EffectPass pass in effect.CurrentTechnique.Passes) 
     { 

      pass.Apply(); 
     //g.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length/3, VertexPositionColorNormal.VertexDeclaration); 
      g.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Length, 0, indices.Length/3); 
     } 
    } 

的註釋行工作,在這兩種情況下,我能看到地形... 下面的代碼是初始化頂點和索引緩衝區:

private void SetUpVertices(GraphicsDevice g) 
    { 
     float currentH; 
     int currentI; 
     vertices = new VertexPositionColorNormal[Width * Height]; 
     for (int x = 0; x < Width; x++) 
     { 
      for (int y = 0; y < Height; y++) 
      { 
       currentH = heightData[x,y]; 
       currentI = x + y * Width; 
       vertices[currentI].Position = new Vector3(x, currentH , -y); 
       if (currentH < minH + (maxH - minH)/3) 
        vertices[currentI].Color = Color.ForestGreen; 
       else if (currentH < maxH - (maxH - minH)/3) 
        vertices[currentI].Color = Color.LawnGreen; 
       else 
        vertices[currentI].Color = Color.White; 
      } 
     } 
     SetUpIndices(g); 
    } 
    private void SetUpIndices(GraphicsDevice g) 
    { 
     indices = new int[(Width - 1) * (Height - 1) * 6]; 
     int counter = 0; 
     for (int y = 0; y < Height - 1; y++) 
     { 
      for (int x = 0; x < Width - 1; x++) 
      { 
       int lowerLeft = x + y * Width; 
       int lowerRight = (x + 1) + y * Width; 
       int topLeft = x + (y + 1) * Width; 
       int topRight = (x + 1) + (y + 1) * Width; 

       indices[counter++] = topLeft; 
       indices[counter++] = lowerRight; 
       indices[counter++] = lowerLeft; 
       indices[counter++] = topLeft; 
       indices[counter++] = topRight; 
       indices[counter++] = lowerRight; 
      } 
     } 
     SetUpNormals(g); 
    } 
    private void SetUpNormals(GraphicsDevice g) 
    { 
     for (int i = 0; i < vertices.Length; i++) 
     { 
      vertices[i].Normal = Vector3.Zero; 
     } 
     int[] index = new int[3]; 
     Vector3 s1, s2, n; 
     for (int i = 0; i < vertices.Length/3; i++) 
     { 
      for (int y = 0; y < 3; y++) 
       index[y] = indices[i * 3 + y]; 
      s1 = vertices[index[0]].Position - vertices[index[2]].Position; 
      s2 = vertices[index[0]].Position - vertices[index[1]].Position; 
      n = Vector3.Cross(s1, s2); 
      for (int y = 0; y < 3; y++) 
      { 
       vertices[index[y]].Normal += n; 
       vertices[index[y]].Normal.Normalize(); 
      } 
     } 
     FillBuffers(g); 
    } 
    private void FillBuffers(GraphicsDevice g) 
    { 
     VertexBuffer = new VertexBuffer(g, VertexPositionColorNormal.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); 
     VertexBuffer.SetData(vertices); 
     IndexBuffer = new IndexBuffer(g, typeof(int), indices.Length, BufferUsage.WriteOnly); 
     IndexBuffer.SetData(indices); 
     g.Indices = IndexBuffer; 
     g.SetVertexBuffer(VertexBuffer); 
    } 

我不認爲,有一個錯誤,因爲它正在與其他線路。可能會出現我使用的.fx文件錯誤。如果你這樣想,我要切換到BasicEffects ... (您可能注意到,該代碼是從http://www.riemers.net/eng/Tutorials/XNA/Csharp/series1.php

感謝您的幫助......

你的, 弗洛裏安

回答

1

(回答original revision of the question。)

您沒有將頂點緩衝區和索引緩衝區設置到圖形設備上。的代碼(未經測試)這兩行應該做你需要的東西:

g.GraphicsDevice.Indices = indexBuffer; 
g.GraphicsDevice.SetVertexBuffer(vertexBuffer); 

把他們剛過您設置的參數對你的影響(ef),在循環之前。

頂點緩衝區提供異常消息要求的頂點聲明。問題更新後


編輯:在新的版本中,你要設置的頂點和索引緩衝區 - 但它是在錯誤的地方。您需要將它們設置到每個幀的圖形設備上。只有在FillBuffers中設置了代碼後,您的代碼纔會起作用。但我猜測,這些東西是在你課堂的Draw方法之外繪製的?

如果其他東西是SpriteBatch,即使是使用頂點緩衝區和索引緩衝區。所以它會重置您的設置。 (值得一提的是,它也設置渲染狀態 - 在這種情況下,你可能需要看到this article。)

+0

並且不要忘記你也需要設置IndexBuffer ... – Blau 2013-02-18 08:24:34

+0

@Blau非常好的接收,謝謝!固定。 – 2013-02-18 08:52:19

+0

嗨, 謝謝。我試圖調整一切,但現在它工作。如果我有信譽,我會粉碎投票:) – 2013-02-18 14:41:47