No longer updated: new and updated blog (including old content) at http://roy-t.nl

Archive for http://roy-t.nl, please update your bookmarks

Posts Tagged ‘XNA2’

Creating Animated Textured Models for XNA. part1

Posted by Roy Triesscheijn on Wednesday 5 November, 2008

It’s now online at ziggyware.com

Be sure to check it out since it is an extremely handy tutorial on creating Animated (Skinned) Textured Models in Blender / trueSpace , with all the export scripts and export settings you will need to make it work immidiatly in your XNA2/3 app (both XNA2 and XNA3 source codes included)

Advertisements

Posted in XNA | Tagged: , , , , , , , , , | 1 Comment »

XNA 3.0 and Winforms, the easy way

Posted by Roy Triesscheijn on Thursday 9 October, 2008

There are many tutorials on XNA and Winforms, however none of them seem very easy, but after reading a post from ‘madman’ on Ziggyware.com and fiddleing around it seems very easy  to do, easier than the creators example.

In short we adjust the game1.cs to draw to a picturebox instead of drawing to the window that is created for it. The code is very easy to understand (as it’s only 10lines of code) and performs superb, without the use of ugly timers and all that stuff.

Firstoff create a new XNA3.0 Windows  project in  Visual Studio 2008 (Express) (this code will probably work just fine in XNA2.0/Visual Studio 2005 (Express))

Add a Form to it the usual way, and drag a picturebox to it. Call the picturebox pctSurface.

Then go into the code view of your  form and write the following code:


public IntPtr getDrawSurface()
{
    return pctSurface.Handle;
}

This code will give us the Handle to the picturebox which we will later use to draw our game to.

Now open up game1.cs add the variable ‘private IntPtr drawSurface;’ and change the constructor to look like this:


public Game1(IntPtr drawSurface)
{
              graphics = new GraphicsDeviceManager(this);
              Content.RootDirectory = "Content";
              this.drawSurface = drawSurface;
              graphics.PreparingDeviceSettings +=
              new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
              System.Windows.Forms.Control.FromHandle((this.Window.Handle)).VisibleChanged +=
              new EventHandler(Game1_VisibleChanged);            
}

And add these 2 eventhandlers

        /// <summary>
        /// Event capturing the construction of a draw surface and makes sure this gets redirected to
        /// a predesignated drawsurface marked by pointer drawSurface
        /// </summary>
        ///
<param name="sender"></param>
        ///
<param name="e"></param>
        void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
                e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle =
                drawSurface;
        }

        /// <summary>
        /// Occurs when the original gamewindows' visibility changes and makes sure it stays invisible
        /// </summary>
        ///
<param name="sender"></param>
        ///
<param name="e"></param>
        private void Game1_VisibleChanged(object sender, EventArgs e)
        {
                if (System.Windows.Forms.Control.FromHandle((this.Window.Handle)).Visible == true)
                    System.Windows.Forms.Control.FromHandle((this.Window.Handle)).Visible = false;
        }
 

Now we are almost done, change program.cs’ static void main to this:


static void Main(string[] args)
{
              formMain form = new formMain();
              form.Show();
              Game1 game = new Game1(form.getDrawSurface());
              game.Run();            
}

Now to make sure your application really exits when closing your form add the code

Application.Exit();

to your button and windowclosed eventhandler!

Thats it, run the code and you’ll see your wonderfull Form with a blue square where you’ve located your pictureBox! Now you can change your game1.cs as normal, use your contentmanager and content project as normal, and use windowsforms for an excellent  userinterface for your editor.

Note: this will not work on the Xbox360 since it doesn’t have WinForms
Note2: you might see a window for a few ms when starting your app. This is the old window that used to be drawn to, unfortunately I haven’t figured out how to get rid of it completely, but the eventhandler will hide it the first time it shows.

The sourcode can be downloaded here: sourcecode.
in the example I also created a spriteBatch and spriteFont to show you can really draw!

XNA3.0 In Winforms in action, notice the pictureBox borderstyle3d effect
(notice the picturebox’ borderstyle settings affecting the rendering, here it adds a nice 3D border)

