Is it possible to make zoom on a RenderTarget?

After solving my problems with the resolution, I have a fast question.

There is a easy way to zoom in the game? Now I use RenderTargets for scaling the screen to diferent resolutions (always multiple of itself(x2,x3…)), and I don’t know if there are incompatibilities with that. Maybe I need to create some kind of camera or something.

Thanks in advance!

When rendering the render target to the screen, use the SpriteBatch.Draw overload that takes a source rectangle and a destination rectangle. Set the source rectangle to the section of the render target you want to fill the screen with. Set the destination rectangle to the screen bounds.

The other alternative is to do the zoom when drawing to the render target by altering the orthographic projection or camera in that case.

Yeah, if you use a camera you can probably manage. Usually that just means one transformation matrix (in 2D) that should be applied to all positions and scales of sprites (you can pass it to SpriteBatch.Begin).

If I were to implement this I think I’d create a class that delegates to spritebatch, but applies some additional transformation based on screen size since the transformation should be applied to everything anyway. That way the api calls are the same as calling spritebatch, and you don’t have to bother thinking about it in other game code.

A more obvious option is to just have a seperate camera class that you can query for a matrix to apply when drawing. You can find a lot examples of these if you google a bit. I have an implementation somewhere too if you’re interested. This option is often used when you want an in-game camera. For example when moving around in an rpg or sidescroller. Because you need to ask the camera for the matrix it doesn’t automatically transform everything and you can draw a static HUD.

Note that the first and second option don’t have to be exclusive, I just want to say that you can embed the screen size stuff in your game engine (first option) or implement it like a regular camera (second option).

Could you be more concrete?
I assume that you are saying that I need to modify this line
spriteBatch.Draw(_nativeRenderTarget, _actualScreenRectangle, Color.White);
that is the one that shows the rendertarget to the screen, but didn’t undesrtood completely what I should do.

Also I would be interested in your camera implementation, cause I also have to make a top down rpg part for the game, and would help me a lot to understand some things haha

Hi, Welcome to the world of MonoGame.

When I was looking into it a bit last year I came across the below site, it seemed to have worked for what I was messing around with, hopefully it will be of some use.

http://www.david-amador.com/2010/03/xna-2d-independent-resolution-rendering/

However since then I’ve been told about MonoGame.Extended (only looked at it recently thanks to @Jjagg point me in that direction) and that appears to have camera adaptors in there that might be of use. Download the code as it has quite a few sample projects.

I set up a gist :slight_smile: https://gist.github.com/Jjagg/a5985f832fd8353ffe44eee009280ab0
In your case you can update the position each frame to center your character (or sway towards him) or inherit from camera and make a FollowCamera that returns the player position as translation or something. Transforming with InverseTransform of your Camera instance ‘applies’ the camera.
Note that the viewport bounds in camera aren’t updated when the window is resized.

Woops, I’ve run into a “problem”.

When I zoom into an image, it gets too blurry. Isn’t there a way to make a camera pixel perfect? (yeah, I know that if I zoom into a sprite it wont look, rather deformated, but not blurry).

Also, I’m trying to make the camera make a zoom 50 times (+0.01) over a little time, to make an animation, but using a “for” for that isn’t working, it makes the 50 zoom too fast.

there is a samplerstate clamp or something for spritebatch might help with the pixel thing.

Are you doing the +0.01 in a for loop in a single frame? You might be best using a bool and doing sometihng like

Update(gt)
{
if(zoom) +0.01;
}

That way it will update 0.01 each frame, aka 0.60 per second. If it is in a loop like

Update(gt)
{
for (zoom < 50) zoom += 0.01;
}

It will try to run that entire thing in one frame.

If you want extra detail when zoomed in, then you need to draw the extra detail.
If you want the pixels to get larger without any blur, you need to use SamplerState.PointClamp when drawing the render target to the screen.

PointClamp is what I needed, thanks!

I have the code in the “checkKeyboard” event that I use for the input. This is what I was using:

if (oldState.IsKeyUp(Keys.R) && newState.IsKeyDown(Keys.R))
{
for (int i = 0; i < 5; i++)
{
_camera.Zoom += (float)0.05;
}

            }

But I don’t know how to put it like you’ve said. I don’t control too much the gameTime thing and so.

That for loop will run in 1 frame. ie it will take 1/60 of a second (0.01667 seconds) so really fast and you won’t notice it because it won’t draw until the frame updates and by that point it will have finished and drawn.

You basically just need this

if (oldState.IsKeyUp(Keys.R) && newState.IsKeyDown(Keys.R))
{
_camera.Zoom += (float)0.05;
}

and just need to make sure it doesn’t go over 5. This way it will run every frame, and 0.05/5 = 100 frames which means it will take nearly 2 seconds to finish so will be slower and smooth.

If you are using MonoGame.Extended I believe the camera class has a bounds/clamp property or max zoom etc. so you can specify that as 5 and you are done.

Check out more at https://github.com/craftworkgames/MonoGame.Extended/blob/develop/Source/MonoGame.Extended/Camera2D.cs#L62