2013-02-16 4 views
1

Я создаю игру после работы с книгой XNA 4.0. Это будет 3D, но я уже застрял в создании местности ...ERROR XNA Framework VertexBuffer IndexBuffer use

UPDATE: Все, начиная отсюда обновление ... Terrain Update:

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

Terrain Draw:

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

Закомментированный линия работает в обоих случаях я могу видеть местность ... следующий код для инициализации Vertex и индекс буфера:

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), перед циклом.

Вершинный буфер предоставляет объявление вершины, которое запрашивает сообщение об исключении.


Edit после обновления вопрос: В вашей новой версии вы устанавливаете вершинные и индексные буферы - но это не в том месте. Вам нужно установить их на графическое устройство в каждом кадре. Ваш код будет работать, только если ничего не изменится после того, как вы установили их в FillBuffers. Но я предполагаю, что материал извлекается вне метода вашего класса Draw?

Если это что-то еще SpriteBatch, то даже это работает с использованием буферов вершин и буферов индексов. Таким образом, он сбросит настройки. (Стоит добавить, что он также устанавливает состояния рендеринга - в этом случае вам может понадобиться посмотреть this article.)

+0

и не забывайте, что вам нужно также установить IndexBuffer ... – Blau

+0

@Blau Очень приятно поймать, спасибо! Исправлена. –

+0

Привет, Спасибо. Я попытался настроить все, но теперь это работает. Если бы у меня была репутация, я бы разбил голосование :) –