Update: since I couldn’t believe the XNA devs being less smart than I am, I asked around at the creators forums and landed in a discussion between, Shawn Hargreaves, theZman and myself. According to Shawn this sollution might work properly but its not tested and he says that there might be border cases where this sollution will stop working (drawsurface may invalidate etc..) The creators example is guaranteed to work 100%, however in my eyes it still a bit bulky and hard to understand, that code may be necessairy to let everything work properly, even on strange hardware configurations etc. Also the input logic in the update loop might not work properly. I myself haven’t encountered any of these problems yet but it’s a thing to keep in mind.

My advice: creating an editor just for yourself, or anyway just for devs, you can safely use this sample. If your going to make code that has to ship to other users, you might want to reconsider.

You could also look at this topic: Shawn Hargreaves in the Creators forums

kick it on GameDevKicks.com

Posted in XNA | Tagged: , , , , , , , | 51 Comments »

Simple On demand Content Loading in XNA

Posted by Roy Triesscheijn on Wednesday 27 August, 2008

Written in C# for XNA2.0 but might be useful with other versions.

Warning: I just found out that the XNA2.0 ContentManager automatically checks if content is already loaded or not. The on-demand content loading part of this short-tut is still usefull and there isn’t really overhead in finding content via this dictionary (you have to find it someway) so it is dynamic and very handy, but it doesn’t get an extra plus for making content only load once.

The problem.

There are a few problems with content in any game.

-Is it already loaded?
-Will I need it again? (solved by XNA’s own ContentManager)
-Where do I need to use it
-How am I going to get it to the object that needs it.

Loading content in game1.cs is easy. You just ask to contentmanager to load a certain file, for example:

Texture2D  texture = Content.Load<Texture2D>(@”Textures\Monkey”);

But what if you have several classes in a hierarchy, take for example a WorldHandler that handles multiple pawns. How do you get the ContentManager to the pawns when they want a texture for visual representation. Ofcourse the anwser to this question is relatively easy, create a static class that makes the ContentManager accesible to them. However if we are going to create a seperate class, why not let that class load the content for the pawns so that we don’t need any loading logic in there? That would be great, it would save us a whole lot of lines and if something about the content changes (for example what if we decide that we want a seperate folder for all the lolcats -textures we are going to put in our game?) we only have to change it in one place.

So that solves the later 2 problems. But if we have 50 warriors in our scene that all use the same texture, it would be a waste to load it 50 times, but how can we know if it was already loaded? The sollution I came up for is a dictionary like this:

private static Dictionary<string, Texture2D> textures = new Dictionary<string, Texture2D>();

We can make a dictionary for each content type (for my sprite game I’m using textures and effects atm).

Next we need a way of loading the content into the dictionaries in a smart way. We could load all the content at startup but that would be kind of wasteful, we can do 2 things.

-Load at start of a level
-Load on demand

Or a way in between. After some thinking at this moment I went with total on demand loading. Here is a code sample of how I did it.

public static Texture2D LoadTexture(string name)
{
    Texture2D texture;
    if (textures.TryGetValue(name, out texture) == true)
    {
        return texture;
    }
    else
    {
        texture = Content.Load<Texture2D>(@"Textures\" + name);
        textures.Add(name, texture);
        return texture;
    }
}

If a texture’s tag wasn’t found in the dictionary yet it will be loaded and then returned to the calling object. If it was already loaded it will be returned directly.

Now we have a sollution for all 4 simple problems. We have a nice static class that will take care of all the content loading, that will never load a piece of content twice and that is accesible for all objects in your game. This class could be extended with a garbage collection mechanism if you have so much content that this is needed.

If you would like to load some content at the start of a level, dont worry you can always make a list of content that is needed (in this case a string[] with all the tags for the content) and run a foreach loop on the public static Texture2D LoadTexture(string name) method. You don’t even have to supply a Texture2D object already because just calling the method will get the content loaded.

I hope this article helps all of you around there with making your content management more efficient and easier to handle, but remember I’m still new to all this to and can I no way be compared to all the XNA devs and their techdemo’s so be sure to load arroound at creators.xna.com for some more info on content management. Goodluck and don’t hesitate to comment with links to your tutorials/games/content!

Posted in XNA | Tagged: , , , , , , , | Leave a Comment »