2013-06-17 2 views
0

У меня возникла проблема с линией VertexBuffer. Если я прокомментирую строку, моя программа будет перебирать этот код 49 раз. Код из учебника Римера для XNA 4.0 и работает в этом решении. Я проверил инструкции «using» и не вижу различий между этими двумя проектами. Я не могу понять, почему VertexBuffer приведет к сбою программы, в то время как IndexBuffer просто прекрасен. У кого-нибудь есть идеи?VertexBuffer заставляет программу сбой

public void CopyToTerrainBuffers() 
    { 
     for (int x = 0; x < 7; x++) 
      for (int y = 0; y < 7; y++) 
      { 
       if (!gpu_buffer_std[x, y].initialized) 
       { 
        VertexBuffer temp = new VertexBuffer( device, 
                  typeof(VertexMultitextured), 
                  tiles_std[x + 1, y + 1].terrainVertices.Length * VertexMultitextured.SizeInBytes, 
                  BufferUsage.WriteOnly); 
        // size = 3,698,744 
        gpu_buffer_std[x, y].terrainVertexBuffer = new VertexBuffer(device, 
                       typeof(VertexMultitextured), 
                       tiles_std[x + 1, y + 1].terrainVertices.Length * VertexMultitextured.SizeInBytes, 
                       BufferUsage.WriteOnly); 
        gpu_buffer_std[x, y].terrainIndexBuffer = new IndexBuffer( device, 
                       typeof(int), 
                       tiles_std[x + 1, y + 1].indices.Length, 
                       BufferUsage.WriteOnly); 
        gpu_buffer_std[x, y].initialized = true; 
       } 
       if (!tiles_std[x + 1, y + 1].toGPU) 
       { 
        //gpu_buffer_std[x, y].terrainVertexBuffer.SetData(tiles_std[x + 1, y + 1].terrainVertices); 
        gpu_buffer_std[x, y].terrainIndexBuffer.SetData(tiles_std[x + 1, y + 1].indices); 
        gpu_buffer_std[x, y].terrainVertexDeclaration = VertexMultitextured.VertexDeclaration; 
        tiles_std[x + 1, y + 1].toGPU = true; 
       } 
      } 
    } 

«Темп» должен был определить, является ли это указателем, вызывающим проблему. Это целая функция (метод грубой силы). Здесь используется структура.

public struct VertexMultitextured : IVertexType 
    { 
     public Vector3 position; 
     public Vector3 normal; 
     public Vector4 textureCoordinate; 
     public Vector4 texWeights; 

     public static int SizeInBytes = sizeof(float) * (3 + 3 + 4 + 4); 

     public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration 
     (
      new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), 
      new VertexElement(sizeof(float) * 3, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0), 
      new VertexElement(sizeof(float) * (3 + 3), VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 0), 
      new VertexElement(sizeof(float) * (3 + 3 + 4), VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 1) 
     ); 

     public VertexMultitextured(Vector3 position, Vector3 normal, Vector4 textureCoordinate, Vector4 texWeights) 
     { 
      this.position = position; 
      this.normal = normal; 
      this.textureCoordinate = textureCoordinate; 
      this.texWeights = texWeights; 
     } 

     public Vector3 Position 
     { 
      get { return position; } 
      set { position = value; } 
     } 

     public Vector3 Normal 
     { 
      get { return normal; } 
      set { normal = value; } 
     } 

     public Vector4 TextureCoordinate 
     { 
      get { return textureCoordinate; } 
      set { textureCoordinate = value; } 
     } 

     public Vector4 TexWeights 
     { 
      get { return texWeights; } 
      set { texWeights = value; } 
     } 

     VertexDeclaration IVertexType.VertexDeclaration 
     { 
      get { return VertexDeclaration; } 
     } 
    } 

Обновление: Я взял код в вопросе и поместил его в Реймерса коде, и дал те же результаты. Отладчик показывает следующее:

System.OutOfMemoryException was unhandled 
HResult=-2147024882 
Message=Insufficient memory to continue the execution of the program. 
Source=Microsoft.Xna.Framework 
StackTrace: 
    at Microsoft.Xna.Framework.Helpers.GetExceptionFromResult(UInt32 result) 
    at Microsoft.Xna.Framework.Graphics.GraphicsHelpers.GetExceptionFromResult(UInt32 result) 
    at Microsoft.Xna.Framework.Graphics.VertexBuffer.CreateBuffer(VertexDeclaration vertexDeclaration, UInt32 dwVertexCount, UInt32 usage, _D3DPOOL pool) 
    at Microsoft.Xna.Framework.Graphics.VertexBuffer..ctor(GraphicsDevice graphicsDevice, Type vertexType, Int32 vertexCount, BufferUsage usage) 
    at Series3D4.Game1.CopyToTerrainBuffers(VertexMultitextured[] vertices, Int32[] indices) in D:\C#Programs\Series3D4\Series3D4\Series3D4\Game1.cs:line 494 
    at Series3D4.Game1.LoadVertices() in D:\C#Programs\Series3D4\Series3D4\Series3D4\Game1.cs:line 190 
    at Series3D4.Game1.LoadContent() in D:\C#Programs\Series3D4\Series3D4\Series3D4\Game1.cs:line 172 
    at Microsoft.Xna.Framework.Game.Initialize() 
    at Series3D4.Game1.Initialize() in D:\C#Programs\Series3D4\Series3D4\Series3D4\Game1.cs:line 154 
    at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun) 
    at Microsoft.Xna.Framework.Game.Run() 
    at Series3D4.Program.Main(String[] args) in D:\C#Programs\Series3D4\Series3D4\Series3D4\Program.cs:line 13 
