How to keep the aspect ratio of a render target drawn on screen when window size is changed?

Previously I have adapted my game to different screen sizes using a transformation matrix. Now since I need to do some post-processing effect to the game, I need the game to draw everything onto a render target first, then draw the processed rendertarget onto the back buffer.

I am using this line to draw the render target, and it got drawn successfully:
spriteBatch.Draw(renderTarget, Vector2.Zero, Color.White);

However, when I change the game window size, the aspect ratio of the render target drawn also changes with the game window, which is how it is supposed to be.

How can I keep the render target drawn to the center of the screen (with black bars on either the top and the bottom or the left and the right, if the aspect ratio of the window is different from that of the rendertarget) with the correct aspect ratio? I have tried some other overloads of the SpriteBatch.Draw method, but none of them worked… :frowning:

I’ve got a piece of code I reuse for doing resolution & virtual resolution… It should handle window size changes:

https://github.com/dmanning23/ResolutionBuddy/blob/master/Source/Resolution.cs

An example of how to use it:

Also available as ResolutionBuddy Nuget package for android, iOS, and DesktopGL

Cheers!

Hi @dmanning23 , thanks for sharing your code! Actually I have something similar to your Resolution class that utilizes a transform matrix and draw things onto the screen with the right scale, acpect ratio and position. My problem is that if I first draw things to a render target instead of the back buffer, then draw the render target to the back buffer, the image will look distorted/stretched.

So basically I just want to figure out how to draw a render target so it remains the same aspect ratio and got centered on the screen (which means there could be black bars on the top and bottom/sides).

HI! I must be misunderstanding, because this sounds like the easiest step in everything you’ve done.
But just in case this might help:

I render my game to a render-target…

Then you can scale that render-target to any size… Just scale both axis uniformly, by the same factor.

The aspect ratio is a minor issue… You just draw your render-target higher or lower on the screen depending on aspect ratio…

… And use Clear(Black) before each draw, you get black bars around the image…

I am working on a 2d game that does this. Its called “grinder” and you can find it here on the forums… Supports any screen size, and the top 3 aspect ratios… The HARDEST part of this, is the time consuming interface for user selection. But you could probably auto detect your way out of that :slight_smile:

Hi @monopalle, thanks for your solution! I guess part of the reason why my render target gets drawn incorrectly is because that it has stuff drawn outside the viewport, because the size of the render target was set to 1080p to deal with screen size changes (this issue never mattered before because things were drawn directly to the back buffer using a method that is very similar to @dmanning23’s resolution class). Probably I need to specify the source rectangle on the render target when drawing it to the back buffer using spriteBatch.Draw(renderTarget, desitinationRectangle, sourceRectangle, Color.White), but the weird thing is that the scale/portion of the content drawn to the back buffer also changes (meaning that the size of the source rectangle changes with the size of the game window). Currently I have no clue how to solve this problem… :frowning:

Hey!
First of all, know that I had a lot of issues with that stuff too… I had to “trial and error” my way through a lot of it, and understand it in reverse. It can seem complicated, hard to think about, hard to plan…

I would like to help you further, but I have read your post a bunch of times, and I cant seem to understand where you need help at this point…? If you could maybe use shorter sentences, or really spell it out for me with a question-mark at the end, maybe I could help you better…

Or, you can wait for a native english speaker :wink: lol.

Hi @monopalle ,

Sorry for the mess. So my issue is as follows:

  1. I draw things to a render target first, then draw the render target to the back buffer. This is different from drawing things directly to the back buffer.

  2. When drawing things, I use a transformation matrix (very similar to @dmanning23 's Resolution class ) so that things can be projected to a calculated view port with the correct size, position and aspect ratio. This method works well when things are drawn directly to the back buffer. But with the method above, the result is not desirable: the image is either squashed/stretched when the game window size changes, and some of the stuff that is supposed to be off-screen also show on screen.

  3. Here is my guess: because the size of the render target is set to 1920 x 1080 (to support ), when things got drawn to the render target, the off-screen part also got drawn to it. So when the render target got drawn to the back buffer, some stuff that should be off-screen also shows up.

  4. I’m trying to solve the issue by specifying the source rectangle on the render target and destination rectangle on the back buffer with the line:
    spriteBatch.Draw(renderTarget, desitinationRectangle, sourceRectangle, Color.White)
    But I don’t know how to get the right source rectangle – the bounds of the calculated view port (which is used in step 2 above) doesn’t seem to be it. Every time I change the window size, the portion of the render target drawn to the screen changes.

Sorry again about the messy descriptions. I know they can be really confusing…

Ah never mind… I finally figured out why… I assigned another view port when drawing stuff onto the render target and forgot to switch back to the full screen view port when drawing the render target onto the back buffer… Really sorry about the fuss… :joy:

Nice, I was just about to get into this whole “essay” project :slightly_smiling:
So everything is tip-top?

Haha, thanks man! At least for now it is working properly. I still need to get a functional HLSL version of the xBR shader (either by searching online or translating one myself). Too bad the ones I found do not work… :sob:

Yeah, good luck with that. Last time I tried shaders, I couldnt even find a working tutorial
-But that is a while back.

If you happen across an example that works, it’d be cool if you posted it here…
Something ‘noob’ would be nice. I just want to get something RUNNING this time :slightly_smiling: