resolution scaling

main
Evan Hemsley 2020-07-17 13:37:54 -07:00
parent 670ac8e247
commit 7f11936e5e
4 changed files with 140 additions and 13 deletions

View File

@ -0,0 +1,16 @@
using Encompass;
namespace PongFE.Components
{
public struct PlayAreaComponent : IComponent
{
public int Width { get; }
public int Height { get; }
public PlayAreaComponent(int width, int height)
{
Width = width;
Height = height;
}
}
}

View File

@ -1,7 +1,9 @@
using System.IO; using System.IO;
using Encompass; using Encompass;
using IndependentResolutionRendering;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using PongFE.Components;
using PongFE.Engines; using PongFE.Engines;
using PongFE.Enums; using PongFE.Enums;
using PongFE.Messages; using PongFE.Messages;
@ -20,29 +22,42 @@ namespace PongFE
SpriteBatch SpriteBatch { get; set; } SpriteBatch SpriteBatch { get; set; }
Texture2D WhitePixel { get; set; } Texture2D WhitePixel { get; set; }
RenderTarget2D GameRenderTarget { get; set; }
DynamicSpriteFont ScoreFont { get; set; } DynamicSpriteFont ScoreFont { get; set; }
const int PLAY_AREA_WIDTH = 1280;
const int PLAY_AREA_HEIGHT = 720;
public PongFEGame() public PongFEGame()
{ {
graphics = new GraphicsDeviceManager(this); graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 1280; graphics.PreferredBackBufferWidth = 1680;
graphics.PreferredBackBufferHeight = 720; graphics.PreferredBackBufferHeight = 1050;
graphics.PreferMultiSampling = true; graphics.PreferMultiSampling = true;
Content.RootDirectory = "Content"; Content.RootDirectory = "Content";
Window.AllowUserResizing = true; Window.AllowUserResizing = false;
IsMouseVisible = true; IsMouseVisible = true;
IsFixedTimeStep = true; IsFixedTimeStep = true;
} }
protected override void LoadContent() protected override void LoadContent()
{ {
Resolution.Init(
GraphicsDevice.PresentationParameters.BackBufferWidth,
GraphicsDevice.PresentationParameters.BackBufferHeight,
PLAY_AREA_WIDTH,
PLAY_AREA_HEIGHT
);
SpriteBatch = new SpriteBatch(GraphicsDevice); SpriteBatch = new SpriteBatch(GraphicsDevice);
WhitePixel = new Texture2D(GraphicsDevice, 1, 1); WhitePixel = new Texture2D(GraphicsDevice, 1, 1);
WhitePixel.SetData(new Color[] { Color.White }); WhitePixel.SetData(new Color[] { Color.White });
GameRenderTarget = new RenderTarget2D(GraphicsDevice, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT);
ScoreFont = DynamicSpriteFont.FromTtf( ScoreFont = DynamicSpriteFont.FromTtf(
File.ReadAllBytes(@"Content/Fonts/SquaredDisplay.ttf"), File.ReadAllBytes(@"Content/Fonts/SquaredDisplay.ttf"),
128 128
@ -80,7 +95,7 @@ namespace PongFE
WorldBuilder.SendMessage( WorldBuilder.SendMessage(
new PaddleSpawnMessage( new PaddleSpawnMessage(
new MoonTools.Structs.Position2D(1255, 5), new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH - 25, 5),
Enums.PlayerIndex.Two, Enums.PlayerIndex.Two,
PaddleControl.Computer, PaddleControl.Computer,
20, 20,
@ -90,7 +105,7 @@ namespace PongFE
WorldBuilder.SendMessage( WorldBuilder.SendMessage(
new BallSpawnMessage( new BallSpawnMessage(
new MoonTools.Structs.Position2D(640, 360), new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH / 2, PLAY_AREA_HEIGHT / 2),
300, 300,
16, 16,
16 16
@ -101,7 +116,7 @@ namespace PongFE
WorldBuilder.SendMessage( WorldBuilder.SendMessage(
new BoundarySpawnMessage( new BoundarySpawnMessage(
new MoonTools.Structs.Position2D(0, -6), new MoonTools.Structs.Position2D(0, -6),
1280, PLAY_AREA_WIDTH,
6 6
) )
); );
@ -109,8 +124,8 @@ namespace PongFE
// bottom boundary // bottom boundary
WorldBuilder.SendMessage( WorldBuilder.SendMessage(
new BoundarySpawnMessage( new BoundarySpawnMessage(
new MoonTools.Structs.Position2D(0, 720), new MoonTools.Structs.Position2D(0, PLAY_AREA_HEIGHT),
1280, PLAY_AREA_WIDTH,
6 6
) )
); );
@ -119,9 +134,9 @@ namespace PongFE
WorldBuilder.SendMessage( WorldBuilder.SendMessage(
new GoalBoundarySpawnMessage( new GoalBoundarySpawnMessage(
Enums.PlayerIndex.One, Enums.PlayerIndex.One,
new MoonTools.Structs.Position2D(1280, 0), new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH, 0),
6, 6,
720 PLAY_AREA_HEIGHT
) )
); );
@ -131,10 +146,13 @@ namespace PongFE
Enums.PlayerIndex.Two, Enums.PlayerIndex.Two,
new MoonTools.Structs.Position2D(-6, 0), new MoonTools.Structs.Position2D(-6, 0),
6, 6,
720 PLAY_AREA_HEIGHT
) )
); );
var playAreaEntity = WorldBuilder.CreateEntity();
WorldBuilder.SetComponent(playAreaEntity, new PlayAreaComponent(PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT));
World = WorldBuilder.Build(); World = WorldBuilder.Build();
} }
@ -152,12 +170,34 @@ namespace PongFE
protected override void Draw(GameTime gameTime) protected override void Draw(GameTime gameTime)
{ {
GraphicsDevice.SetRenderTarget(GameRenderTarget);
GraphicsDevice.Clear(Color.Black); GraphicsDevice.Clear(Color.Black);
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
World.Draw(); World.Draw();
SpriteBatch.End(); SpriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.Black);
SpriteBatch.Begin(
SpriteSortMode.Deferred,
null,
null,
null,
null,
null,
Resolution.TransformMatrix
);
SpriteBatch.Draw(
GameRenderTarget,
Vector2.Zero,
Color.White
);
SpriteBatch.End();
base.Draw(gameTime); base.Draw(gameTime);
} }
} }

