Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I tend to opt for the "render to texture" solution so that I can allow for things like full screen without distortions.</p> <p>The class I use to achieve this usually looks something like:</p> <pre><code>class VirtualScreen { public readonly int VirtualWidth; public readonly int VirtualHeight; public readonly float VirtualAspectRatio; private GraphicsDevice graphicsDevice; private RenderTarget2D screen; public VirtualScreen(int virtualWidth, int virtualHeight, GraphicsDevice graphicsDevice) { VirtualWidth = virtualWidth; VirtualHeight = virtualHeight; VirtualAspectRatio = (float)(virtualWidth) / (float)(virtualHeight); this.graphicsDevice = graphicsDevice; screen = new RenderTarget2D(graphicsDevice, virtualWidth, virtualHeight, false, graphicsDevice.PresentationParameters.BackBufferFormat, graphicsDevice.PresentationParameters.DepthStencilFormat, graphicsDevice.PresentationParameters.MultiSampleCount, RenderTargetUsage.DiscardContents); } private bool areaIsDirty = true; public void PhysicalResolutionChanged() { areaIsDirty = true; } private Rectangle area; public void Update() { if (!areaIsDirty) { return; } areaIsDirty = false; var physicalWidth = graphicsDevice.Viewport.Width; var physicalHeight = graphicsDevice.Viewport.Height; var physicalAspectRatio = graphicsDevice.Viewport.AspectRatio; if ((int)(physicalAspectRatio * 10) == (int)(VirtualAspectRatio * 10)) { area = new Rectangle(0, 0, physicalWidth, physicalHeight); return; } if (VirtualAspectRatio &gt; physicalAspectRatio) { var scaling = (float)physicalWidth / (float)VirtualWidth; var width = (float)(VirtualWidth) * scaling; var height = (float)(VirtualHeight) * scaling; var borderSize = (int)((physicalHeight - height) / 2); area = new Rectangle(0, borderSize, (int)width, (int)height); } else { var scaling = (float)physicalHeight / (float)VirtualHeight; var width = (float)(VirtualWidth) * scaling; var height = (float)(VirtualHeight) * scaling; var borderSize = (int)((physicalWidth - width) / 2); area = new Rectangle(borderSize, 0, (int)width, (int)height); } } public void BeginCapture() { graphicsDevice.SetRenderTarget(screen); } public void EndCapture() { graphicsDevice.SetRenderTarget(null); } public void Draw(SpriteBatch spriteBatch) { spriteBatch.Draw(screen, area, Color.White); } } </code></pre> <p>And then in my game, the initialisation tends look something like:</p> <pre><code> VirtualScreen virtualScreen; protected override void Initialize() { virtualScreen = new VirtualScreen(96, 54, GraphicsDevice); Window.ClientSizeChanged += new EventHandler&lt;EventArgs&gt;(Window_ClientSizeChanged); Window.AllowUserResizing = true; base.Initialize(); } void Window_ClientSizeChanged(object sender, EventArgs e) { virtualScreen.PhysicalResolutionChanged(); } </code></pre> <p>With the all important call to Update:</p> <pre><code>protected override void Update(GameTime gameTime) { virtualScreen.Update(); base.Update(gameTime); } </code></pre> <p>And then the act of drawing itself:</p> <pre><code> protected override void Draw(GameTime gameTime) { virtualScreen.BeginCapture(); GraphicsDevice.Clear(Color.CornflowerBlue); // game rendering happens here... virtualScreen.EndCapture(); GraphicsDevice.Clear(Color.Black); spriteBatch.Begin(); virtualScreen.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); } </code></pre> <p>With this in place, I can basically stop caring about resolution at all and just focus on the game.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload