render text to Texture2D during LoadContent phase

Jul 29, 2009 at 5:04 PM

I want to render some text into a 2D texture.  I've been through the discussions that show how to do this, however, everything that I have seen so far shows that the texture actually gets rendered during a call to Draw and needs the DrawState to be in that state.  

What I need to do is to render text onto a 2D texture during the LoadContent phase and currently cannot figure out how to do this as DrawTargetTexture2D requires a call to Draw(DrawState state) to accomplish this, and at that point DrawState does not have the information that is needed.

 

 

Jul 30, 2009 at 8:09 AM

Are you saying that target.Draw(state) doesn't work for you from within an IContentOwner.LoadContent()?

 

Jul 30, 2009 at 3:09 PM

Correct.  In the main Application:

        protected override void LoadContent(DrawState state, Microsoft.Xna.Framework.Content.ContentManager manager)

        {

       DrawTargetTexture2D drawTarget = new DrawTargetTexture2D(new Camera2D(), 512, 512, SurfaceFormat.Color);
            TextElement kanjiDrawer = new TextElement();
            kanjiDrawer.Font = kanjiFont;
            kanjiDrawer.Text.Clear();
            kanjiDrawer.Text.Append(text);
            kanjiDrawer.Colour = Color.Black;
            kanjiDrawer.Position = new Vector2(256, -256);
            drawTarget.Add(kanjiDrawer);
            
            drawTarget.Draw(state);

 

        protected override void LoadContent(DrawState state, Microsoft.Xna.Framework.Content.ContentManager manager)
        {

when it hits, the draw I get an "Invalid Operation" exception.

I tried Warm(Application) but that renders garbage.

Just in case you are wondering, the TextElement that is configured above works fine when drawn from inside the Application.Draw method.

 

 

 

Coordinator
Jul 31, 2009 at 3:51 AM

Hi.

I'd agree that being able to render things in a content load would be useful. However it's currently setup the way it is because of some potential cases where you could have load being called within the Draw method - which could cause all sorts of strife.
The problem is, what if someone tries to load some content in the middle of their draw method (as an example)? Currently this is allowed. But allowing drawing within content load brings up a bunch of potential issues. Issues that could either be dealt with, ignored, explained.. etc. At the time I didn't consider something like this, so I went with simply locking down the draw state because I didn't want too much confusion.

I'll have a think about it :-)

Coordinator
Aug 1, 2009 at 2:32 AM

I've been thinking about it, and it's not feasible.
For example if you were loading content on another thread! (argh!)

But I have an alternative solution that may well work out OK. But it'll require some work too. UpdateState currently has the method 'PreFrameDraw' which is passed in an IDraw object. This draw method will be called at the start of the next frame, just before the main Draw() loop starts. I can simply add this into DrawState as well. So during your content load, you can add the object, and it'll be drawn before the next frame is drawn (if you are currently in update, that would be the current frame).

Aug 1, 2009 at 9:41 PM

For my particular application I was rendering kanji characters loaded from an XML file.  My alternative was to create all of the bitmaps in Photoshop which is what it sounds like I'll do.  Being able to render them from a text object was just going to save me the time/trouble of creating them all in photoshop.

 

 

Coordinator
Aug 1, 2009 at 11:23 PM

An alternative is simply flag that they need rendering again, and draw them during the main Draw loop whenever this flag is true. :-) This would be a temporary work around.
However if photoshop works just as well then that's great. I'm not sure how you'd render text at runtime on the xbox - as I don't think it has built in font rendering.