Thought for the Dazed

I've had to give up that Distance Learning course as I was having trouble seeing the teacher.

Flickr
www.flickr.com
RobMiles' items Go to RobMiles' photostream
Twitter
C# Yellow Book

Search entire site
Friday
Jun112010

Broken Wings

A couple of weeks ago I was in a toyshop with my dad. We were watching this awesome radio controlled helicopter buzz around the top of the shop.  I mentioned that the thing I wanted at that moment most in the world, really really wanted, was a helicopter just like that. So dad got me one for my birthday, even though it isn’t for a while. He even let me play with it in advance, which was great. It was just like being a kid again.

image

And, just like when I was a kid, I’ve gone and broken my toy. By cunning use of a wall I’ve managed to smash the rotor pivot thing which holds the blades on.  Fortunately I’ve found a supplier of the part needed to fix things up. If you have a Syma S032 “Fiery Dragon” you can get pretty much all the bits you’d need to build another one from here. You have to pay postage from Hong Kong, which is a bit of a pain, but the actual part is very cheap. I’ve bought two.

image

This is what the part should like. Mine is in more than one piece….

The only good news is that I used PayPal, and discovered that I had a little bit of money left on my PayPal account that I’d forgotten about, which means that I can regard the replacement bits as free I suppose.

I just hope I can get everything mended and working before dad comes round again…..

Thursday
Jun102010

Using RenderTarget2D in XNA on the Zune HD

Have you been lying awake at night wondering why your texture rendering doesn’t work on the Zune HD? No? Oh, well it must be just me then.

Anyhoo, I’ve found the problem, and the story goes like this.

RenderTarget2D is a way that you can draw things on a texture rather than on the game display. Normally I’d write things like:

spriteBatch.Begin();
spriteBatch.Draw (lots of pretty stuff….)
spriteBatch.End();

When the End method runs it takes all my drawing operations, batches them up and pushes them onto the graphics hardware, so the screen now contains the results of all my drawing operations.

However, sometimes you want to do things like rear view mirrors in driving games. You want to draw the view you would see behind the game onto a texture and then draw the texture on top of the rear view mirror.  In this case you need to create a thing called a RenderTarget2D which can accept the draw operations and put them onto a texture rather than the screen. Render targets are not that hard to use:

RenderTarget r = new RenderTarget2D(
   GraphicsDevice,  // my graphics device
   800,              // width of texture   
   600,              // height of texture
   1,               // no. of levels (1 works)
   SurfaceFormat.Color);  // format

GraphicsDevice.SetRenderTarget(0,r);

spriteBatch.Begin();
spriteBatch.Draw (lots of pretty stuff….)
spriteBatch.End();

GraphicsDevices.SetRenderTarget(0,null);

Texture2D result = r.GetTexture();

In the example above I send a bunch of drawing operations to a render target which is 800 pixels wide and 600 pixels high. I set the GraphicsDevice to render to this target, and then at the end I point it at null, which means go back to drawing on the screen again. The render target that I create is called r, and it ends up providing me with a texture which holds the results of all the drawing operations. You can use this to make your whole game display slide about, or bounce around the screen and it is very effective.

I’m using it so that my game can create some textures when it starts, rather than having to load them. I got the rendering working just right on the Windows PC and then transferred my code over the the Zune HD and it broke. I could clear the texture with different colours but I couldn’t draw anything on them. Wah.

After some twiddling I’ve found the problem. When you get a graphics device to render to a texture it is doing something it isn’t particularly used to. Graphics devices are designed to put stuff on the screen, not into memory.  This means that you have to be careful when you set up the target for the rendering, so that the graphics device is happy to write to it. You can find our more about this kind of thing here.

From the point of view of the Zune HD hardware, it is only happy to draw things if the target texture is either the size of the display or half the size of the display. Don’t ask me why, I don’t make the rules.  Any other sizes don’t produce an error, but they don’t work either, which is no fun.

This is not actually a huge problem (except perhaps for memory usage I guess) in that although you have to create textures that are larger than you really want you can use a version of Draw to only pull out the actual part that you want when you finally render them onto the screen. So, if you want to render to textures on a Zune you need to create your render target thus:

drawBuffer =
    new RenderTarget2D(
        GraphicsDevice, 
        GraphicsDevice.Viewport.Width / 2, 
        GraphicsDevice.Viewport.Height / 2,
        1,
        SurfaceFormat.Color);

