OutOfMemory exception when drawing a cube

I have a class that draws and rotates a cube. every time I rotate the cube, I reload the buffer with 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); } 

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

after a couple of minutes or so, I get an OutOfMemory exception in the line:

 buffer.SetData<VertexPositionNormalTexture>(verts); 

Can someone explain why this is happening and what I can do to solve this problem.

+7
out-of-memory xna 3d
source share
2 answers

Vertex buffers are unmanaged resources. The garbage collector does not know that they are using a whole bunch of unmanaged memory (and GPU resources) backstage. All he knows is the tiny bit of managed memory that everyone uses.

I talk more about unmanaged resources in XNA in my answer to this question .

You can call Dispose() on each VertexBuffer before it leaks (but after drawing is complete, as it will still be used!) To free up unmanaged resources. This will avoid a memory error, but it will still be very slow!

What you really have to do is create the minimum required vertex buffers only once. The ideal place for this is in your LoadContent function (and then Dispose() in your UnloadContent function). If you have a whole bunch of cubes, all you need is a single vertex buffer that describes the cube that you will use every time you draw a cube.

Obviously, you do not 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() .

(The way you install WorldViewProj is fine too. But using a nice API is, well, better.)

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

More about this, your problem is similar to another question I answered .

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

+8
source share

It looks like you create a new vertex buffer every frame and don't let the old one fall out of the garbage collection area. In fact, you do this for each of your cubes.

A better approach would be to simply update the vertex values ​​of each frame, or better to update the transform on the cube in each frame.

0
source share

All Articles