Viewport confusion

I want the game to adapt to the screen resolution, but I want the viewport to always stay the same, so the game basically just resizes itself when running on different PCs. How do I do it?
So, for example, screen resolution is 1920x1080 and the viewport is 640x480. How do I stretch those 640x480 onto 1920x1080? Is that even possible?
If this did not make any sense, I’ll try to explain another way.
Thanks in advance!

You’ll want to do your rendering to a RenderTarget2D.

Basically, create a RenderTarget2D object to the size you want to draw to.

Inside your ‘Draw’ method you use GraphicsDevice.SetRenderTarget(“name of your RenderTarget2D object”) so that all draw calls go to that rather than the actual screen.

Once all drawing is done you use GraphicsDevice.SetRenderTarget(null) to switch back to the screen.

Then use the spritebatch to perform a 2D draw, passing your RenderTarget2D as the image to draw across your entire screen.

I would recommend looking into writing custom shaders for the 2D draw, since you can then implement custom filtering to improve the scaling.

If you’re planning on your game being widescreen I’d recommend making your viewport a widescreen resolution as well so you keep the pixel ratio the same when you upscale. e.g. 640x360 is good for a retro 2D look without being too low resolution, if you want something higher than that, try 800x450.


Thank you, I’ll definitely try that. Is there any other way?

and how do implement multiple spriteBatch.Draw()? Because I have multiple draw calls per frame and they all differ, like one is SamplerState.PointClamp and the other is SamplerState.PointWrap for example

I’ve you’re using 2D you ‘could’ rescale all your sprites to the higher resolution when you draw by setting a larger destination draw size, but that can create some issues with the look of the sprites.

I think you mean multiple spritebatch.Begin(), and no I don’t know how to manage that as in everything I’ve done I’ve always used a single spritebatch.Begin() where all draw calls use the same setting.

You could potentially handle different sampler states using a custom shader, but passing the information on a per-draw call basis for each would be tricky, certainly not impossible.

I don’t know if other people may have any better suggestions.

1 Like

okay, it’ll do, thanks for help!

omg dude I got it, that is AWESOME! Thank you a lot!!!

What you are describing is sometimes called resolution independence.

What I like to do is create a transformation matrix that’s passed in as a parameter to each SpriteBatch.Begin call. I wrote a tutorial about it on my blog.

We’ve also implemented them as viewport adapters in MonoGame.Extended.

thanks, but RenderTarget helped :slight_smile:

I’m glad you found a solution smile

I’ve never really played with the RenderTarget method myself. It seems like a good way to do it. I’ll have to look into how that works sometime.