Scaling entire screen in XNA

Adam Rezich picture Adam Rezich · Sep 29, 2011 · Viewed 7.7k times · Source

Using XNA, I'm trying to make an adventure game engine that lets you make games that look like they fell out of the early 90s, like Day of the Tentacle and Sam & Max Hit the Road. Thus, I want the game to actually run at 320x240 (I know, it should probably be 320x200, but shh), but it should scale up depending on user settings.

It works kind of okay right now, but I'm running into some problems where I actually want it to look more pixellated that it currently does.

Here's what I'm doing right now:

In the game initialization:

    public Game() {
        graphics = new GraphicsDeviceManager(this);
        graphics.PreferredBackBufferWidth = 640;
        graphics.PreferredBackBufferHeight = 480;
        graphics.PreferMultiSampling = false;

        Scale = graphics.PreferredBackBufferWidth / 320;
    }

Scale is a public static variable that I can check anytime to see how much I should scale my game relative to 320x240.

In my drawing function:

spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Matrix.CreateScale(Game.Scale));

This way, everything is drawn at 320x240 and blown up to fit the current resolution (640x480 by default). And of course I do math to convert the actual coordinates of the mouse into 320x240 coordinates, and so forth.

Now, this is great and all, but now I'm getting to the point where I want to start scaling my sprites, to have them walk into the distance and so forth.

Look at the images below. The upper-left image is a piece of a screenshot from when the game is running at 640x480. The image to the right of it is how it "should" look, at 320x240. The bottom row of images is just the top row blown up to 300% (in Photoshop, not in-engine) so you can see what I'm talking about.

image showing the difference in scaling as the resolution changes

In the 640x480 image, you can see different "line thicknesses;" the thicker lines are how it should really look (one pixel = 2x2, because this is running at 640x480), but the thinner lines (1x1 pixel) also appear, when they shouldn't, due to scaling (see the images on the right).

Basically I'm trying to emulate a 320x240 display but blown up to any resolution using XNA, and matrix transformations aren't doing the trick. Is there any way I could go about doing this?

Answer

user155407 picture user155407 · Sep 29, 2011

Render everything in the native resolution to a RenderTarget instead of the back buffer:

        SpriteBatch targetBatch = new SpriteBatch(GraphicsDevice);
        RenderTarget2D target = new RenderTarget2D(GraphicsDevice, 320, 240);
        GraphicsDevice.SetRenderTarget(target);

        //perform draw calls

Then render this target (your whole screen) to the back buffer:

        //set rendering back to the back buffer
        GraphicsDevice.SetRenderTarget(null);

        //render target to back buffer
        targetBatch.Begin();
        targetBatch.Draw(target, new Rectangle(0, 0, GraphicsDevice.DisplayMode.Width, GraphicsDevice.DisplayMode.Height), Color.White);
        targetBatch.End();