[SOLVED] MonoGame is always rendering at 800 x 480 in 3D

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:

For some reason, MonoGame won’t change the 3D rendering resolution. The UI is scaling fine, but the 3D rendering isn’t

I’ve tried setting a RenderTexture, I’ve added the following code to OnResize():

public void OnClientSizeChanged(object sender, EventArgs e)
{
	if (Window.ClientBounds.Width > 0 && Window.ClientBounds.Height > 0 && !resizing)
	{
		resizing = true;

		Graphics.PreferredBackBufferWidth = Window.ClientBounds.Width;
		Graphics.PreferredBackBufferHeight = Window.ClientBounds.Height;
		Graphics.ApplyChanges();
		renderTarget = new RenderTarget2D(Device, Window.ClientBounds.Width, Window.ClientBounds.Height, true, Device.DisplayMode.Format, DepthFormat.Depth24);
		Viewport = GraphicsDevice.Viewport;
		GraphicsDevice.SetRenderTarget(renderTarget);
		resizing = false;
	}
}

Note: Graphics is the GraphicsDeviceManager variable.

This has been bugging me for the past couple days. Any help would be greatly appreciated.

Hi, welcome to the forums,

What is the hardware you are running on and also, what’s in your initialiser code?
And when does this occur?

Hardware:
Intel Core i3-4010U @1.70GHz
4.0 DDR3 RAM
Integrated Graphics :frowning:

Code:

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.

1 Like

You need to re-initialize your view/projection matrix after resizing, because the aspect ratio changed

1 Like

Thanx @reiti.net & @Kimimaru, that fixed my problem :slight_smile: