tecnico puntos punto perspectiva paso metodo fuga dibujo cubo con .net xna 3d out-of-memory

.net - puntos - Excepción de OutOfMemory al dibujar cubo



perspectiva a dos puntos de fuga metodo (2)

tengo una clase que dibuja y gira un cubo. cada vez que giro el cubo, vuelvo a cargar el buffer con los nuevos valores para el cubo.

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

luego llama al método Cube.Draw en 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); }

después de unos minutos más o menos, recibo una excepción OutOfMemory en la línea:

buffer.SetData<VertexPositionNormalTexture>(verts);

¿Podría alguien explicar por qué sucede esto y qué puedo hacer para resolverlo?


Parece que estás creando un nuevo búfer de vértice en cada fotograma y no permites que el anterior se salga del alcance para ser basura. De hecho, estás haciendo esto para cada uno de tus cubos.

Un mejor enfoque sería simplemente actualizar los valores de los vértices en cada cuadro o, mejor aún, actualizar la transformación en el cubo de cada cuadro.


Los buffers de vértice son recursos no administrados. El recolector de basura no sabe que están usando una gran cantidad de memoria no administrada (y recursos de GPU) detrás de las escenas. Todo lo que sabe es la pequeña cantidad de memoria administrada que cada uno usa.

Hablo más sobre recursos no administrados en XNA en mi respuesta a esta pregunta .

Puede llamar a Dispose() en cada VertexBuffer antes de que se filtre (¡pero una vez que finalice el dibujo, ya que todavía estará en uso!), Para liberar los recursos no administrados. Esto evitará el error de falta de memoria, ¡pero seguirá siendo muy lento!

Lo que realmente debería hacer es crear los búferes de vértices mínimos necesarios solo una vez . El lugar ideal para hacerlo es en su función LoadContent (y luego Dispose() en su función UnloadContent ). Si tiene un montón de cubos, todo lo que necesita es un único búfer de vértices que describa un cubo, que reutilizará cada vez que dibuje un cubo.

Obviamente no quieres dibujar todos tus cubos en el mismo lugar. Para eso está la matriz mundial. Cada vez que dibuja un cubo, establezca BasicEffect.World en su matriz de transformación para ese cubo y llame a Apply() .

(La forma en que está configurando WorldViewProj directamente también está bien. Pero usar la buena API es, bueno, más agradable).

Si la rotación es lo que desea, use Matrix.CreateFromYawPitchRoll(yaw, pitch, roll) para crear su matriz de transformación.

Para obtener más detalles al respecto, su problema es similar a otra pregunta que he respondido .

(Tenga en cuenta que, si los vértices mismos realmente cambian cada cuadro, debe usar DrawUserPrimitives . Pero tenga en cuenta que esto es aún considerablemente más lento que dejar que el sombreado de vértices en la GPU maneje las transformaciones).