Simple GUI and Menu system

I’ve been silent in the blog for the last couple of weeks mainly because I was on vacation and then cleaning up and commenting all the code I’ll introduce in IGF v0.4.0.0. During that time, a few of IGF v0.3 users came back to me letting me know they found a very annoying bug: Deferred renderer wasn’t working on Xbox 360 and worse freezing the system.

I was really surprised as I test all my samples and they all worked on Windows when I switched from Forward to Deferred rendering. Since I’m adding nothing special for Xbox 360 Deferrred SunBunr rendering, I was really sure it would work as is on the console too: I was wrong!

I raised the point to John at SynapseGaming as stepping through the entire rendering pipeline, I couldn’t find any reason why such thing was happening and he told me he’ll have a look at it.

I’ll therefore wait this bug to be solved before releasing the IGF v0.4.0.0 which I had ready for a release today :(

However, I won’t stay inactive until then and decided to move on working on the next set of features. For v0.5, IGF will gain two new features that are highly related design wise and one of which received a lot of votes in the Feature Request system: a Simple GUI & Menu system.

I already had a working prototype and I started porting it to IGF which was achieved really easily (couple of hours). I’m now testing it on my systems to make sure it works in all cases ;)

As usual, adding a new feature to IGF starts by adding a manager to the SunBurn SceneInterface in the Application.InitializeSunBurn() method override. This time you’ll add the GuiManager like this:

// in your own Application class override
public override void InitializeSunBurn()
{
   SunBurn.AddManager(new GuiManager(GraphicsDeviceManager);

   CreateRenderer(Renderer.Forward);
}

Then, adding a simple Label in your game would be as easy as the following code in your GameState.Initialize() overriden method:

/// <summary>
///   Initializes the GameState. Override this method to load any non-graphics resources and query for any required services.
/// </summary>
public override void Initialize()
{
    // we retrive the GuiManager instance
    var gui = SunBurn.GetManager<GuiManager>(true);

    // we create a Screen instance in which we'll be adding Controls
    var testScreen = new Screen(100, 100, true);
    // we then create a Label passing the SpriteFont path and the initial text string
    var testLabel = new Label("Fonts/MenuItemFont", "Hello World");
    // we ask the GameState to PreLoad the Label SpriteFont
    PreLoad(testLabel);
    // we add the Label to the Screen
    testScreen.Add(testLabel);

    // we finally add the Screen to the GuiManager
    gui.AddScreen(testScreen);
}

You may be wondering why we need the Screen class? Well, it’s basically a container that will ensure the rendering is performed only when required (state or property changes). Moreover, if you look at its constructor, the last argument is a boolean and it tells the Screen if it should render to screen directly or not. If you set this to false, you’ll have the ability to get all controls rendered through the Screen in a Texture2D that you’ll potentially want to use in a 3d quad instead of rendering directly to the screen.

Here is a simple example of the Menu system rendered on Textures and used in multiple quads that are placed in SunBurn 3D scene. Hope you’ll find that useful ;)

7 Comments

  1. Greg A says:

    I am getting the following exception when trying to render a Lable with v0.8 of IGF.

    XNA Framework Reach profile requires mipmapped Texture2D sizes to be powers of two. To use a non power of two Texture2D, remove the mipmaps.

    I am trying to render test “Hello World” not an image. Why does test need to be to the power of 2?

  2. Philippe Da Silva says:

    Hi, Could you please tell me which version you are using? Indie or Pro? Windows, Xbox 360 or WP7 builds?
    Thanks

  3. Greg A says:

    I am using Sunburn Pro for WP7 and v.8 of IGF.

    Thanks,
    Greg

  4. Greg A says:

    This is happening in the Screen.PrepareRenderTarget

    _renderTarget2D = new RenderTarget2D(device, Width, Height, true, SurfaceFormat.Color, DepthFormat.None, Application.Graphics.GraphicsDevice.PresentationParameters.MultiSampleCount, RenderTargetUsage.PreserveContents);

    The height is set to 480 and the width is set to 800 (the phone screen size)

    I also tried changing the true to false to turn off mipmaps, but still got this exception.

  5. Greg A says:

    I changes the menuScreen to 512, 512 and I am able to get the buttons to render now.

    var playerInput = Application.Input.GetPlayerInput(PlayerIndex.One);
    _menuScreen = new Screen(true, true, playerInput, 512, 512);

    So in order to do fullscreen games on WP7 would I set the screen size to 1024 x 1024 and only use 800 x 480?

  6. Philippe Da Silva says:

    Hi Greg,

    That’s actually something I need to look at since the WP7 builds of IGF aren’t fully tested. The WP7 support is still alpha since I don’t have much experience developing for this platform.

    I know it works but there might be some hickups, like the one you just found, that I need to get solved.

    I’ll therefore look onto it and see what is the best option to render GUI with WP7.
    I guess your suggested solution is the best one until then.

    By the way, comments in this blog aren’t the best place to get support as they are lost on the blog and I’d rather have you post on the discussions tab in http://igf.codeplex.com so that other IGF users may find answers to related issues while searching for them.
    Thanks

  7. Greg A says:

    Thanks Philippe for the reply. I’ll be sure to use the discussions going forward.

Leave a Reply