Created
February 28, 2019 10:37
-
-
Save aristotaloss/85478568d95fd81509a6ad64f7048bad to your computer and use it in GitHub Desktop.
Ported from https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils/viewport/ExtendViewport.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using MonoGame.Extended.ViewportAdapters; | |
namespace Aros.Shared.Engine | |
{ | |
public class ExtendViewportAdapter : ScalingViewportAdapter | |
{ | |
private readonly GraphicsDeviceManager _graphicsDeviceManager; | |
private readonly GameWindow _window; | |
private readonly float MaxWorldWidth = 0; | |
private readonly float MaxWorldHeight = 0; | |
private readonly float MinWorldWidth = 0; | |
private readonly float MinWorldHeight = 0; | |
public override int VirtualWidth => _virtualWidth; | |
public override int VirtualHeight => _virtualHeight; | |
private int _virtualWidth; | |
private int _virtualHeight; | |
public ExtendViewportAdapter(GameWindow window, GraphicsDevice graphicsDevice, int virtualWidth, | |
int virtualHeight) | |
: base(graphicsDevice, virtualWidth, virtualHeight) | |
{ | |
_window = window; | |
window.ClientSizeChanged += OnClientSizeChanged; | |
_virtualWidth = virtualWidth; | |
_virtualHeight = virtualHeight; | |
MinWorldWidth = virtualWidth; | |
MinWorldHeight = virtualHeight; | |
} | |
private void OnClientSizeChanged(object sender, EventArgs eventArgs) | |
{ | |
var screenWidth = GraphicsDevice.PresentationParameters.BackBufferWidth; | |
var screenHeight = GraphicsDevice.PresentationParameters.BackBufferHeight; | |
float worldWidth = MinWorldWidth; | |
float worldHeight = MinWorldHeight; | |
var scaled = ScaleFit(worldWidth, worldHeight, screenWidth, screenHeight); | |
int viewportWidth = (int) Math.Round(scaled.X); | |
int viewportHeight = (int) Math.Round(scaled.Y); | |
if (viewportWidth < screenWidth) | |
{ | |
float toViewportSpace = viewportHeight / worldHeight; | |
float toWorldSpace = worldHeight / viewportHeight; | |
float lengthen = (screenWidth - viewportWidth) * toWorldSpace; | |
if (MaxWorldWidth > 0) | |
lengthen = Math.Min(lengthen, MaxWorldWidth - MinWorldWidth); | |
worldWidth += lengthen; | |
viewportWidth += (int) Math.Round(lengthen * toViewportSpace); | |
} | |
else if (viewportHeight < screenHeight) | |
{ | |
float toViewportSpace = viewportWidth / worldWidth; | |
float toWorldSpace = worldWidth / viewportWidth; | |
float lengthen = (screenHeight - viewportHeight) * toWorldSpace; | |
if (MaxWorldHeight > 0) | |
lengthen = Math.Min(lengthen, MaxWorldHeight - MinWorldHeight); | |
worldHeight += lengthen; | |
viewportHeight += (int) Math.Round(lengthen * toViewportSpace); | |
} | |
_virtualWidth = (int) worldWidth; | |
_virtualHeight = (int) worldHeight; | |
GraphicsDevice.Viewport = new Viewport((int) (screenWidth - viewportWidth) / 2, (int) (screenHeight - viewportHeight) / 2, viewportWidth, viewportHeight); | |
} | |
private static Vector2 ScaleFit(float sourceWidth, float sourceHeight, float targetWidth, float targetHeight) | |
{ | |
float targetRatio = targetHeight / targetWidth; | |
float sourceRatio = sourceHeight / sourceWidth; | |
float scale = targetRatio > sourceRatio ? targetWidth / sourceWidth : targetHeight / sourceHeight; | |
return new Vector2(sourceWidth * scale, sourceHeight * scale); | |
} | |
public override void Reset() | |
{ | |
base.Reset(); | |
OnClientSizeChanged(this, EventArgs.Empty); | |
} | |
public override Point PointToScreen(int x, int y) | |
{ | |
var viewport = GraphicsDevice.Viewport; | |
return base.PointToScreen(x - viewport.X, y - viewport.Y); | |
} | |
public override Matrix GetScaleMatrix() | |
{ | |
var scaleX = (float)ViewportWidth / VirtualWidth; | |
var scaleY = (float)ViewportHeight / VirtualHeight; | |
return Matrix.CreateScale(scaleX, scaleY, 1.0f); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment