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.
My Window Class;
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;
}
}
}
My Draw() method;
protected override void Draw(GameTime gameTime)
{
window1.DrawNewWindow(spriteBatch, GraphicsDevice);
window1.drawNew = false;
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.AlphaBlend,
SamplerState.PointClamp,
null,
null,
null);
window1.Draw(spriteBatch, GraphicsDevice);
spriteBatch.End();
base.Draw(gameTime);
}
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.
may be part of the culprit. Try not to instantiate something new every update. It occurs about 60 times a second and can cause serious overhead. Initialize the render targets in the Initialize method instead.