I’ve got a monogame project going where I want to generate lots of moving sprites that are a single letter. Think the interface of Dwarf Fortress in opengl.
I’ve written a class that runs at startup to create a series of textures from character strings. I could load up all the textures from static images, but I’d rather have the flexibility of being able to quickly add a new sprite by just picking a character and running with it.
The class works just fine for the first texture, but the second texture comes back completely blank.
The class is this:
class Text2Texture //Class to generate 32x32 textures generated from a character string.
{
GraphicsDevice graphics;
ContentManager content;
SpriteBatch spriteBatch;
SpriteFont fontRender;
RenderTarget2D scratchTexture;
public Text2Texture(GraphicsDevice gd, ContentManager cm, SpriteBatch sb)
{
graphics = gd;
spriteBatch = sb;
content = new ContentManager(cm.ServiceProvider, cm.RootDirectory);
fontRender = content.Load<SpriteFont>("PCSenior");
scratchTexture = new RenderTarget2D(graphics, 32, 32, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.PreserveContents);
}
public Texture2D generateTextureBox(string text)
{
//Setup to draw on an unseen rendertarget.
graphics.SetRenderTarget(scratchTexture);
graphics.Clear(Color.Transparent);
//Draw the text onto a rendertarget to create the texture.
spriteBatch.Begin();
Vector2 FontOrigion = fontRender.MeasureString(text) / 2;
spriteBatch.DrawString(fontRender, text, new Vector2(16, 18), Color.Black, 0, FontOrigion, 1.0f, SpriteEffects.None, 0.5f);
spriteBatch.End();
//Make a copy of the data onto the new texture.
Texture2D finalTexture = new Texture2D(graphics, scratchTexture.Width, scratchTexture.Height);
Color[] texdata = new Color[scratchTexture.Width * scratchTexture.Height];
scratchTexture.GetData(texdata);
finalTexture.SetData(texdata);
graphics.SetRenderTarget(null);
return finalTexture;
}
}
Then under game1.cs I have this in under LoadContent:
TextureA = t2t.generateTextureBox("A"); //A is drawn
TextureB = t2t.generateTextureBox("B"); //B never shows up.
The draw is equally straightforward. Under Draw I have:
spriteBatch.Draw(TextureA, new Vector2(20, 20), null, Color.Black, 0f, new Vector2(16, 16), 1f, SpriteEffects.None, 1);
spriteBatch.Draw(TextureB, new Vector2(50, 50), null, Color.Black, 0f, new Vector2(16, 16), 1f, SpriteEffects.None, 1);
Stepping through the code, it seems that point of failure is at the spriteBatch.DrawString(…) step. It simply isn’t drawing anything.
I’ve monkeyed with the code quite a bit trying to figure this out.
One change I tried is to dispose the scratchtexture after the copy and create a new one each time. When I do that, the first texture is created correctly, the second one is created, but it shows up as a black box (The alpha transparency is drawn incorrectly.)
I’ve also tried passing in the graphics device to the generateTextureBox method instead of when I instantiate the class, that doesn’t help.
Any suggestions here?