XNA 4.0 SpriteBatch.Draw Out Of Memory Exception Thrown
- by RustyGearGames
Well, first of all, my guess is that I'm calling the spritebatch.draw() method to many times, but I need to (Or, it's the only way I can figure out how to) Draw my in-game windows. I'll just go ahead and dump my code;
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace System.Window
{
class Window
{
#region Variables
public Texture2D importedTexture;
public Texture2D WindowSkin;
public RenderTarget2D currentWindow;
public RenderTarget2D windowTexture;
public Vector2 pos;
public int prevWindowWidth;
public int prevWindowHeight;
public int windowWidth;
public int windowHeight;
public bool visible;
public bool active;
public bool drawNew;
#region Rectangles
public Rectangle clickRect;
public Rectangle topLeftRect;
public Rectangle topRightRect;
public Rectangle buttonRect;
public Rectangle botLeftRect;
public Rectangle botRightRect;
#endregion
#endregion
public Window()
{
}
public void Initialize(GraphicsDevice g, Texture2D ws, Texture2D it, int w, int h, bool v, bool a)
{
WindowSkin = ws;
importedTexture = it;
windowWidth = w;
prevWindowWidth = w;
windowHeight = h;
prevWindowHeight = h;
windowTexture = new RenderTarget2D(g, windowWidth, windowHeight);
currentWindow = windowTexture;
visible = v;
active = a;
drawNew = true;
topLeftRect = new Rectangle(0, 0, 32, 32);
topRightRect = new Rectangle(32, 0, 32, 32);
buttonRect = new Rectangle(64, 0, 32, 32);
botLeftRect = new Rectangle(0, 64, 32, 32);
botRightRect = new Rectangle(64, 64, 32, 32);
}
public void Update(GraphicsDevice g, Vector2 p, int width, int height)
{
prevWindowWidth = windowWidth;
prevWindowHeight = windowHeight;
pos = p;
windowWidth = width;
windowHeight = height;
windowTexture = new RenderTarget2D(g, windowWidth+2, windowHeight+2);
}
public void Draw(SpriteBatch s, GraphicsDevice g)
{
s.Draw(currentWindow, pos, new Rectangle(0, 0, windowWidth, windowHeight), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
}
public void DrawNewWindow(SpriteBatch s, GraphicsDevice g)
{
g.SetRenderTarget(windowTexture);
g.Clear(Color.Transparent);
s.Begin();
#region Draw Background
for (int w = 3; w < (windowWidth); w += 32)
{
for (int h = 32; h < (windowHeight); h += 32)
{
s.Draw(WindowSkin, new Vector2(w, h), new Rectangle(32, 32, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
}
}
#endregion
s.Draw(importedTexture, new Vector2(3, 32), new Rectangle(0, 0, importedTexture.Width, importedTexture.Height), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
#region Draw resizables
for (int i = 32; i < (windowWidth - 64); i += 32)
{
s.Draw(WindowSkin, new Vector2(i, 0), new Rectangle(16, 0, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
}
for (int i = 32; i < (windowWidth - 32); i += 32)
{
s.Draw(WindowSkin, new Vector2(i, windowHeight - 32), new Rectangle(32, 64, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
}
for (int i = 64; i < (windowHeight - 32); i += 32)
{
s.Draw(WindowSkin, new Vector2(0, i), new Rectangle(0, 48, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
}
for (int i = 64; i < (windowHeight - 32); i += 32)
{
s.Draw(WindowSkin, new Vector2(windowWidth - 32, i), new Rectangle(64, 48, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
}
#endregion
#region Draw Corners
s.Draw(WindowSkin, new Vector2(0, 0), topLeftRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
s.Draw(WindowSkin, new Vector2(0, 32), new Rectangle(0, 32, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
s.Draw(WindowSkin, new Vector2(windowWidth - 64, 0), topRightRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
s.Draw(WindowSkin, new Vector2(windowWidth - 32, 32), new Rectangle(64, 32, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
s.Draw(WindowSkin, new Vector2(windowWidth - 32, 0), buttonRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
s.Draw(WindowSkin, new Vector2(0, windowHeight - 32), botLeftRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
s.Draw(WindowSkin, new Vector2(windowWidth - 32, windowHeight - 32), botRightRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
#endregion
s.End();
currentWindow = windowTexture;
}
}
}
It's all nice and configured for my little windowskin texture, and such. the only problem is that it will get a little laggy, and then completely crash on me about a minute into running it. It throws an Out Of Memory Exception, but I don't know and can't find any other topic or post on this relating to spritebatch. Does anybody have any suggestions on how I can get this working and not take up much memory? I would think this as an easy, cost effective way of drawing a window. I'm just not sure how cut down on my draw calls, or get any of that memory back.