绘制立方体时出现 OutOfMemory 异常 [英] OutOfMemory Exception when drawing cube

查看:24
本文介绍了绘制立方体时出现 OutOfMemory 异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i have a class that draws and rotates a cube. every time i rotate the cube i reload the buffer with the new values for the cube.

    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方法

then call the Cube.Draw method in Game.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 异常:

after a couple of minutes or so i get an OutOfMemory Exception on the line:

buffer.SetData<VertexPositionNormalTexture>(verts);

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

could somebody please explain why this is happening and what i can do to solve it.

推荐答案

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

Vertex buffers are unmanaged resources. The garbage collector doesn't know that they are using a whole bunch of unmanaged memory (and GPU resources) behind the scenes. All it knows about is the tiny little bit of managed memory that each one uses.

我在 我对这个问题的回答.

您可以在泄漏之前对每个 VertexBuffer 调用 Dispose()(但在绘制完成后,因为它仍在使用中!),以释放非托管资源.这样可以避免内存不足的错误,但还是会很慢!

You could call Dispose() on each VertexBuffer before you leak it (but after drawing finishes, as it will still be in use!), to release the unmanaged resources. This will avoid the out of memory error, but will still be very slow!

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

What you really should be doing is creating the minimum necessary vertex buffers only once. The ideal place to do this is in your LoadContent function (and then Dispose() them in your UnloadContent function). If you have a whole bunch of cubes, all you need is a single vertex buffer that describes a cube, which you reuse every time you draw a cube.

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

Obviously you don't want to draw all your cubes in the same place. This is what the World matrix is for. Each time you draw a cube, set BasicEffect.World to your transformation matrix for that cube and call Apply().

(您直接设置 WorldViewProj 的方式也可以.但是使用漂亮的 API 更好.)

(The way you are setting WorldViewProj directly is ok too. But using the nice API is, well, nicer.)

如果旋转是你想要的,使用 Matrix.CreateFromYawPitchRoll(yaw, pitch, roll) 来创建你的变换矩阵.

If rotation is what you want, use Matrix.CreateFromYawPitchRoll(yaw, pitch, roll) to create your transformation matrix.

有关此的更多详细信息,您的问题类似于另一个问题我有回答.

For more details about this, your problem is similar to another question I have answered.

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

(Note that, if the vertices themselves really do change each frame, you should use DrawUserPrimitives. But note that this is still considerably slower than letting the vertex shader on the GPU handle any transformations.)

这篇关于绘制立方体时出现 OutOfMemory 异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