Apologies for the long post, but hopefully you will find the below useful regarding the resolution.
In my windows project I have a resolution class (see below) and then in my “Game1()” method I have the following:
// Change Virtual Resolution
Resolution.Initialize(graphics, Color.DarkGoldenrod);
Resolution.SetVirtualResolution(1920, 1080); // Size game is designed for
Resolution.SetResolution(1600, 900, false); // Actual size of window to display
I’m designing my game for a 1920x1080 res but set it windowed (1600x900 - so I can move it and see my debug screen etc.), but the virtual viewport in the screen is still 1920x1080, change the “false” above to true for full screen.
EDIT: Forgot to mention at the top of the DRAW() method you will need :
Resolution.BeginDraw();
At the very top of the file you will also see a “MouseHelper” this is to convert the mouse to the correct viewport virtual position.
Hopefully this will be helpful.
//====================================================
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace ScreenManagerTesting
{
public static class MouseHelper
{
/// <summary>
/// Translates the actual mouse position obtained from Mouse.GetState() into the virtual mouse position#
/// after a scaling matrix is applied to the viewport
/// </summary>
public static Point CurrentMousePosition
{
get
{
MouseState mouse = Mouse.GetState();
Vector2 mousePosition = new Vector2(mouse.X, mouse.Y);
Vector2 virtualViewport = new Vector2(Resolution.VirtualViewportX, Resolution.VirtualViewportY);
mousePosition = Vector2.Transform(mousePosition - virtualViewport, Matrix.Invert(Resolution.GetTransformationMatrix()));
Point virtualMousePosition = new Point((int)mousePosition.X, (int)mousePosition.Y);
return virtualMousePosition;
}
}
}
static class Resolution
{
static private GraphicsDeviceManager graphicsDevice = null;
static private int virtualWidth = 1920; // Size to display at / designed for size
static private int virtualHeight = 1080; // Size to display at / designed for size
static private int screenWidth = 1920; // Actual Screen size
static private int screenHeight = 1080; // Actual Screen size
static private bool fullScreen = false;
static private bool recreateScaleMatrix = true;
static private Matrix scaleMatrix;
static private int virtualViewportX;
static private int virtualViewportY;
static private Color backGroundColor; // This is used for when it's a letter/pillar box display
/// <summary>
/// Initializes the specified device.
/// </summary>
/// <param name="device">The graphics device.</param>
/// <param name="backgroundColor">Color of the background.(Default: Color.Black)</param>
static public void Initialize(GraphicsDeviceManager device, Color? backgroundColor = null)
{
Resolution.screenWidth = device.PreferredBackBufferWidth;
Resolution.screenHeight = device.PreferredBackBufferHeight;
Resolution.graphicsDevice = device;
Resolution.recreateScaleMatrix = true;
Resolution.backGroundColor = backgroundColor ?? Color.Black;
ApplyResolutionSettings();
}
static public Rectangle VirtualViewport
{
get
{
return new Rectangle(0, 0, Resolution.virtualWidth, Resolution.virtualHeight);
}
}
public static int VirtualViewportX
{
get { return virtualViewportX; }
}
public static int VirtualViewportY
{
get { return virtualViewportY; }
}
static public Matrix GetTransformationMatrix()
{
if (Resolution.recreateScaleMatrix)
{
RecreateScaleMatrix();
}
return Resolution.scaleMatrix;
}
/// <summary>
/// Sets the virtual resolution. This is the resolution the "game" is designed in.
/// If game is ran in resolution not of the same aspect ration, then it will be
/// displayed as a letterbox/pillar box.
/// </summary>
/// <param name="virtualWidth">Width of the virtual screen.</param>
/// <param name="virtualHeight">Height of the virtual screen.</param>
static public void SetVirtualResolution(int virtualWidth = 1920, int virtualHeight = 1080)
{
Resolution.virtualWidth = virtualWidth;
Resolution.virtualHeight = virtualHeight;
Resolution.recreateScaleMatrix = true;
}
/// <summary>
/// Sets the actual display resolution. e.g. the users monitor size. If smaller than current monitor
/// resolution, then will display in window (unless set to full screen)
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="fullScreen">if set to <c>true</c> [full screen].</param>
static public void SetResolution(int width = 1600, int height = 900, bool fullScreen = false)
{
Resolution.fullScreen = fullScreen;
Resolution.screenWidth = (fullScreen) ? GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width : width;
Resolution.screenHeight = (fullScreen) ? GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height : height;
ApplyResolutionSettings();
}
static private void ApplyResolutionSettings()
{
#if XBOX360
Resolution.fullScreen = true;
#endif
// If we aren't using a full screen mode, the height and width of the window can
// be set to anything equal to or smaller than the actual screen size.
if (Resolution.fullScreen == false)
{
if ((Resolution.screenWidth <= GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width)
&& (Resolution.screenHeight <= GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height))
{
graphicsDevice.PreferredBackBufferWidth = Resolution.screenWidth;
graphicsDevice.PreferredBackBufferHeight = Resolution.screenHeight;
graphicsDevice.IsFullScreen = Resolution.fullScreen;
graphicsDevice.ApplyChanges();
}
}
else
{
// If we are using full screen mode, we should check to make sure that the display
// adapter can handle the video mode we are trying to set. To do this, we will
// iterate through the display modes supported by the adapter and check them against
// the mode we want to set.
foreach (DisplayMode dm in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
{
// Check the width and height of each mode against the passed values
if ((dm.Width == Resolution.screenWidth) && (dm.Height == Resolution.screenHeight))
{
// The mode is supported, so set the buffer formats, apply changes and return
graphicsDevice.PreferredBackBufferWidth = Resolution.screenWidth;
graphicsDevice.PreferredBackBufferHeight = Resolution.screenHeight;
graphicsDevice.IsFullScreen = Resolution.fullScreen;
graphicsDevice.ApplyChanges();
}
}
}
Resolution.recreateScaleMatrix = true;
Resolution.screenWidth = graphicsDevice.PreferredBackBufferWidth;
Resolution.screenHeight = graphicsDevice.PreferredBackBufferHeight;
}
/// <summary>
/// Sets the device to use the draw pump
/// Sets correct aspect ratio
/// </summary>
static public void BeginDraw()
{
BeginDraw(Resolution.backGroundColor);
}
/// <summary>
/// Sets the device to use the draw pump
/// Sets correct aspect ratio
/// </summary>
static public void BeginDraw(Color backgroundColor)
{
FullViewport();
ResetViewport();
graphicsDevice.GraphicsDevice.Clear(backgroundColor);
}
static private void RecreateScaleMatrix()
{
Resolution.recreateScaleMatrix = false;
Resolution.scaleMatrix = Matrix.CreateScale(
(float)graphicsDevice.GraphicsDevice.Viewport.Width / virtualWidth,
(float)graphicsDevice.GraphicsDevice.Viewport.Height / virtualHeight,
1f);
}
/// <summary>
/// Sets the graphics device viewport to the screen width/height.
/// </summary>
static public void FullViewport()
{
Viewport vp = new Viewport();
vp.X = vp.Y = 0;
vp.Width = Resolution.screenWidth;
vp.Height = Resolution.screenHeight;
graphicsDevice.GraphicsDevice.Viewport = vp;
}
/// <summary>
/// Resets the viewport. Calculates the proper viewport according to aspect ration
/// </summary>
static public void ResetViewport()
{
float targetAspectRatio = GetVirtualAspectRatio();
// figure out the largest area that fits in this resolution at the desired aspect ratio
int width = graphicsDevice.PreferredBackBufferWidth;
int height = (int)(width / targetAspectRatio + .5f);
bool changed = false;
if (height > graphicsDevice.PreferredBackBufferHeight)
{
height = graphicsDevice.PreferredBackBufferHeight;
// PillarBox
width = (int)(height * targetAspectRatio + .5f);
changed = true;
}
// set up the new viewport centered in the backbuffer
Viewport viewport = new Viewport();
viewport.X = (graphicsDevice.PreferredBackBufferWidth / 2) - (width / 2);
viewport.Y = (graphicsDevice.PreferredBackBufferHeight / 2) - (height / 2);
viewport.Width = width;
viewport.Height = height;
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
virtualViewportX = viewport.X;
virtualViewportY = viewport.Y;
if (changed)
{
Resolution.recreateScaleMatrix = true;
}
graphicsDevice.GraphicsDevice.Viewport = viewport;
}
/// <summary>
/// Get virtual Mode Aspect Ratio
/// </summary>
/// <returns>aspect ratio</returns>
static public float GetVirtualAspectRatio()
{
return (float)Resolution.virtualWidth / (float)Resolution.virtualHeight;
}
}
}