View File

@ -25,6 +25,8 @@ namespace PongFE.Renderers
int? playerOneScore = null; int? playerOneScore = null;
int? playerTwoScore = null; int? playerTwoScore = null;
ref readonly var playAreaComponent = ref ReadComponent<PlayAreaComponent>();
foreach (ref readonly var entity in ReadEntities<ScoreComponent>()) foreach (ref readonly var entity in ReadEntities<ScoreComponent>())
{ {
ref readonly var scoreComponent = ref GetComponent<ScoreComponent>(entity); ref readonly var scoreComponent = ref GetComponent<ScoreComponent>(entity);
@ -45,7 +47,7 @@ namespace PongFE.Renderers
SpriteBatch.DrawString( SpriteBatch.DrawString(
Font, Font,
playerOneScore.Value.ToString(), playerOneScore.Value.ToString(),
new Vector2(640 - SpacingFromCenter, SpacingFromTop), new Vector2(playAreaComponent.Width / 2 - SpacingFromCenter, SpacingFromTop),
Color.White Color.White
); );
} }
@ -55,7 +57,7 @@ namespace PongFE.Renderers
SpriteBatch.DrawString( SpriteBatch.DrawString(
Font, Font,
playerTwoScore.Value.ToString(), playerTwoScore.Value.ToString(),
new Vector2(640 + SpacingFromCenter - (Font.Size / 2), SpacingFromTop), new Vector2(playAreaComponent.Width / 2 + SpacingFromCenter - (Font.Size / 2), SpacingFromTop),
Color.White Color.White
); );
} }

View File

@ -0,0 +1,69 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace IndependentResolutionRendering
{
static class Resolution
{
static private int s_virtual_width;
static private int s_virtual_height;
static private int s_screen_width;
static private int s_screen_height;
static private Matrix s_transform_matrix;
static private bool s_dirtyMatrix = true;
static public void Init(int screenWidth, int screenHeight, int virtualWidth, int virtualHeight)
{
s_screen_width = screenWidth;
s_screen_height = screenHeight;
s_virtual_width = virtualWidth;
s_virtual_height = virtualHeight;
s_dirtyMatrix = true;
}
static public Matrix TransformMatrix
{
get
{
if (s_dirtyMatrix) RecreateScaleMatrix();
return s_transform_matrix;
}
}
static public void SetScreenResolution(int width, int height)
{
s_screen_width = width;
s_screen_height = height;
s_dirtyMatrix = true;
}
static public void SetVirtualResolution(int width, int height)
{
s_virtual_width = width;
s_virtual_height = height;
s_dirtyMatrix = true;
}
static private void RecreateScaleMatrix()
{
var scaleUniform = System.Math.Min(
(float)s_screen_width / s_virtual_width,
(float)s_screen_height / s_virtual_height
);
var scaleMatrix = Matrix.CreateScale(
(float)scaleUniform,
(float)scaleUniform,
1f
);
var offX = (s_screen_width - scaleUniform * s_virtual_width) / 2;
var offY = (s_screen_height - scaleUniform * s_virtual_height) / 2;
var translationMatrix = Matrix.CreateTranslation(offX, offY, 0);
s_transform_matrix = scaleMatrix * translationMatrix;
s_dirtyMatrix = false;
}
}
}