Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am developing a game with XNA and I am a little desperate with resolutions. For now I have only implemented the main menu but I want to get a game that is independent of the resolution. As I am a beginner, I haven't taken into account the resolution so far. When I started to change the resolution, began my real headache.

The background image that I use has a 1920x1080 resolution, so it has an aspect ratio 16:9 (panoramic). The initial resolution was 800x600, so the background image looks stretched. The same happens with resolutions with aspect ratio 4:3 (640x480, 1024x768...).

Before post in this forum, I search information on Internet and I find this solution (and similar in other pages). The solution offered by the site seems perfect to me at first because I wasn't thinking of using two resolutions (one internal for drawing and one that correspond to the size of the windows).

However I has been observing some problems:

  • The first thing is the fullscreen mode. When I turns the game in fullscreen mode and its resolution is lower than the OS's resolution, the game doesn't stretch the resolution to fill the entire screen. This makes that the game looks at the center of the screen but appears black border on both sides of the screen (as in this image)

  • The second problem is again with the aspect ratio. As I say above, the aspect ratio of my background image is 16:9. However the resolutions that I am trying has an aspect ratio of 4:3. With the page solution, I has the same problem (the background image seens to be stretched). I started to research the code to find a solution and changing the function RecreateScaleMatrix() to this:


private static void RecreateScaleMatrix() 
{
    _dirtyMatrix = false;
    float aspect = 16.0f / 9.0f;
    _scaleMatrix =
        Matrix.CreateScale((float)_device.GraphicsDevice.Viewport.Width / _virtualWidth,
                           (float)_device.GraphicsDevice.Viewport.Height / _virtualHeight, 1f) *
        Matrix.CreateScale(1, EngineManager.GameGraphicsDevice.Viewport.AspectRatio / aspect, 1) *
        Matrix.CreateTranslation(0,
                                 (_device.GraphicsDevice.Viewport.Height - (_device.GraphicsDevice.Viewport.Height / aspect)) / 4.0f, 
                                 0);
}

seems to be solved, but only on certain resolutions and futher reducing the rectangle which show the final result.

I have been thinking all these problems all day and I realized that without knowing exactly the resolution of the image to draw in advance (it can be have a aspect ratio of 4:3, 16:9 or other) is almost impossible to draw an image clearly.

Does anyone know how to solve all these problems? I have lost many days only in this and I am really frustrated.

Thanks in advance.

PD: Excuse my English level.

share|improve this question
add comment

1 Answer

The most simple answer is what you've already found: draw everything internally to a RenderTarget with a fixed resolution and after that use the RenderTarget as a texture and draw it as large as possible. You should be able to fill the entire screen if the aspect ratio is the same. Simply use the Spritebatch.Draw overload that uses a destination rectangle. If you use an internal resolution with an aspect ratio of 16:9 then you should create a rectangle like this:

//If the internal resolution and target resolution are both 16:9
Rectangle dest = new Rectangle
    (
        0,
        0,
        graphics.ViewPort.Width,
        graphics.ViewPort.Height
    );

//If the internal resolution is 16:9 and target resolution is 4:3
int height = (int)(graphics.ViewPort.Width * (16.0/9.0));
Rectangle dest = new Rectangle
    (
        0,
        graphics.ViewPort.Height - (int)(height / 2.0),
        graphics.ViewPort.Width,
        height
    );

Another approach would be to make sure that all text and GUI elements are withing a safe in the render target that has a 4:3 aspect ratio and then simply discard the most left and right part on a 4:3 screen. (This might give players with a 16:9 aspect ratio an advantage since they will have a larger FOV).

Tip: if you are developing your game for the XBOX360 you can jus develop for one resoltion since the XBOX will do the up and down scaling automatically for you. You should use an internal resolution of 720P since this is the highest resolution that the XBOX upscaler/downscaler can scale down to old-TV resolution.

Edit:

See the comments: the general formula for the destination rectangle that works for all aspect ratios where width >= height would be:

double aspectratio = ((double)graphics.ViewPort.Width / (double)graphics.Viewport.Height);
    int height = (int)(graphics.ViewPort.Width * aspectratio;
    Rectangle dest = new Rectangle
        (
            0,
            graphics.ViewPort.Height - (int)(height / 2.0),
            graphics.ViewPort.Width,
            height
        );
share|improve this answer
1  
Don't forget about 16:10 which is also a fairly common monitor size as well. –  Matthew Scharley Aug 13 '12 at 1:25
    
Ah you're absolutely right! I've added the general formula that should work for all aspect ratios where the screen width >= screen height. –  Roy T. Aug 13 '12 at 6:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.