I’m currently trying to implement window scaling in my MonoGame game, which I’m developing to learn how the engine works, but when I scale the window, the 3D rendering breaks, as seen below:
public Client() : base()
{
_inst = this;
Graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
Window.Title = "Minecraft";
IsMouseVisible = true;
// When we lose focus
Deactivated += (sender, e) =>
{
Paused = true;
};
Exiting += OnQuit;
GameWindow = Window;
Paused = true;
CurrentState = new MainState();
threadManager = new ThreadManager();
}
protected override void Initialize()
{
EmptyTexture = new Texture2D(GraphicsDevice, 1, 1);
EmptyTexture.SetData(new Color[] { new Color(0, 0, 0, 0) });
Viewport = GraphicsDevice.Viewport;
Device = GraphicsDevice;
Window.AllowUserResizing = true;
Window.ClientSizeChanged += OnClientSizeChanged;
base.Initialize();
if (GameSettings.VSyncEnabled) {
Graphics.SynchronizeWithVerticalRetrace = true;
IsFixedTimeStep = true;
} else if (GameSettings.UnlimitedFPS) {
Graphics.SynchronizeWithVerticalRetrace = false;
IsFixedTimeStep = false;
} else {
Graphics.SynchronizeWithVerticalRetrace = false;
IsFixedTimeStep = true;
TargetElapsedTime = TimeSpan.FromSeconds(1d / GameSettings.FPS*10);
}
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
SpriteBatch = new SpriteBatch(GraphicsDevice);
TerrainTexture = Content.Load<Texture2D>("terrain");
Font = Content.Load<SpriteFont>("MainFont");
Char = Content.Load<Texture2D>("char");
CrosshairTexture = Content.Load<Texture2D>("Crosshair");
Mob player = new Mob(Char, Vector3I.Zero);
Calm1 = Content.Load<SoundEffect>("calm1");
Calm1Instance = Calm1.CreateInstance();
AudioEmitter = new AudioEmitter();
AudioListener = new AudioListener();
ObjectPos = Vector3.Zero;
Calm1Instance.Apply3D(AudioListener, AudioEmitter);
Calm1Instance.IsLooped = true;
Calm1Instance.Volume = 1f; // Full volume.
Calm1Instance.Play();
RaiseLoadEvent(Content);
//Initialise the RenderTarget
renderTarget = new RenderTarget2D(Device, Window.ClientBounds.Width, Window.ClientBounds.Height, true, Device.DisplayMode.Format, DepthFormat.Depth24);
GraphicsDevice.SetRenderTarget(renderTarget);
Window.Title = "Minecraft";
}
The Window starts at 800 x 480. When I change the resolution of the Window, the 3D rendering gets stretched to fix the bounds of the Window (as seen in the screenschot, where it’s clearly exaggerated).
From what I’ve gathered, it sounds like what you want to do is render to a high resolution then downscale; is this correct?
If so, create a RenderTarget at a designated resolution (Ex. 1920x1080), render everything to it, then draw that RenderTarget to the backbuffer, scaling by the size of the game window. For example, if I had a 1920x1080 RenderTarget with a 960x540 game window, I’d render the RenderTarget at a scale of (.5, .5).
Make sure to dispose the previous RenderTarget before assigning the new one, as the unmanaged memory won’t be reclaimed.