.net - 绘制立方体时出现 OutOfMemory 异常

标签 .net xna 3d out-of-memory

我有一个绘制和旋转立方体的类。每次我旋转立方体时,我都会用立方体的新值重新加载缓冲区。

    public void LoadBuffer(GraphicsDevice graphicsDevice)
    {
        buffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, triangles * 3, BufferUsage.None);
        buffer.SetData<VertexPositionNormalTexture>(verts);
        graphicsDevice.SetVertexBuffer(buffer);
    }

    public void Draw(GraphicsDevice graphicsDevice)
    {
        graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, triangles);
    }

然后在 Game.Draw 中调用 Cube.Draw 方法
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Color.White, 1f, 0);

        basicEffect.Parameters["WorldViewProj"].SetValue(world * view * projection);

        EffectPass pass = basicEffect.CurrentTechnique.Passes[0];
        if (pass != null)
        {
            pass.Apply();
            cube1.LoadBuffer(GraphicsDevice);
            cube1.Draw(GraphicsDevice);
            cube2.LoadBuffer(GraphicsDevice);
            cube2.Draw(GraphicsDevice);
            cube3.LoadBuffer(GraphicsDevice);
            cube3.Draw(GraphicsDevice);
        }
        base.Draw(gameTime);
    }

大约几分钟后,我在线上收到了 OutOfMemory 异常:
buffer.SetData<VertexPositionNormalTexture>(verts);

有人可以解释为什么会发生这种情况以及我能做些什么来解决它。

最佳答案

顶点缓冲区是非托管资源。垃圾收集器不知道他们在幕后使用了一大堆非托管内存(和 GPU 资源)。它所知道的只是每个人使用的一小部分托管内存。

我在 my answer to this question 中更多地谈论 XNA 中的非托管资源。 .

您可以调用Dispose()在每个 VertexBuffer在你泄露它之前(但在绘制完成之后,因为它仍然会被使用!),释放非托管资源。这将避免内存不足错误,但仍然会很慢!

你真正应该做的是只创建一次最少的必要顶点缓冲区。执行此操作的理想地点是您的 LoadContent函数(然后 Dispose() 它们在您的 UnloadContent 函数中)。如果你有一大堆立方体,你只需要一个描述立方体的顶点缓冲区,每次绘制立方体时都可以重复使用它。

显然你不想在同一个地方绘制所有的立方体。这就是 World 矩阵的用途。每次绘制立方体时,设置 BasicEffect.World到该立方体的转换矩阵并调用 Apply() .

(您直接设置 WorldViewProj 的方式也可以。但是使用 nice API 会更好。)

如果您想要旋转,请使用 Matrix.CreateFromYawPitchRoll(yaw, pitch, roll)创建您的转换矩阵。

有关此的更多详细信息,您的问题类似于 another question I have answered .

(请注意,如果顶点本身确实改变了每一帧,您应该使用 DrawUserPrimitives 。但请注意,这仍然比让 GPU 上的顶点着色器处理任何变换要慢得多。)

关于.net - 绘制立方体时出现 OutOfMemory 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3364481/

相关文章:

java - 计算机图形学 : Moving in the world

math - 计算 LookAt 矩阵

c# - 将现有的 Node Js 项目添加到现有的 .Net 解决方案

c# - 方法重载决议系统如何决定在传递空值时调用哪个方法?

c# - HSV 到 RGB 在黄色处停止 C#

将 3D 线框转换为 3D 实体模型

.net - 无法使 Dapper 查询映射不区分大小写

c# - 如何使用 C# 查找一个月中的第三个星期五?

c# - XNA - 键盘文本输入

c# - GameTime 始终为 0 - MonoGame (XNA) - C#