Maintaining a fixed aspect ratio

November 17th, 2009 | 6 comments

It’s quite common for a game to desire a fixed aspect ratio. Most games on the Xbox 360 are fixed at a 16:9 aspect ratio because they assume you’re on a 720p or 1080p widescreen television. If you are on a television that isn’t 16:9, the Xbox 360 will automatically letterbox your game for you. However there are times when knowing how to lock your own aspect ratio is useful:

  1. If you want to lock your game at a 4:3 aspect ratio, the Xbox 360 will not pillarbox the game for you. It will instead stretch it across the backbuffer, ruining your game.
  2. There is neither automatic letterboxing or pillarboxing on the PC. If you want your game to run at a maximum resolution and maintain aspect ratio, you have some work to do.

With all this in mind, I’ve written up a little sample showing how to handle this in a very simple manner. It essentially boils down to a few simple steps:

  1. Create your backbuffer at the display adapter’s current resolution.
  2. When drawing, first set the viewport to the full backbuffer and clear black.
  3. Compute the largest viewport of the desired aspect ratio that fits on screen and set that to the device.
  4. Clear the screen again (it will only clear the viewport area) and draw your game.

Step three is the only real tricky part and that’s not to complex. Here’s my method for handling that:

int width = GraphicsDevice.PresentationParameters.BackBufferWidth;
int height = (int)(width / targetAspectRatio + .5f);
if (height > GraphicsDevice.PresentationParameters.BackBufferHeight)
{
   height = GraphicsDevice.PresentationParameters.BackBufferHeight;
   width = (int)(height * targetAspectRatio + .5f);
}

As you can see, that’s not really that complex.

With this in place you can easily make a 4:3 game for the Xbox or make any game maintain a fixed aspect ratio on the PC where monitors can be just about any aspect ratio imaginable. Feel free to download and use the code from my little sample: FullScreenAspectRatio.zip.

Here’s a screenshot from the test app running a fixed 4:3 aspect ratio on my computer (which runs natively at 1920×1080):

FullScreen Aspect Ratio


Possibly Related Posts

(Automatically Generated)
Extension Methods and You
Expanded site width
A More Robust Exception System
Quick and Dirty Screenshots in PC Games
Split screen in SunBurn

  1. November 18th, 2009 at 01:19

    Thanks a lot. Really helpful =)
    Just one noob question, what does the Min, MaxDepth do?

  2. November 18th, 2009 at 01:19

    Thanks a lot. Really helpful =)
    Just one noob question, what does the Min, MaxDepth do?

  3. November 18th, 2009 at 17:30

    Sets the minimum and maximum depth values when rendering. Generally those are 0 and 1, but to be safe you could get the default values in LoadContent and reuse them if you wanted to be absolutely sure.

  4. November 18th, 2009 at 17:30

    Sets the minimum and maximum depth values when rendering. Generally those are 0 and 1, but to be safe you could get the default values in LoadContent and reuse them if you wanted to be absolutely sure.

  5. December 12th, 2009 at 02:31

    Do you have any idea why this works but when setting a render target the bars disappear?

    I’m creating the render target like this

    PresentationParameters pp = GraphicsDevice.PresentationParameters;
    lightMap = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, 1, SurfaceFormat.Color, pp.MultiSampleType, pp.MultiSampleQuality);

  6. December 12th, 2009 at 02:31

    Do you have any idea why this works but when setting a render target the bars disappear?

    I’m creating the render target like this

    PresentationParameters pp = GraphicsDevice.PresentationParameters;
    lightMap = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, 1, SurfaceFormat.Color, pp.MultiSampleType, pp.MultiSampleQuality);

You must be logged in to post a comment.