0

我遇到了 VertexBuffer 行的崩溃问题。如果我注释掉这一行,我的程序将遍历这段代码 49 次。该代码来自 Riemer 的 XNA 4.0 教程,并且在该解决方案中工作。我检查了“使用”语句,并没有发现两个项目之间有任何不同。我无法弄清楚为什么 VertexBuffer 会在 IndexBuffer 很好的情况下使程序崩溃。有没有人有任何想法?

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

'temp' 是为了查看它是否是导致问题的指针。这是整个功能(蛮力方法)。这是正在使用的结构。

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

更新:我已经将有问题的代码放入 Reimers 代码中,并产生了相同的结果。调试器显示以下内容:

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

以及来自 Reimers 代码的修改函数:

    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
4

1 回答 1

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

我看不到错误,请了几天假,然后“繁荣”,就在那里。

于 2013-06-28T21:35:11.283 回答