InnerException: 

Вот используемый класс:

public class DisplayTileChunk 
    { 
     // Header info for tile control 
     public bool beenmoved; // x,z been updated after move 
     public bool isvisible; // render the tile on screen 
     public bool loaded; // tile loaded/processed in memory 
     public bool toGPU; // tile data transfered to GPU 
     // Terrain info 
     public int[] texture_index = new int[4]; 
     public VertexMultitextured[] terrainVertices = new VertexMultitextured[4225]; // 65 x 65 
     public int[] indices = new int[24576]; // 64 x 64 x 6 
     public VertexBuffer terrainVertexBuffer; 
     public IndexBuffer terrainIndexBuffer; 
     public VertexDeclaration terrainVertexDeclaration; 
     public int noVertices; // = terrainVertexBuffer.VertexCount; 
     public int noTriangles; // = terrainIndexBuffer.IndexCount/3; 
     // Water Info 
     public VertexBuffer waterVertexBuffer; 
     public VertexDeclaration waterVertexDeclaration; 
     // Vegetation Info 
     public VertexBuffer treeVertexBuffer; 
     public VertexDeclaration treeVertexDeclaration; 
    } 

и модифицированная функция от Реймерса кода:

private void CopyToTerrainBuffers(VertexMultitextured[] vertices, int[] indices) 
    { 
     terrainVertexBuffer = new VertexBuffer(device, typeof(VertexMultitextured), vertices.Length * VertexMultitextured.SizeInBytes, BufferUsage.WriteOnly); 
     terrainVertexBuffer.SetData(vertices); 

     terrainIndexBuffer = new IndexBuffer(device, typeof(int), indices.Length, BufferUsage.WriteOnly); 
     terrainIndexBuffer.SetData(indices); 

     for (int x = 0; x < 36; x++) 
      for (int y = 0; y < 36; y++) 
      { 
       gpu_buffer_std[x, y] = new DisplayTileChunk(); 
       VertexBuffer test = new VertexBuffer(device, typeof(VertexMultitextured), 4225 * VertexMultitextured.SizeInBytes, BufferUsage.None); 
       //gpu_buffer_std[x, y].terrainVertexBuffer = new VertexBuffer(device, typeof(VertexMultitextured), gpu_buffer_std[x, y].terrainVertices.Length * VertexMultitextured.SizeInBytes, BufferUsage.WriteOnly); 
       //gpu_buffer_std[x, y].terrainIndexBuffer = new IndexBuffer(device, typeof(int), gpu_buffer_std[x, y].indices.Length, BufferUsage.WriteOnly); 
      } 

    } 

И некоторые интересные цифры от отладчика:

vertices.Length = 16384 
terrainVertexBuffer.VertexCount = 917504 
terrainVertexBuffer._vertexCount = 917504 
terrainVertexBuffer._size = 51380224 

test.VertexCount = 236600 
test._vertexCount = 236600 
test._size = 13249600 
+0

Какая ошибка вы получаете, на какую итерацию это происходит? – borrillis

+0

Нет сообщения об ошибке, программа просто «перестает работать», она сбрасывается при первом проходе. Если бы они оба вызвали ошибку, программа была бы прямой. –

+0

Вам необходимо отправить более подробную информацию. Вы можете связать учебное пособие, которое вы используете, предоставить больше кода и предоставить более конкретное описание того, что означает «перестает работать». Это бросание необработанного исключения? Или вы можете пройти через него и определить линию аварии? Что говорит отладчик? –

ответ

1

Найдено проблема, оригинальная линия:

 terrainVertexBuffer = new VertexBuffer(device, 
               typeof(VertexMultitextured), 
               vertices.Length * VertexMultitextured.SizeInBytes, 
               BufferUsage.WriteOnly); 

Правильная линия:

 terrainVertexBuffer = new VertexBuffer(device, 
               typeof(VertexMultitextured), 
               vertices.Length, // error was here 
               BufferUsage.WriteOnly); 

Я не мог видеть ошибку за глядя на него, потребовалось несколько выходных дней и «бум», там это было ,

Смежные вопросы