This is the smallest texture you can use, if you want to draw on the full screen just don’t divide by 2.

Thursday
Jun102010

Static Constructors

Summer Ball Star

One of the few nice things about marking all the programming exam papers over the last week was the number of people who seemed to understand what “static” means in a programming context. While one or two did make the mistake of putting ‘static means that you can’t change it’ and getting both a muffled oath and zero marks from me most answered “static means that it always there, like the continuous background hiss from a badly tuned FM radio”. Actually, not all of them were as poetic as that, but they all knew that the thing about static items is that you don’t have to make them, your program can use them without having to create any instances.

Pressed for uses of static their answers made sense too, constants that you want everyone in a class to make use of, validation values and methods, all the sensible stuff. I didn’t ask about static constructors though, which is the next step along the road.

If you want to set up an instance of a class you add a constructor method that runs when an object of that type is created. These can be given values so that you can pre-set your object with data at the beginning of its life. Bank accounts can be given account holder names and starting balance values, sprites can be given textures and positions.

Sometimes you might want to perform some code to set up values in your static class. For example a class providing some constants for your program might need to read some system settings first. Unfortunately you can’t use a normal constructor for this because (duh!) we never make an instance of a static class. Instead though you can use a static constructor. This is just like a normal constructor, but has the keyword static in front:

public static class Settings
{
   public static int Number;
   static Settings ()
   {
        // code in here is performed when
        // the class is loaded
        Number = 99;
   }
}

The thing to remember about this is that the static constructor is run when the class is loaded, not at the start of the program. The first time your program reaches a statement like:

int i = Settings.Number;

- that is when the Settings class is loaded and the static constructor runs. In order to reduce memory use and time spent processing unwanted code the .NET runtime system only loads classes when they are needed, so if we never use a value from the Settings class it is never brought into memory and the static constructor never runs. Don’t think of static constructors all running when your program starts, they only run when the classes that contain them are loaded.

In fact any class can contain a static constructor that runs when it is loaded, not just static ones. If you need to get something set up before anybody uses your object just use the construction above to get control when the class is brought in. One way to find out if a particular class is ever actually used in your program is to add a static constructor and then put a breakpoint in it.

Wednesday
Jun092010

Football Crazy

image

I asked number one wife what she thought about the the world cup. She shrugged and replied “Humm. England are  around 8th or 9th in the world. Quarter Finals if we are lucky”.

I think that’s about all that needs to be said on the subject. Me, I’ve got boxed sets of “How I Met Your Mother”, “30 Rock”, “Chuck” and “Big Bang Theory”. Should be a great one….

Tuesday
Jun082010

XNA Cross Platform Compilation Symbols

Garden Flowers 02

I’m writing a single XNA game that should work on a whole bunch of platforms. Actually I’m going for Windows PC, Windows Phone, Xbox 360 and Zune. Which is a full house I reckon.

Anyhoo, this is a bit of a pain, as I have to make the code do different things for the different target devices. For example the Xbox and the Windows PC don’t have a touch screen so I have to simulate this in some way, or provide a different input mechanism for those platforms.

I can do this by using the symbols provided by XNA to let me select code which is passed to the compiler when the program is built. There are a bunch of them.

#if WINDOWS
// only compile this bit if we are targeting Windows PC
#endif

#if XBOX
// only compile this bit if we are targeting XBOX
#endif

#if ZUNE
// only compile this bit if we are targeting ZUNE
#endif

#if WINDOWS_PHONE
// only compile this bit if we are targeting Windows
//  Phone
#endif

It is important that you understand what is happening here. We are not selecting which code to run when the program is active, we are actually selecting which code gets compiled when the program is built.  I could do this to really confuse a programmer:

#if ZUNE
     Har Har
#endif

This is a very nasty thing to do. It means that the program will not compile if the programmer tries to build version for the Zune, it will produce an error when the compiler sees “Har Har” and ties to compile it. It will however work for every other XNA platform.

One other thing worth knowing is that the symbols that you see when editing with Visual Studio depend on the context in which the file was opened. If you have a multi-project solution (one project for Zune, another for Windows and so on) then the project that you open the file from determines which symbols are active when the file is edited and compiled. This is true even if all the entries in the project source are links to the same actual source file. In other words, the view you have of the code depends on where you opened the file from.