Show More
Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
References:
File last commit:
Show/Diff file:
Action:
FNA/src/Graphics/Viewport.cs
305 lines | 6.6 KiB | text/x-csharp | CSharpLexer
305 lines | 6.6 KiB | text/x-csharp | CSharpLexer
r0 | #region License | |||
/* FNA - XNA4 Reimplementation for Desktop Platforms | ||||
* Copyright 2009-2020 Ethan Lee and the MonoGame Team | ||||
* | ||||
* Released under the Microsoft Public License. | ||||
* See LICENSE for details. | ||||
*/ | ||||
#endregion | ||||
#region Using Statements | ||||
using System; | ||||
#endregion | ||||
namespace Microsoft.Xna.Framework.Graphics | ||||
{ | ||||
/// <summary> | ||||
/// Describes the view bounds for render-target surface. | ||||
/// </summary> | ||||
[Serializable] | ||||
public struct Viewport | ||||
{ | ||||
#region Public Properties | ||||
/// <summary> | ||||
/// The height of the bounds in pixels. | ||||
/// </summary> | ||||
public int Height | ||||
{ | ||||
get | ||||
{ | ||||
return height; | ||||
} | ||||
set | ||||
{ | ||||
height = value; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// The upper limit of depth of this viewport. | ||||
/// </summary> | ||||
public float MaxDepth | ||||
{ | ||||
get | ||||
{ | ||||
return maxDepth; | ||||
} | ||||
set | ||||
{ | ||||
maxDepth = value; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// The lower limit of depth of this viewport. | ||||
/// </summary> | ||||
public float MinDepth | ||||
{ | ||||
get | ||||
{ | ||||
return minDepth; | ||||
} | ||||
set | ||||
{ | ||||
minDepth = value; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// The width of the bounds in pixels. | ||||
/// </summary> | ||||
public int Width | ||||
{ | ||||
get | ||||
{ | ||||
return width; | ||||
} | ||||
set | ||||
{ | ||||
width = value; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// The y coordinate of the beginning of this viewport. | ||||
/// </summary> | ||||
public int Y | ||||
{ | ||||
get | ||||
{ | ||||
return y; | ||||
} | ||||
set | ||||
{ | ||||
y = value; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// The x coordinate of the beginning of this viewport. | ||||
/// </summary> | ||||
public int X | ||||
{ | ||||
get | ||||
{ | ||||
return x; | ||||
} | ||||
set | ||||
{ | ||||
x = value; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets the aspect ratio of this <see cref="Viewport"/>, which is width / height. | ||||
/// </summary> | ||||
public float AspectRatio | ||||
{ | ||||
get | ||||
{ | ||||
if ((height != 0) && (width != 0)) | ||||
{ | ||||
return (((float) width) / ((float) height)); | ||||
} | ||||
return 0.0f; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets a boundary of this <see cref="Viewport"/>. | ||||
/// </summary> | ||||
public Rectangle Bounds | ||||
{ | ||||
get | ||||
{ | ||||
return new Rectangle( | ||||
x, | ||||
y, | ||||
width, | ||||
height | ||||
); | ||||
} | ||||
set | ||||
{ | ||||
x = value.X; | ||||
y = value.Y; | ||||
width = value.Width; | ||||
height = value.Height; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Returns the subset of the viewport that is guaranteed to be visible on a lower quality display. | ||||
/// </summary> | ||||
public Rectangle TitleSafeArea | ||||
{ | ||||
get | ||||
{ | ||||
return Bounds; | ||||
} | ||||
} | ||||
#endregion | ||||
#region Private Variables | ||||
private int x; | ||||
private int y; | ||||
private int width; | ||||
private int height; | ||||
private float minDepth; | ||||
private float maxDepth; | ||||
#endregion | ||||
#region Public Constructors | ||||
/// <summary> | ||||
/// Constructs a viewport from the given values. The <see cref="MinDepth"/> will be 0.0 and <see cref="MaxDepth"/> will be 1.0. | ||||
/// </summary> | ||||
/// <param name="x">The x coordinate of the upper-left corner of the view bounds in pixels.</param> | ||||
/// <param name="y">The y coordinate of the upper-left corner of the view bounds in pixels.</param> | ||||
/// <param name="width">The width of the view bounds in pixels.</param> | ||||
/// <param name="height">The height of the view bounds in pixels.</param> | ||||
public Viewport(int x, int y, int width, int height) | ||||
{ | ||||
this.x = x; | ||||
this.y = y; | ||||
this.width = width; | ||||
this.height = height; | ||||
minDepth = 0.0f; | ||||
maxDepth = 1.0f; | ||||
} | ||||
/// <summary> | ||||
/// Constructs a viewport from the given values. | ||||
/// </summary> | ||||
/// <param name="bounds">A <see cref="Rectangle"/> that defines the location and size of the <see cref="Viewport"/> in a render target.</param> | ||||
public Viewport(Rectangle bounds) | ||||
{ | ||||
x = bounds.X; | ||||
y = bounds.Y; | ||||
width = bounds.Width; | ||||
height = bounds.Height; | ||||
minDepth = 0.0f; | ||||
maxDepth = 1.0f; | ||||
} | ||||
#endregion | ||||
#region Public Methods | ||||
/// <summary> | ||||
/// Projects a <see cref="Vector3"/> from world space into screen space. | ||||
/// </summary> | ||||
/// <param name="source">The <see cref="Vector3"/> to project.</param> | ||||
/// <param name="projection">The projection <see cref="Matrix"/>.</param> | ||||
/// <param name="view">The view <see cref="Matrix"/>.</param> | ||||
/// <param name="world">The world <see cref="Matrix"/>.</param> | ||||
/// <returns></returns> | ||||
public Vector3 Project( | ||||
Vector3 source, | ||||
Matrix projection, | ||||
Matrix view, | ||||
Matrix world | ||||
) { | ||||
Matrix matrix = Matrix.Multiply( | ||||
Matrix.Multiply(world, view), | ||||
projection | ||||
); | ||||
Vector3 vector = Vector3.Transform(source, matrix); | ||||
float a = (((source.X * matrix.M14) + (source.Y * matrix.M24)) + (source.Z * matrix.M34)) + matrix.M44; | ||||
if (!MathHelper.WithinEpsilon(a, 1.0f)) | ||||
{ | ||||
vector.X = vector.X / a; | ||||
vector.Y = vector.Y / a; | ||||
vector.Z = vector.Z / a; | ||||
} | ||||
vector.X = (((vector.X + 1f) * 0.5f) * Width) + X; | ||||
vector.Y = (((-vector.Y + 1f) * 0.5f) * Height) + Y; | ||||
vector.Z = (vector.Z * (MaxDepth - MinDepth)) + MinDepth; | ||||
return vector; | ||||
} | ||||
/// <summary> | ||||
/// Unprojects a <see cref="Vector3"/> from screen space into world space. | ||||
/// </summary> | ||||
/// <param name="source">The <see cref="Vector3"/> to unproject.</param> | ||||
/// <param name="projection">The projection <see cref="Matrix"/>.</param> | ||||
/// <param name="view">The view <see cref="Matrix"/>.</param> | ||||
/// <param name="world">The world <see cref="Matrix"/>.</param> | ||||
/// <returns></returns> | ||||
public Vector3 Unproject(Vector3 source, Matrix projection, Matrix view, Matrix world) | ||||
{ | ||||
Matrix matrix = Matrix.Invert( | ||||
Matrix.Multiply( | ||||
Matrix.Multiply(world, view), | ||||
projection | ||||
) | ||||
); | ||||
source.X = (((source.X - X) / ((float) Width)) * 2f) - 1f; | ||||
source.Y = -((((source.Y - Y) / ((float) Height)) * 2f) - 1f); | ||||
source.Z = (source.Z - MinDepth) / (MaxDepth - MinDepth); | ||||
Vector3 vector = Vector3.Transform(source, matrix); | ||||
float a = ( | ||||
((source.X * matrix.M14) + (source.Y * matrix.M24)) + | ||||
(source.Z * matrix.M34) | ||||
) + matrix.M44; | ||||
if (!MathHelper.WithinEpsilon(a, 1.0f)) | ||||
{ | ||||
vector.X = vector.X / a; | ||||
vector.Y = vector.Y / a; | ||||
vector.Z = vector.Z / a; | ||||
} | ||||
return vector; | ||||
} | ||||
/// <summary> | ||||
/// Returns a <see cref="String"/> representation of this <see cref="Viewport"/> in the format: | ||||
/// {X:[<see cref="X"/>] Y:[<see cref="Y"/>] Width:[<see cref="Width"/>] Height:[<see cref="Height"/>] MinDepth:[<see cref="MinDepth"/>] MaxDepth:[<see cref="MaxDepth"/>]} | ||||
/// </summary> | ||||
/// <returns>A <see cref="String"/> representation of this <see cref="Viewport"/>.</returns> | ||||
public override string ToString() | ||||
{ | ||||
return ( | ||||
"{" + | ||||
"X:" + x.ToString() + | ||||
" Y:" + y.ToString() + | ||||
" Width:" + width.ToString() + | ||||
" Height:" + height.ToString() + | ||||
" MinDepth:" + minDepth.ToString() + | ||||
" MaxDepth:" + maxDepth.ToString() + | ||||
"}" | ||||
); | ||||
} | ||||
#endregion | ||||
} | ||||
} | ||||