- Implemented the SkinnedEffect class (not tested yet, sample will come soon)
- Optimizations in the SpriteBatch and SpriteFont classes
This commit is contained in:
parent
8b735c16c2
commit
7350ca3d3a
@ -67,6 +67,8 @@ namespace ANX.Framework.Graphics
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
OneOverWidth = 1f / width;
|
||||
OneOverHeight = 1f / height;
|
||||
|
||||
base.levelCount = 1;
|
||||
base.format = SurfaceFormat.Color;
|
||||
|
@ -1,34 +1,189 @@
|
||||
#region Using Statements
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ANX.Framework.NonXNA;
|
||||
using ANX.Framework.Graphics;
|
||||
|
||||
#endregion // Using Statements
|
||||
using ANX.Framework.NonXNA.Development;
|
||||
|
||||
// This file is part of the ANX.Framework created by the
|
||||
// "ANX.Framework developer group" and released under the Ms-PL license.
|
||||
// For details see: http://anxframework.codeplex.com/license
|
||||
|
||||
|
||||
|
||||
namespace ANX.Framework.Graphics
|
||||
{
|
||||
[PercentageComplete(100)]
|
||||
[TestState(TestStateAttribute.TestState.Untested)]
|
||||
[Developer("AstrorEnales")]
|
||||
public class SkinnedEffect : Effect, IEffectMatrices, IEffectLights, IEffectFog
|
||||
{
|
||||
{
|
||||
public const int MaxBones = 72;
|
||||
|
||||
#region Private
|
||||
private Matrix world;
|
||||
private Matrix view;
|
||||
private Matrix projection;
|
||||
private bool preferPerPixelLighting;
|
||||
private bool isFogEnabled;
|
||||
private Vector3 diffuseColor;
|
||||
private Vector3 specularColor;
|
||||
private Vector3 fogColor;
|
||||
private Vector3 emissiveColor;
|
||||
private Vector3 ambientLightColor;
|
||||
private Matrix[] bones;
|
||||
private int weightsPerBone;
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
public float FogEnd { get; set; }
|
||||
public float FogStart { get; set; }
|
||||
public Texture2D Texture { get; set; }
|
||||
public float Alpha { get; set; }
|
||||
public float SpecularPower { get; set; }
|
||||
public DirectionalLight DirectionalLight0 { get; private set; }
|
||||
public DirectionalLight DirectionalLight1 { get; private set; }
|
||||
public DirectionalLight DirectionalLight2 { get; private set; }
|
||||
|
||||
public int WeightsPerVertex
|
||||
{
|
||||
get
|
||||
{
|
||||
return weightsPerBone;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 1 && value != 2 && value != 4)
|
||||
throw new ArgumentOutOfRangeException("Weights per bone only allows 1, 2 or 4 as value!");
|
||||
weightsPerBone = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool PreferPerPixelLighting
|
||||
{
|
||||
get { return preferPerPixelLighting; }
|
||||
set
|
||||
{
|
||||
preferPerPixelLighting = value;
|
||||
SelectTechnique();
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get { return projection; }
|
||||
set { projection = value; }
|
||||
}
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return view; }
|
||||
set { view = value; }
|
||||
}
|
||||
|
||||
public Matrix World
|
||||
{
|
||||
get { return world; }
|
||||
set { world = value; }
|
||||
}
|
||||
|
||||
public Vector3 AmbientLightColor
|
||||
{
|
||||
get { return ambientLightColor; }
|
||||
set { ambientLightColor = value; }
|
||||
}
|
||||
|
||||
public bool LightingEnabled
|
||||
{
|
||||
get { return true; }
|
||||
set
|
||||
{
|
||||
if (value == false)
|
||||
throw new NotSupportedException("SkinnedEffect without Lighting isn't supported!");
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 FogColor
|
||||
{
|
||||
get { return fogColor; }
|
||||
set { fogColor = value; }
|
||||
}
|
||||
|
||||
public bool FogEnabled
|
||||
{
|
||||
get { return isFogEnabled; }
|
||||
set
|
||||
{
|
||||
isFogEnabled = value;
|
||||
SelectTechnique();
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 DiffuseColor
|
||||
{
|
||||
get { return diffuseColor; }
|
||||
set { diffuseColor = value; }
|
||||
}
|
||||
public Vector3 EmissiveColor
|
||||
{
|
||||
get { return emissiveColor; }
|
||||
set { emissiveColor = value; }
|
||||
}
|
||||
|
||||
public Vector3 SpecularColor
|
||||
{
|
||||
get { return specularColor; }
|
||||
set { specularColor = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
public SkinnedEffect(GraphicsDevice graphics)
|
||||
: base(graphics, GetByteCode(), GetSourceLanguage())
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
{
|
||||
world = Matrix.Identity;
|
||||
view = Matrix.Identity;
|
||||
projection = Matrix.Identity;
|
||||
FogStart = 0f;
|
||||
FogEnd = 1f;
|
||||
Alpha = 1f;
|
||||
diffuseColor = Vector3.One;
|
||||
ambientLightColor = Vector3.One;
|
||||
emissiveColor = Vector3.One;
|
||||
specularColor = Vector3.One;
|
||||
SpecularPower = 16f;
|
||||
WeightsPerVertex = 4;
|
||||
CreateLights(null);
|
||||
DirectionalLight0.Enabled = true;
|
||||
|
||||
bones = new Matrix[MaxBones];
|
||||
for (int index = 0; index < MaxBones; index++)
|
||||
bones[index] = Matrix.Identity;
|
||||
|
||||
SelectTechnique();
|
||||
}
|
||||
|
||||
protected SkinnedEffect(SkinnedEffect cloneSource)
|
||||
: base(cloneSource)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
{
|
||||
world = cloneSource.world;
|
||||
view = cloneSource.view;
|
||||
projection = cloneSource.projection;
|
||||
preferPerPixelLighting = cloneSource.preferPerPixelLighting;
|
||||
isFogEnabled = cloneSource.isFogEnabled;
|
||||
diffuseColor = cloneSource.diffuseColor;
|
||||
specularColor = cloneSource.specularColor;
|
||||
fogColor = cloneSource.fogColor;
|
||||
emissiveColor = cloneSource.emissiveColor;
|
||||
ambientLightColor = cloneSource.ambientLightColor;
|
||||
FogEnd = cloneSource.FogEnd;
|
||||
FogStart = cloneSource.FogStart;
|
||||
Texture = cloneSource.Texture;
|
||||
SpecularPower = cloneSource.SpecularPower;
|
||||
Alpha = cloneSource.Alpha;
|
||||
WeightsPerVertex = cloneSource.WeightsPerVertex;
|
||||
for (int index = 0; index < MaxBones; index++)
|
||||
bones[index] = cloneSource.bones[index];
|
||||
|
||||
CreateLights(cloneSource);
|
||||
SelectTechnique();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetByteCode
|
||||
private static byte[] GetByteCode()
|
||||
@ -46,245 +201,186 @@ namespace ANX.Framework.Graphics
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override Effect Clone()
|
||||
#region Clone
|
||||
public override Effect Clone()
|
||||
{
|
||||
return new SkinnedEffect(this);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public const int MaxBones = 72;
|
||||
#region CreateLights
|
||||
private void CreateLights(SkinnedEffect cloneSource)
|
||||
{
|
||||
DirectionalLight0 = new DirectionalLight(Parameters["DirLight0Direction"], Parameters["DirLight0DiffuseColor"],
|
||||
null, (cloneSource != null) ? cloneSource.DirectionalLight0 : null);
|
||||
DirectionalLight1 = new DirectionalLight(Parameters["DirLight1Direction"], Parameters["DirLight1DiffuseColor"],
|
||||
null, (cloneSource != null) ? cloneSource.DirectionalLight1 : null);
|
||||
DirectionalLight2 = new DirectionalLight(Parameters["DirLight2Direction"], Parameters["DirLight2DiffuseColor"],
|
||||
null, (cloneSource != null) ? cloneSource.DirectionalLight2 : null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public bool PreferPerPixelLighting
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
#region EnableDefaultLighting
|
||||
public void EnableDefaultLighting()
|
||||
{
|
||||
LightingEnabled = true;
|
||||
ambientLightColor = new Vector3(0.05333332f, 0.09882354f, 0.1819608f);
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
DirectionalLight0.Direction = new Vector3(-0.5265408f, -0.5735765f, -0.6275069f);
|
||||
DirectionalLight0.DiffuseColor = new Vector3(1f, 0.9607844f, 0.8078432f);
|
||||
DirectionalLight0.SpecularColor = DirectionalLight0.DiffuseColor;
|
||||
DirectionalLight0.Enabled = true;
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
DirectionalLight1.Direction = new Vector3(0.7198464f, 0.3420201f, 0.6040227f);
|
||||
DirectionalLight1.DiffuseColor = new Vector3(0.9647059f, 0.7607844f, 0.4078432f);
|
||||
DirectionalLight1.SpecularColor = Vector3.Zero;
|
||||
DirectionalLight1.Enabled = true;
|
||||
|
||||
public Matrix World
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
DirectionalLight2.Direction = new Vector3(0.4545195f, -0.7660444f, 0.4545195f);
|
||||
DirectionalLight2.DiffuseColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
|
||||
DirectionalLight2.SpecularColor = DirectionalLight2.DiffuseColor;
|
||||
DirectionalLight2.Enabled = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void EnableDefaultLighting()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#region GetBoneTransforms
|
||||
public Matrix[] GetBoneTransforms(int count)
|
||||
{
|
||||
if (count <= 0)
|
||||
throw new ArgumentOutOfRangeException("count");
|
||||
if (count > 72)
|
||||
throw new ArgumentException("The maximum number of allowed bones for the SkinnedEffect is " + MaxBones + "!");
|
||||
|
||||
public Vector3 AmbientLightColor
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
var result = new Matrix[MaxBones];
|
||||
for (int index = 0; index < MaxBones; index++)
|
||||
{
|
||||
result[index] = bones[index];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public DirectionalLight DirectionalLight0
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
#region SetBoneTransforms
|
||||
public void SetBoneTransforms(Matrix[] boneTransforms)
|
||||
{
|
||||
if (boneTransforms == null || boneTransforms.Length == 0)
|
||||
throw new ArgumentNullException("boneTransforms");
|
||||
|
||||
public DirectionalLight DirectionalLight1
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
if (boneTransforms.Length > 72)
|
||||
throw new ArgumentException("The maximum number of allowed bones for the SkinnedEffect is " + MaxBones + "!");
|
||||
|
||||
public DirectionalLight DirectionalLight2
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
for (int index = 0; index < MaxBones; index++)
|
||||
bones[index] = index < boneTransforms.Length ? boneTransforms[index] : Matrix.Identity;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public bool LightingEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
#region PreBindSetParameters
|
||||
internal override void PreBindSetParameters()
|
||||
{
|
||||
Matrix worldView;
|
||||
Matrix.Multiply(ref world, ref view, out worldView);
|
||||
Matrix wvp;
|
||||
Matrix.Multiply(ref worldView, ref projection, out wvp);
|
||||
Parameters["WorldViewProj"].SetValue(wvp);
|
||||
|
||||
public Vector3 FogColor
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
SetLightingMatrices();
|
||||
SetMaterialColor();
|
||||
|
||||
public bool FogEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
Parameters["Bones"].SetValue(bones);
|
||||
|
||||
public float FogEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
Parameters["FogColor"].SetValue(fogColor);
|
||||
Parameters["SpecularPower"].SetValue(SpecularPower);
|
||||
Parameters["SpecularColor"].SetValue(specularColor);
|
||||
|
||||
public float FogStart
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
if (Texture != null)
|
||||
Parameters["Texture"].SetValue(Texture);
|
||||
|
||||
public Texture2D Texture
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
if (isFogEnabled)
|
||||
SetFogVector(ref worldView);
|
||||
else
|
||||
Parameters["FogVector"].SetValue(Vector4.Zero);
|
||||
|
||||
public int WeightsPerVertex
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
SelectTechnique();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Vector3 DiffuseColor
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
#region SelectTechnique
|
||||
private void SelectTechnique()
|
||||
{
|
||||
string name = "";
|
||||
if (WeightsPerVertex == 1)
|
||||
name = "OneBone";
|
||||
else if (WeightsPerVertex == 2)
|
||||
name = "TwoBones";
|
||||
else if (WeightsPerVertex == 4)
|
||||
name = "FourBones";
|
||||
|
||||
public Vector3 EmissiveColor
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
bool oneLight = DirectionalLight1.Enabled == false && DirectionalLight2.Enabled == false;
|
||||
if (preferPerPixelLighting)
|
||||
name += "PixelLighting";
|
||||
else if (oneLight)
|
||||
name += "OneLight";
|
||||
else
|
||||
name += "VertexLighting";
|
||||
|
||||
public Vector3 SpecularColor
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
if (isFogEnabled == false)
|
||||
name += "NoFog";
|
||||
|
||||
public float SpecularPower
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
CurrentTechnique = Techniques[name];
|
||||
}
|
||||
#endregion
|
||||
|
||||
public float Alpha
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
#region SetLightingMatrices
|
||||
private void SetLightingMatrices()
|
||||
{
|
||||
Matrix worldInverse;
|
||||
Matrix.Invert(ref world, out worldInverse);
|
||||
Matrix worldInverseTranspose;
|
||||
Matrix.Transpose(ref worldInverse, out worldInverseTranspose);
|
||||
|
||||
public Matrix[] GetBoneTransforms(int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
Parameters["World"].SetValue(world);
|
||||
Parameters["WorldInverseTranspose"].SetValue(worldInverseTranspose);
|
||||
|
||||
public void SetBoneTransforms(Matrix[] boneTransforms)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
Matrix viewInverse;
|
||||
Matrix.Invert(ref view, out viewInverse);
|
||||
Parameters["EyePosition"].SetValue(viewInverse.Translation);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SetMaterialColor
|
||||
private void SetMaterialColor()
|
||||
{
|
||||
Vector4 diffuse;
|
||||
diffuse.X = diffuseColor.X * Alpha;
|
||||
diffuse.Y = diffuseColor.Y * Alpha;
|
||||
diffuse.Z = diffuseColor.Z * Alpha;
|
||||
diffuse.W = Alpha;
|
||||
Vector3 emissive;
|
||||
emissive.X = (emissiveColor.X + ambientLightColor.X * diffuseColor.X) * Alpha;
|
||||
emissive.Y = (emissiveColor.Y + ambientLightColor.Y * diffuseColor.Y) * Alpha;
|
||||
emissive.Z = (emissiveColor.Z + ambientLightColor.Z * diffuseColor.Z) * Alpha;
|
||||
Parameters["DiffuseColor"].SetValue(diffuse);
|
||||
Parameters["EmissiveColor"].SetValue(emissive);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SetFogVector
|
||||
private void SetFogVector(ref Matrix worldView)
|
||||
{
|
||||
if (FogStart == FogEnd)
|
||||
{
|
||||
Parameters["FogVector"].SetValue(new Vector4(0f, 0f, 0f, 1f));
|
||||
return;
|
||||
}
|
||||
|
||||
float fogFactor = 1f / (FogStart - FogEnd);
|
||||
Vector4 value;
|
||||
value.X = worldView.M13 * fogFactor;
|
||||
value.Y = worldView.M23 * fogFactor;
|
||||
value.Z = worldView.M33 * fogFactor;
|
||||
value.W = (worldView.M43 + FogStart) * fogFactor;
|
||||
Parameters["FogVector"].SetValue(value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
#region Using Statements
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ANX.Framework.NonXNA;
|
||||
|
||||
#endregion // Using Statements
|
||||
using ANX.Framework.NonXNA.Development;
|
||||
|
||||
// This file is part of the ANX.Framework created by the
|
||||
// "ANX.Framework developer group" and released under the Ms-PL license.
|
||||
@ -12,11 +10,14 @@ using ANX.Framework.NonXNA;
|
||||
|
||||
namespace ANX.Framework.Graphics
|
||||
{
|
||||
[PercentageComplete(100)]
|
||||
[TestState(TestStateAttribute.TestState.Untested)]
|
||||
[Developer("Glatzemann, AstrorEnales")]
|
||||
public class SpriteBatch : GraphicsResource
|
||||
{
|
||||
#region Private Members
|
||||
private const int InitialBatchSize = 1024;
|
||||
{
|
||||
private const int InitialBatchSize = 1024;
|
||||
|
||||
#region Private
|
||||
private Effect spriteBatchEffect;
|
||||
private bool hasBegun;
|
||||
private SpriteSortMode currentSortMode;
|
||||
@ -43,8 +44,7 @@ namespace ANX.Framework.Graphics
|
||||
private static TextureComparer textureComparer = new TextureComparer();
|
||||
private static FrontToBackComparer frontToBackComparer = new FrontToBackComparer();
|
||||
private static BackToFrontComparer backToFrontComparer = new BackToFrontComparer();
|
||||
|
||||
#endregion // Private Members
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
public SpriteBatch(GraphicsDevice graphicsDevice)
|
||||
@ -55,43 +55,55 @@ namespace ANX.Framework.Graphics
|
||||
base.GraphicsDevice = graphicsDevice;
|
||||
|
||||
var renderSystemCreator = AddInSystemFactory.Instance.GetDefaultCreator<IRenderSystemCreator>();
|
||||
this.spriteBatchEffect = new Effect(graphicsDevice, renderSystemCreator.GetShaderByteCode(NonXNA.PreDefinedShader.SpriteBatch), renderSystemCreator.GetStockShaderSourceLanguage);
|
||||
this.spriteBatchEffect = new Effect(graphicsDevice,
|
||||
renderSystemCreator.GetShaderByteCode(NonXNA.PreDefinedShader.SpriteBatch),
|
||||
renderSystemCreator.GetStockShaderSourceLanguage);
|
||||
|
||||
this.spriteInfos = new SpriteInfo[InitialBatchSize];
|
||||
|
||||
this.InitializeIndexBuffer(InitialBatchSize);
|
||||
|
||||
this.InitializeVertexBuffer();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Begin-Method
|
||||
#region Begin
|
||||
public void Begin()
|
||||
{
|
||||
Begin(SpriteSortMode.Texture, null, null, null, null, null, Matrix.Identity);
|
||||
Begin(SpriteSortMode.Texture, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public void Begin(SpriteSortMode sortMode, BlendState blendState)
|
||||
{
|
||||
Begin(sortMode, blendState, null, null, null, null, Matrix.Identity);
|
||||
Begin(sortMode, blendState, null, null, null, null);
|
||||
}
|
||||
|
||||
public void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState)
|
||||
public void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState,
|
||||
DepthStencilState depthStencilState, RasterizerState rasterizerState)
|
||||
{
|
||||
Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, null, Matrix.Identity);
|
||||
Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, null);
|
||||
}
|
||||
|
||||
public void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect)
|
||||
{
|
||||
Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, Matrix.Identity);
|
||||
public void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState,
|
||||
DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect)
|
||||
{
|
||||
if (hasBegun == true)
|
||||
throw new Exception("End() has to be called before a new SpriteBatch can be started with Begin()");
|
||||
|
||||
hasBegun = true;
|
||||
this.currentSortMode = sortMode;
|
||||
|
||||
this.blendState = blendState;
|
||||
this.samplerState = samplerState;
|
||||
this.depthStencilState = depthStencilState;
|
||||
this.rasterizerState = rasterizerState;
|
||||
this.effect = effect;
|
||||
this.transformMatrix = Matrix.Identity;
|
||||
}
|
||||
|
||||
public void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix transformMatrix)
|
||||
public void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState,
|
||||
DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix transformMatrix)
|
||||
{
|
||||
if (this.hasBegun == true)
|
||||
{
|
||||
if (hasBegun == true)
|
||||
throw new Exception("End() has to be called before a new SpriteBatch can be started with Begin()");
|
||||
}
|
||||
|
||||
hasBegun = true;
|
||||
|
||||
@ -104,150 +116,186 @@ namespace ANX.Framework.Graphics
|
||||
this.effect = effect;
|
||||
this.transformMatrix = transformMatrix;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion // Begin-Method
|
||||
#region Draw
|
||||
public void Draw(Texture2D texture, Rectangle destinationRectangle, Color color)
|
||||
{
|
||||
Draw(texture, new Vector2(destinationRectangle.X, destinationRectangle.Y), new Vector2(destinationRectangle.Width,
|
||||
destinationRectangle.Height), null, color, Vector2.Zero, 0f, 0f, Vector2.One, SpriteEffects.None);
|
||||
}
|
||||
|
||||
#region Draw-Method
|
||||
public void Draw (Texture2D texture, Rectangle destinationRectangle, Color color)
|
||||
public void Draw(Texture2D texture, Rectangle destinationRectangle, Nullable<Rectangle> sourceRectangle, Color color)
|
||||
{
|
||||
Draw(texture, new Vector2(destinationRectangle.X, destinationRectangle.Y), new Vector2(destinationRectangle.Width,
|
||||
destinationRectangle.Height), sourceRectangle, color, Vector2.Zero, 0f, 0f, Vector2.One, SpriteEffects.None);
|
||||
}
|
||||
|
||||
public void Draw(Texture2D texture, Rectangle destinationRectangle, Nullable<Rectangle> sourceRectangle, Color color,
|
||||
Single rotation, Vector2 origin, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
Draw(texture, new Vector2(destinationRectangle.X, destinationRectangle.Y), new Vector2(destinationRectangle.Width, destinationRectangle.Height), null, color, Vector2.Zero, 0.0f, 0.0f, Vector2.One, SpriteEffects.None);
|
||||
}
|
||||
|
||||
public void Draw (Texture2D texture, Rectangle destinationRectangle, Nullable<Rectangle> sourceRectangle, Color color)
|
||||
{
|
||||
Draw(texture, new Vector2(destinationRectangle.X, destinationRectangle.Y), new Vector2(destinationRectangle.Width, destinationRectangle.Height), sourceRectangle, color, Vector2.Zero, 0.0f, 0.0f, Vector2.One, SpriteEffects.None);
|
||||
}
|
||||
|
||||
public void Draw(Texture2D texture, Rectangle destinationRectangle, Nullable<Rectangle> sourceRectangle, Color color, Single rotation, Vector2 origin, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
Draw(texture, new Vector2(destinationRectangle.X, destinationRectangle.Y), new Vector2(destinationRectangle.Width, destinationRectangle.Height), sourceRectangle, color, origin, layerDepth, rotation, Vector2.One, effects);
|
||||
Draw(texture, new Vector2(destinationRectangle.X, destinationRectangle.Y), new Vector2(destinationRectangle.Width,
|
||||
destinationRectangle.Height), sourceRectangle, color, origin, layerDepth, rotation, Vector2.One, effects);
|
||||
}
|
||||
|
||||
public void Draw(Texture2D texture, Vector2 position, Color color)
|
||||
{
|
||||
Draw(texture, position, new Vector2(texture.Width, texture.Height), null, color, Vector2.Zero, 0.0f, 0.0f, Vector2.One, SpriteEffects.None);
|
||||
Draw(texture, position, new Vector2(texture.Width, texture.Height), null, color, Vector2.Zero, 0f, 0f, Vector2.One,
|
||||
SpriteEffects.None);
|
||||
}
|
||||
|
||||
public void Draw(Texture2D texture, Vector2 position, Nullable<Rectangle> sourceRectangle, Color color)
|
||||
{
|
||||
Vector2 size = sourceRectangle.HasValue ? new Vector2(sourceRectangle.Value.Width, sourceRectangle.Value.Height) : new Vector2(texture.Width, texture.Height);
|
||||
Draw(texture, position, size, sourceRectangle, color, Vector2.Zero, 0.0f, 0.0f, Vector2.One, SpriteEffects.None);
|
||||
Vector2 size = sourceRectangle.HasValue ?
|
||||
new Vector2(sourceRectangle.Value.Width, sourceRectangle.Value.Height) :
|
||||
new Vector2(texture.Width, texture.Height);
|
||||
Draw(texture, position, size, sourceRectangle, color, Vector2.Zero, 0f, 0f, Vector2.One, SpriteEffects.None);
|
||||
}
|
||||
|
||||
public void Draw(Texture2D texture, Vector2 position, Nullable<Rectangle> sourceRectangle, Color color, Single rotation, Vector2 origin, Single scale, SpriteEffects effects, Single layerDepth)
|
||||
public void Draw(Texture2D texture, Vector2 position, Nullable<Rectangle> sourceRectangle, Color color, Single rotation,
|
||||
Vector2 origin, Single scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
Vector2 size = sourceRectangle.HasValue ? new Vector2(sourceRectangle.Value.Width, sourceRectangle.Value.Height) : new Vector2(texture.Width, texture.Height);
|
||||
Vector2 size = sourceRectangle.HasValue ?
|
||||
new Vector2(sourceRectangle.Value.Width, sourceRectangle.Value.Height) :
|
||||
new Vector2(texture.Width, texture.Height);
|
||||
Draw(texture, position, size, sourceRectangle, color, origin, layerDepth, rotation, new Vector2(scale), effects);
|
||||
}
|
||||
|
||||
public void Draw(Texture2D texture, Vector2 position, Nullable<Rectangle> sourceRectangle, Color color, Single rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
Vector2 size = sourceRectangle.HasValue ? new Vector2(sourceRectangle.Value.Width, sourceRectangle.Value.Height) : new Vector2(texture.Width, texture.Height);
|
||||
Draw(texture, position, size, sourceRectangle, color, origin, layerDepth, rotation, scale, effects);
|
||||
public void Draw(Texture2D texture, Vector2 position, Nullable<Rectangle> sourceRectangle, Color color, Single rotation,
|
||||
Vector2 origin, Vector2 scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
Vector2 size = sourceRectangle.HasValue ?
|
||||
new Vector2(sourceRectangle.Value.Width, sourceRectangle.Value.Height) :
|
||||
new Vector2(texture.Width, texture.Height);
|
||||
Draw(texture, position, size, sourceRectangle, color, origin, layerDepth, rotation, scale, effects);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DrawOptimizedText
|
||||
internal void DrawOptimizedText(Texture2D texture, Vector2 position, ref Rectangle sourceRectangle, ref Color color,
|
||||
float rotation, Vector2 scale, SpriteEffects effects, float layerDepth)
|
||||
{
|
||||
Vector2 size = new Vector2(sourceRectangle.Width, sourceRectangle.Height);
|
||||
Draw(texture, position, size, sourceRectangle, color, Vector2.Zero, layerDepth, rotation, scale, effects);
|
||||
}
|
||||
|
||||
internal void DrawOptimizedText(Texture2D texture, Vector2 position, ref Rectangle sourceRectangle, ref Color color)
|
||||
{
|
||||
if (hasBegun == false)
|
||||
throw new InvalidOperationException("Begin() must be called before Draw()");
|
||||
|
||||
if (texture == null)
|
||||
throw new ArgumentNullException("texture");
|
||||
|
||||
ResizeIfNeeded();
|
||||
|
||||
Vector2 bottomRight;
|
||||
bottomRight.X = position.X + sourceRectangle.Width;
|
||||
bottomRight.Y = position.Y + sourceRectangle.Height;
|
||||
|
||||
SpriteInfo currentSprite = spriteInfos[currentBatchPosition];
|
||||
currentSprite.Corners = new Vector2[]
|
||||
{
|
||||
position,
|
||||
new Vector2(bottomRight.X, position.Y),
|
||||
bottomRight,
|
||||
new Vector2(position.X, bottomRight.Y)
|
||||
};
|
||||
|
||||
currentSprite.Tint = color;
|
||||
currentSprite.texture = texture;
|
||||
|
||||
currentSprite.topLeftUV.X = sourceRectangle.X * texture.OneOverWidth;
|
||||
currentSprite.topLeftUV.Y = sourceRectangle.Y * texture.OneOverHeight;
|
||||
currentSprite.bottomRightUV.X = (sourceRectangle.X + sourceRectangle.Width) * texture.OneOverWidth;
|
||||
currentSprite.bottomRightUV.Y = (sourceRectangle.Y + sourceRectangle.Height) * texture.OneOverHeight;
|
||||
|
||||
currentSprite.origin = Vector2.Zero;
|
||||
currentSprite.rotation = 0f;
|
||||
currentSprite.layerDepth = 1f;
|
||||
|
||||
spriteInfos[currentBatchPosition] = currentSprite;
|
||||
currentBatchPosition++;
|
||||
|
||||
if (this.currentSortMode == SpriteSortMode.Immediate)
|
||||
{
|
||||
BatchRender(0, 1);
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DrawString
|
||||
public void DrawString(SpriteFont font, String text, Vector2 position, Color color)
|
||||
{
|
||||
if (font == null)
|
||||
throw new ArgumentNullException("font");
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
|
||||
font.DrawString(text, this, position, color);
|
||||
}
|
||||
|
||||
#endregion // Draw-Method
|
||||
public void DrawString(SpriteFont font, StringBuilder text, Vector2 position, Color color)
|
||||
{
|
||||
if (font == null)
|
||||
throw new ArgumentNullException("font");
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
|
||||
#region DrawString-Method
|
||||
public void DrawString(SpriteFont font, String text, Vector2 position, Color color)
|
||||
{
|
||||
if (font == null)
|
||||
{
|
||||
throw new ArgumentNullException("font");
|
||||
}
|
||||
font.DrawString(text.ToString(), this, position, color);
|
||||
}
|
||||
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
public void DrawString(SpriteFont font, String text, Vector2 position, Color color, Single rotation, Vector2 origin,
|
||||
Single scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
if (font == null)
|
||||
throw new ArgumentNullException("font");
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
|
||||
font.DrawString(ref text, this, position, color, Vector2.One, Vector2.Zero, 0.0f, 1.0f, SpriteEffects.None);
|
||||
font.DrawString(text, this, position, color, new Vector2(scale), origin, rotation, layerDepth, effects);
|
||||
}
|
||||
|
||||
public void DrawString(SpriteFont font, String text, Vector2 position, Color color, Single rotation, Vector2 origin, Single scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
if (font == null)
|
||||
{
|
||||
throw new ArgumentNullException("font");
|
||||
}
|
||||
public void DrawString(SpriteFont font, String text, Vector2 position, Color color, Single rotation, Vector2 origin,
|
||||
Vector2 scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
if (font == null)
|
||||
throw new ArgumentNullException("font");
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
|
||||
font.DrawString(ref text, this, position, color, new Vector2(scale), origin, rotation, layerDepth, effects);
|
||||
font.DrawString(text, this, position, color, scale, origin, rotation, layerDepth, effects);
|
||||
}
|
||||
|
||||
public void DrawString(SpriteFont font, String text, Vector2 position, Color color, Single rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
if (font == null)
|
||||
{
|
||||
throw new ArgumentNullException("font");
|
||||
}
|
||||
public void DrawString(SpriteFont font, StringBuilder text, Vector2 position, Color color, Single rotation,
|
||||
Vector2 origin, Single scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
if (font == null)
|
||||
throw new ArgumentNullException("font");
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
font.DrawString(text.ToString(), this, position, color, new Vector2(scale), origin, rotation, layerDepth, effects);
|
||||
}
|
||||
|
||||
font.DrawString(ref text, this, position, color, scale, origin, rotation, layerDepth, effects);
|
||||
}
|
||||
public void DrawString(SpriteFont font, StringBuilder text, Vector2 position, Color color, Single rotation,
|
||||
Vector2 origin, Vector2 scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
if (font == null)
|
||||
throw new ArgumentNullException("font");
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
|
||||
public void DrawString (SpriteFont font, StringBuilder text, Vector2 position, Color color)
|
||||
{
|
||||
if (font == null)
|
||||
{
|
||||
throw new ArgumentNullException("font");
|
||||
}
|
||||
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
|
||||
DrawString(font, text.ToString(), position, color);
|
||||
}
|
||||
|
||||
public void DrawString (SpriteFont font, StringBuilder text, Vector2 position, Color color, Single rotation, Vector2 origin, Single scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
if (font == null)
|
||||
{
|
||||
throw new ArgumentNullException("font");
|
||||
}
|
||||
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
|
||||
DrawString(font, text.ToString(), position, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
||||
public void DrawString (SpriteFont font, StringBuilder text, Vector2 position, Color color, Single rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, Single layerDepth)
|
||||
{
|
||||
if (font == null)
|
||||
{
|
||||
throw new ArgumentNullException("font");
|
||||
}
|
||||
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
|
||||
DrawString(font, text.ToString(), position, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
||||
#endregion // DrawString-Method
|
||||
font.DrawString(text.ToString(), this, position, color, scale, origin, rotation, layerDepth, effects);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region End
|
||||
public void End()
|
||||
{
|
||||
if (hasBegun == false)
|
||||
{
|
||||
throw new Exception("Begin() has to be called before End()");
|
||||
}
|
||||
|
||||
hasBegun = false;
|
||||
|
||||
@ -256,17 +304,11 @@ namespace ANX.Framework.Graphics
|
||||
if (currentBatchPosition > 0)
|
||||
{
|
||||
if (this.currentSortMode == SpriteSortMode.Texture)
|
||||
{
|
||||
Array.Sort<SpriteInfo>(spriteInfos, 0, currentBatchPosition, textureComparer);
|
||||
}
|
||||
else if (this.currentSortMode == SpriteSortMode.BackToFront)
|
||||
{
|
||||
Array.Sort<SpriteInfo>(spriteInfos, 0, currentBatchPosition, backToFrontComparer);
|
||||
}
|
||||
else if (this.currentSortMode == SpriteSortMode.FrontToBack)
|
||||
{
|
||||
Array.Sort<SpriteInfo>(spriteInfos, 0, currentBatchPosition, frontToBackComparer);
|
||||
}
|
||||
|
||||
int startOffset = 0;
|
||||
Texture2D lastTexture = spriteInfos[0].texture;
|
||||
@ -285,57 +327,72 @@ namespace ANX.Framework.Graphics
|
||||
|
||||
Flush();
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
private void Draw(Texture2D texture, Vector2 topLeft, Vector2 destinationSize, Rectangle? sourceRectangle, Color tint, Vector2 origin, float layerDepth, float rotation, Vector2 scale, SpriteEffects effects)
|
||||
#region ResizeIfNeeded
|
||||
private void ResizeIfNeeded()
|
||||
{
|
||||
if (currentBatchPosition >= spriteInfos.Length)
|
||||
{
|
||||
int newSize = spriteInfos.Length * 2;
|
||||
Array.Resize<SpriteInfo>(ref spriteInfos, newSize);
|
||||
InitializeIndexBuffer(newSize);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Draw
|
||||
private void Draw(Texture2D texture, Vector2 topLeft, Vector2 destinationSize, Rectangle? sourceRectangle,
|
||||
Color tint, Vector2 origin, float layerDepth, float rotation, Vector2 scale, SpriteEffects effects)
|
||||
{
|
||||
if (hasBegun == false)
|
||||
{
|
||||
throw new InvalidOperationException("Begin() must be called before Draw()");
|
||||
}
|
||||
|
||||
if (texture == null)
|
||||
{
|
||||
throw new ArgumentNullException("texture");
|
||||
}
|
||||
|
||||
if (currentBatchPosition >= spriteInfos.Length)
|
||||
{
|
||||
int newSize = spriteInfos.Length * 2;
|
||||
Array.Resize<SpriteInfo>(ref spriteInfos, newSize);
|
||||
InitializeIndexBuffer(newSize);
|
||||
}
|
||||
ResizeIfNeeded();
|
||||
|
||||
Vector2 bottomRight = topLeft + (destinationSize * scale);
|
||||
Vector2 bottomRight = new Vector2(topLeft.X + (destinationSize.X * scale.X),
|
||||
topLeft.Y + (destinationSize.Y * scale.Y));
|
||||
|
||||
spriteInfos[currentBatchPosition].Corners = new Vector2[] { topLeft, new Vector2(bottomRight.X, topLeft.Y), bottomRight, new Vector2(topLeft.X, bottomRight.Y) };
|
||||
SpriteInfo currentSprite = spriteInfos[currentBatchPosition];
|
||||
currentSprite.Corners = new Vector2[]
|
||||
{
|
||||
topLeft,
|
||||
new Vector2(bottomRight.X, topLeft.Y),
|
||||
bottomRight,
|
||||
new Vector2(topLeft.X, bottomRight.Y)
|
||||
};
|
||||
|
||||
spriteInfos[currentBatchPosition].Tint = tint;
|
||||
spriteInfos[currentBatchPosition].texture = texture;
|
||||
currentSprite.Tint = tint;
|
||||
currentSprite.texture = texture;
|
||||
|
||||
if (sourceRectangle.HasValue)
|
||||
{
|
||||
spriteInfos[currentBatchPosition].topLeftUV = new Vector2(sourceRectangle.Value.X / (float)texture.Width, sourceRectangle.Value.Y / (float)texture.Height);
|
||||
spriteInfos[currentBatchPosition].bottomRightUV = new Vector2((sourceRectangle.Value.X + sourceRectangle.Value.Width) / (float)texture.Width, (sourceRectangle.Value.Y + sourceRectangle.Value.Height) / (float)texture.Height);
|
||||
currentSprite.topLeftUV.X = sourceRectangle.Value.X * texture.OneOverWidth;
|
||||
currentSprite.topLeftUV.Y = sourceRectangle.Value.Y * texture.OneOverHeight;
|
||||
currentSprite.bottomRightUV.X = (sourceRectangle.Value.X + sourceRectangle.Value.Width) * texture.OneOverWidth;
|
||||
currentSprite.bottomRightUV.Y = (sourceRectangle.Value.Y + sourceRectangle.Value.Height) * texture.OneOverHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteInfos[currentBatchPosition].topLeftUV = Vector2.Zero;
|
||||
spriteInfos[currentBatchPosition].bottomRightUV = Vector2.One;
|
||||
currentSprite.topLeftUV = Vector2.Zero;
|
||||
currentSprite.bottomRightUV = Vector2.One;
|
||||
}
|
||||
|
||||
if ((effects & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
float tempY = spriteInfos[currentBatchPosition].bottomRightUV.Y;
|
||||
spriteInfos[currentBatchPosition].bottomRightUV.Y = spriteInfos[currentBatchPosition].topLeftUV.Y;
|
||||
spriteInfos[currentBatchPosition].topLeftUV.Y = tempY;
|
||||
float tempY = currentSprite.bottomRightUV.Y;
|
||||
currentSprite.bottomRightUV.Y = currentSprite.topLeftUV.Y;
|
||||
currentSprite.topLeftUV.Y = tempY;
|
||||
}
|
||||
|
||||
if ((effects & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically)
|
||||
{
|
||||
float tempX = spriteInfos[currentBatchPosition].bottomRightUV.X;
|
||||
spriteInfos[currentBatchPosition].bottomRightUV.X = spriteInfos[currentBatchPosition].topLeftUV.X;
|
||||
spriteInfos[currentBatchPosition].topLeftUV.X = tempX;
|
||||
float tempX = currentSprite.bottomRightUV.X;
|
||||
currentSprite.bottomRightUV.X = currentSprite.topLeftUV.X;
|
||||
currentSprite.topLeftUV.X = tempX;
|
||||
}
|
||||
|
||||
if (rotation != 0f)
|
||||
@ -348,17 +405,22 @@ namespace ANX.Framework.Graphics
|
||||
|
||||
Vector2 transformVector;
|
||||
Vector2 result;
|
||||
float offsetX = topLeft.X + origin.X;
|
||||
float offsetY = topLeft.Y + origin.Y;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
transformVector = spriteInfos[currentBatchPosition].Corners[i] - topLeft - origin;
|
||||
transformVector.X = currentSprite.Corners[i].X - offsetX;
|
||||
transformVector.Y = currentSprite.Corners[i].Y - offsetY;
|
||||
Vector2.Transform(ref transformVector, ref this.cachedRotationMatrix, out result);
|
||||
spriteInfos[currentBatchPosition].Corners[i] = result + topLeft + origin;
|
||||
currentSprite.Corners[i].X = result.X + offsetX;
|
||||
currentSprite.Corners[i].Y = result.Y + offsetY;
|
||||
}
|
||||
}
|
||||
|
||||
spriteInfos[currentBatchPosition].origin = origin;
|
||||
spriteInfos[currentBatchPosition].rotation = rotation;
|
||||
spriteInfos[currentBatchPosition].layerDepth = layerDepth;
|
||||
currentSprite.origin = origin;
|
||||
currentSprite.rotation = rotation;
|
||||
currentSprite.layerDepth = layerDepth;
|
||||
spriteInfos[currentBatchPosition] = currentSprite;
|
||||
|
||||
currentBatchPosition++;
|
||||
|
||||
@ -367,20 +429,18 @@ namespace ANX.Framework.Graphics
|
||||
BatchRender(0, 1);
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void BatchRender(int offset, int count)
|
||||
#region BatchRender
|
||||
private void BatchRender(int offset, int count)
|
||||
{
|
||||
int vertexCount = count * 4;
|
||||
|
||||
if (this.vertices == null)
|
||||
{
|
||||
this.vertices = new VertexPositionColorTexture[vertexCount];
|
||||
}
|
||||
else if (this.vertices.Length < vertexCount)
|
||||
{
|
||||
Array.Resize<VertexPositionColorTexture>(ref this.vertices, vertexCount);
|
||||
}
|
||||
|
||||
int vertexPos = 0;
|
||||
for (int i = offset; i < offset + count; i++)
|
||||
@ -415,27 +475,34 @@ namespace ANX.Framework.Graphics
|
||||
spriteBatchEffect.Parameters["Texture"].SetValue(this.spriteInfos[offset].texture);
|
||||
|
||||
GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertexCount, 0, count * 2);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void Flush()
|
||||
#region Flush
|
||||
private void Flush()
|
||||
{
|
||||
currentBatchPosition = 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void InitializeIndexBuffer(int size)
|
||||
#region InitializeIndexBuffer
|
||||
private void InitializeIndexBuffer(int size)
|
||||
{
|
||||
int indexCount = size * 6;
|
||||
|
||||
if (this.indexBuffer == null)
|
||||
{
|
||||
this.indexBuffer = new DynamicIndexBuffer(this.GraphicsDevice, IndexElementSize.SixteenBits, indexCount, BufferUsage.WriteOnly);
|
||||
this.indexBuffer = new DynamicIndexBuffer(this.GraphicsDevice, IndexElementSize.SixteenBits, indexCount,
|
||||
BufferUsage.WriteOnly);
|
||||
this.indexBuffer.ContentLost += new EventHandler<EventArgs>(indexBuffer_ContentLost);
|
||||
}
|
||||
|
||||
SetIndexData(indexCount);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void indexBuffer_ContentLost(object sender, EventArgs e)
|
||||
#region indexBuffer_ContentLost
|
||||
private void indexBuffer_ContentLost(object sender, EventArgs e)
|
||||
{
|
||||
if (this.indexBuffer != null)
|
||||
{
|
||||
@ -445,11 +512,13 @@ namespace ANX.Framework.Graphics
|
||||
}
|
||||
|
||||
InitializeIndexBuffer(InitialBatchSize);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void SetIndexData(int indexCount)
|
||||
#region SetIndexData
|
||||
private void SetIndexData(int indexCount)
|
||||
{
|
||||
short[] indices = new short[indexCount];
|
||||
var indices = new ushort[indexCount];
|
||||
|
||||
int baseIndex;
|
||||
int baseArrayIndex;
|
||||
@ -458,27 +527,32 @@ namespace ANX.Framework.Graphics
|
||||
baseIndex = i * 4;
|
||||
baseArrayIndex = baseIndex + i + i;
|
||||
|
||||
indices[baseArrayIndex] = (short)baseIndex;
|
||||
indices[baseArrayIndex + 1] = (short)(baseIndex + 1);
|
||||
indices[baseArrayIndex + 2] = (short)(baseIndex + 2);
|
||||
indices[baseArrayIndex + 3] = (short)baseIndex;
|
||||
indices[baseArrayIndex + 4] = (short)(baseIndex + 2);
|
||||
indices[baseArrayIndex + 5] = (short)(baseIndex + 3);
|
||||
indices[baseArrayIndex] = (ushort)baseIndex;
|
||||
indices[baseArrayIndex + 1] = (ushort)(baseIndex + 1);
|
||||
indices[baseArrayIndex + 2] = (ushort)(baseIndex + 2);
|
||||
indices[baseArrayIndex + 3] = (ushort)baseIndex;
|
||||
indices[baseArrayIndex + 4] = (ushort)(baseIndex + 2);
|
||||
indices[baseArrayIndex + 5] = (ushort)(baseIndex + 3);
|
||||
}
|
||||
|
||||
this.indexBuffer.SetData<short>(indices);
|
||||
}
|
||||
this.indexBuffer.SetData<ushort>(indices);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void InitializeVertexBuffer()
|
||||
#region InitializeVertexBuffer
|
||||
private void InitializeVertexBuffer()
|
||||
{
|
||||
if (this.vertexBuffer == null)
|
||||
{
|
||||
this.vertexBuffer = new DynamicVertexBuffer(this.GraphicsDevice, typeof(VertexPositionColorTexture), InitialBatchSize * 4, BufferUsage.WriteOnly);
|
||||
this.vertexBuffer.ContentLost += new EventHandler<EventArgs>(vertexBuffer_ContentLost);
|
||||
this.vertexBuffer = new DynamicVertexBuffer(this.GraphicsDevice, typeof(VertexPositionColorTexture),
|
||||
InitialBatchSize * 4, BufferUsage.WriteOnly);
|
||||
this.vertexBuffer.ContentLost += vertexBuffer_ContentLost;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void vertexBuffer_ContentLost(object sender, EventArgs e)
|
||||
#region vertexBuffer_ContentLost
|
||||
private void vertexBuffer_ContentLost(object sender, EventArgs e)
|
||||
{
|
||||
this.currentBatchPosition = 0;
|
||||
|
||||
@ -490,16 +564,19 @@ namespace ANX.Framework.Graphics
|
||||
}
|
||||
|
||||
InitializeVertexBuffer();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void SetRenderStates()
|
||||
#region SetRenderStates
|
||||
private void SetRenderStates()
|
||||
{
|
||||
GraphicsDevice.BlendState = this.blendState != null ? this.blendState : BlendState.AlphaBlend;
|
||||
GraphicsDevice.DepthStencilState = this.depthStencilState != null ? this.depthStencilState : DepthStencilState.None;
|
||||
GraphicsDevice.RasterizerState = this.rasterizerState != null ? this.rasterizerState : RasterizerState.CullCounterClockwise;
|
||||
GraphicsDevice.SamplerStates[0] = this.samplerState != null ? this.samplerState : SamplerState.LinearClamp;
|
||||
GraphicsDevice.BlendState = blendState != null ? blendState : BlendState.AlphaBlend;
|
||||
GraphicsDevice.DepthStencilState = depthStencilState != null ? depthStencilState : DepthStencilState.None;
|
||||
GraphicsDevice.RasterizerState = rasterizerState != null ? rasterizerState : RasterizerState.CullCounterClockwise;
|
||||
GraphicsDevice.SamplerStates[0] = samplerState != null ? samplerState : SamplerState.LinearClamp;
|
||||
|
||||
if (cachedTransformMatrix == null || GraphicsDevice.Viewport.Width != viewportWidth || GraphicsDevice.Viewport.Height != viewportHeight)
|
||||
if (cachedTransformMatrix == null || GraphicsDevice.Viewport.Width != viewportWidth ||
|
||||
GraphicsDevice.Viewport.Height != viewportHeight)
|
||||
{
|
||||
this.viewportWidth = GraphicsDevice.Viewport.Width;
|
||||
this.viewportHeight = GraphicsDevice.Viewport.Height;
|
||||
@ -518,14 +595,18 @@ namespace ANX.Framework.Graphics
|
||||
cachedTransformMatrix.M42 -= cachedTransformMatrix.M22;
|
||||
}
|
||||
|
||||
this.spriteBatchEffect.Parameters["MatrixTransform"].SetValue(this.transformMatrix * cachedTransformMatrix);
|
||||
Matrix result;
|
||||
Matrix.Multiply(ref transformMatrix, ref cachedTransformMatrix, out result);
|
||||
this.spriteBatchEffect.Parameters["MatrixTransform"].SetValue(result);
|
||||
spriteBatchEffect.NativeEffect.Apply(GraphicsDevice);
|
||||
|
||||
GraphicsDevice.Indices = this.indexBuffer;
|
||||
GraphicsDevice.SetVertexBuffer(this.vertexBuffer);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override void Dispose()
|
||||
#region Dispose
|
||||
public override void Dispose()
|
||||
{
|
||||
if (this.spriteBatchEffect != null)
|
||||
{
|
||||
@ -550,19 +631,18 @@ namespace ANX.Framework.Graphics
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private class TextureComparer : IComparer<SpriteInfo>
|
||||
private class TextureComparer : IComparer<SpriteInfo>
|
||||
{
|
||||
public int Compare(SpriteInfo x, SpriteInfo y)
|
||||
{
|
||||
if (x.texture.GetHashCode() > y.texture.GetHashCode())
|
||||
{
|
||||
int hash1 = x.texture.GetHashCode();
|
||||
int hash2 = y.texture.GetHashCode();
|
||||
if (hash1 > hash2)
|
||||
return -1;
|
||||
}
|
||||
else if (x.texture.GetHashCode() < y.texture.GetHashCode())
|
||||
{
|
||||
else if (hash1 < hash2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -573,13 +653,9 @@ namespace ANX.Framework.Graphics
|
||||
public int Compare(SpriteInfo x, SpriteInfo y)
|
||||
{
|
||||
if (x.layerDepth > y.layerDepth)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (x.layerDepth < y.layerDepth)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -590,17 +666,12 @@ namespace ANX.Framework.Graphics
|
||||
public int Compare(SpriteInfo x, SpriteInfo y)
|
||||
{
|
||||
if (x.layerDepth > y.layerDepth)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (x.layerDepth < y.layerDepth)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
#region Using Statements
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
#endregion // Using Statements
|
||||
using ANX.Framework.NonXNA.Development;
|
||||
|
||||
// This file is part of the ANX.Framework created by the
|
||||
// "ANX.Framework developer group" and released under the Ms-PL license.
|
||||
@ -11,252 +10,262 @@ using System.Text;
|
||||
|
||||
namespace ANX.Framework.Graphics
|
||||
{
|
||||
[PercentageComplete(100)]
|
||||
[TestState(TestStateAttribute.TestState.Untested)]
|
||||
[Developer("Glatzemann, AstrorEnales")]
|
||||
public sealed class SpriteFont
|
||||
{
|
||||
#region Private Members
|
||||
#region Private
|
||||
private Texture2D texture;
|
||||
private List<Rectangle> glyphs;
|
||||
private List<Rectangle> cropping;
|
||||
private Rectangle[] glyphs;
|
||||
private Rectangle[] cropping;
|
||||
private List<char> characterMap;
|
||||
private int lineSpacing;
|
||||
private float horizontalSpacing;
|
||||
private List<Vector3> kerning;
|
||||
private char? defaultCharacter;
|
||||
private ReadOnlyCollection<Char> characters;
|
||||
private Vector3[] kernings;
|
||||
private char? defaultCharacter;
|
||||
Vector2 topLeft;
|
||||
Vector2 position;
|
||||
#endregion
|
||||
|
||||
#endregion // Private Members
|
||||
|
||||
public ReadOnlyCollection<Char> Characters
|
||||
{
|
||||
get { return characters; }
|
||||
}
|
||||
#region Public
|
||||
public ReadOnlyCollection<Char> Characters { get; private set; }
|
||||
public int LineSpacing { get; set; }
|
||||
public float Spacing { get; set; }
|
||||
|
||||
public char? DefaultCharacter
|
||||
{
|
||||
get { return defaultCharacter; }
|
||||
set
|
||||
{
|
||||
if (value.HasValue && !this.characterMap.Contains(value.Value))
|
||||
{
|
||||
if (value.HasValue && this.characterMap.Contains(value.Value) == false)
|
||||
throw new NotSupportedException("Character is not in used font");
|
||||
}
|
||||
|
||||
this.defaultCharacter = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public int LineSpacing
|
||||
{
|
||||
get { return lineSpacing; }
|
||||
set { lineSpacing = value; }
|
||||
}
|
||||
|
||||
public float Spacing
|
||||
{
|
||||
get { return horizontalSpacing; }
|
||||
set { horizontalSpacing = value; }
|
||||
}
|
||||
|
||||
|
||||
internal SpriteFont(
|
||||
Texture2D texture, List<Rectangle> glyphs, List<Rectangle> cropping, List<char> charMap,
|
||||
int lineSpacing, float horizontalSpacing, List<Vector3> kerning, char? defaultCharacter)
|
||||
#region Constructor
|
||||
internal SpriteFont(Texture2D texture, List<Rectangle> glyphs, List<Rectangle> cropping, List<char> charMap,
|
||||
int lineSpacing, float horizontalSpacing, List<Vector3> kerning, char? defaultCharacter)
|
||||
{
|
||||
this.texture = texture;
|
||||
this.glyphs = glyphs;
|
||||
this.cropping = cropping;
|
||||
this.glyphs = glyphs.ToArray();
|
||||
this.cropping = cropping.ToArray();
|
||||
this.characterMap = charMap;
|
||||
this.lineSpacing = lineSpacing;
|
||||
this.horizontalSpacing = horizontalSpacing;
|
||||
this.kerning = kerning;
|
||||
this.LineSpacing = lineSpacing;
|
||||
this.Spacing = horizontalSpacing;
|
||||
this.kernings = kerning.ToArray();
|
||||
this.defaultCharacter = defaultCharacter;
|
||||
|
||||
this.characters = new ReadOnlyCollection<char>(characterMap);
|
||||
Characters = new ReadOnlyCollection<char>(characterMap);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Vector2 MeasureString(string text)
|
||||
#region MeasureString
|
||||
public Vector2 MeasureString(string text)
|
||||
{
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
|
||||
return InternalMeasure(ref text);
|
||||
return InternalMeasure(text);
|
||||
}
|
||||
|
||||
public Vector2 MeasureString(StringBuilder text)
|
||||
{
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
|
||||
String cachedText = text.ToString();
|
||||
return InternalMeasure(ref cachedText);
|
||||
return InternalMeasure(text.ToString());
|
||||
}
|
||||
#endregion
|
||||
|
||||
internal void DrawString(ref String text, SpriteBatch spriteBatch, Vector2 textPos, Color color, Vector2 scale, Vector2 origin, float rotation, float layerDepth, SpriteEffects effects)
|
||||
#region DrawString
|
||||
internal void DrawString(string text, SpriteBatch spriteBatch, Vector2 textPos, Color color, Vector2 scale,
|
||||
Vector2 origin, float rotation, float layerDepth, SpriteEffects effects)
|
||||
{
|
||||
Matrix transformation = Matrix.CreateRotationZ(rotation) * Matrix.CreateTranslation(-origin.X * scale.X, -origin.Y * scale.Y, 0f);
|
||||
Matrix rotationMatrix;
|
||||
Matrix.CreateRotationZ(rotation, out rotationMatrix);
|
||||
Matrix translationMatrix;
|
||||
Matrix.CreateTranslation(-origin.X * scale.X, -origin.Y * scale.Y, 0f, out translationMatrix);
|
||||
Matrix transformation;
|
||||
Matrix.Multiply(ref rotationMatrix, ref translationMatrix, out transformation);
|
||||
|
||||
topLeft.X = topLeft.Y = 0f;
|
||||
int horizontalFlipModifier = 1;
|
||||
float width = 0f;
|
||||
Vector2 topLeft = new Vector2();
|
||||
bool firstCharacterInLine = true;
|
||||
bool flipVertically = (effects & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically;
|
||||
bool flipHorizontally = (effects & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally;
|
||||
|
||||
if ((effects & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally)
|
||||
if (flipHorizontally)
|
||||
{
|
||||
topLeft.X = width = this.InternalMeasure(ref text).X * scale.X;
|
||||
topLeft.X = width = InternalMeasure(text).X * scale.X;
|
||||
horizontalFlipModifier = -1;
|
||||
}
|
||||
|
||||
if ((effects & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically)
|
||||
{
|
||||
topLeft.Y = (this.InternalMeasure(ref text).Y - this.lineSpacing) * scale.Y;
|
||||
}
|
||||
if (flipVertically)
|
||||
topLeft.Y = (InternalMeasure(text).Y - LineSpacing) * scale.Y;
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
char currentCharacter = text[i];
|
||||
switch (currentCharacter)
|
||||
{
|
||||
case '\r':
|
||||
break;
|
||||
bool firstCharacterInLine = true;
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
char currentCharacter = text[i];
|
||||
if (currentCharacter == '\r')
|
||||
continue;
|
||||
|
||||
case '\n':
|
||||
firstCharacterInLine = true;
|
||||
topLeft.X = width;
|
||||
if ((effects & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically)
|
||||
{
|
||||
topLeft.Y -= this.lineSpacing * scale.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
topLeft.Y += this.lineSpacing * scale.Y;
|
||||
}
|
||||
break;
|
||||
if (currentCharacter == '\n')
|
||||
{
|
||||
firstCharacterInLine = true;
|
||||
topLeft.X = width;
|
||||
float factor = LineSpacing * scale.Y;
|
||||
topLeft.Y += flipVertically ? -factor : factor;
|
||||
continue;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
int characterIndex = GetIndexForCharacter(currentCharacter);
|
||||
Vector3 kerning = this.kerning[characterIndex];
|
||||
Rectangle glyphRect = this.glyphs[characterIndex];
|
||||
Rectangle croppingRect = this.cropping[characterIndex];
|
||||
int characterIndex = GetIndexForCharacter(currentCharacter);
|
||||
Vector3 kerning = kernings[characterIndex];
|
||||
Rectangle croppingRect = cropping[characterIndex];
|
||||
|
||||
if (firstCharacterInLine)
|
||||
{
|
||||
kerning.X = Math.Max(kerning.X, 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
topLeft.X += (this.Spacing * scale.X) * horizontalFlipModifier;
|
||||
}
|
||||
topLeft.X += (kerning.X * scale.X) * horizontalFlipModifier;
|
||||
if (firstCharacterInLine)
|
||||
kerning.X = Math.Max(kerning.X, 0f);
|
||||
else
|
||||
topLeft.X += (Spacing * scale.X) * horizontalFlipModifier;
|
||||
|
||||
if ((effects & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically)
|
||||
{
|
||||
croppingRect.Y = (this.lineSpacing - glyphRect.Height) - croppingRect.Y;
|
||||
}
|
||||
if ((effects & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
croppingRect.X -= croppingRect.Width;
|
||||
}
|
||||
Vector2 position = Vector2.Transform(topLeft + (new Vector2(croppingRect.X, croppingRect.Y) * scale), transformation);
|
||||
spriteBatch.Draw(this.texture, position + textPos, glyphRect, color, rotation, Vector2.Zero, scale, effects, layerDepth);
|
||||
firstCharacterInLine = false;
|
||||
topLeft.X += ((kerning.Y + kerning.Z) * scale.X) * horizontalFlipModifier;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
topLeft.X += (kerning.X * scale.X) * horizontalFlipModifier;
|
||||
|
||||
if (flipVertically)
|
||||
croppingRect.Y = (LineSpacing - glyphs[characterIndex].Height) - croppingRect.Y;
|
||||
|
||||
if (flipHorizontally)
|
||||
croppingRect.X -= croppingRect.Width;
|
||||
|
||||
position.X = topLeft.X + (croppingRect.X * scale.X);
|
||||
position.Y = topLeft.Y + (croppingRect.Y * scale.Y);
|
||||
Vector2 result;
|
||||
Vector2.Transform(ref position, ref transformation, out result);
|
||||
result.X += textPos.X;
|
||||
result.Y += textPos.Y;
|
||||
spriteBatch.DrawOptimizedText(texture, result, ref glyphs[characterIndex], ref color, rotation, scale,
|
||||
effects, layerDepth);
|
||||
firstCharacterInLine = false;
|
||||
topLeft.X += ((kerning.Y + kerning.Z) * scale.X) * horizontalFlipModifier;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private Vector2 InternalMeasure(ref String text)
|
||||
#region DrawString
|
||||
internal void DrawString(string text, SpriteBatch spriteBatch, Vector2 textPos, Color color)
|
||||
{
|
||||
topLeft.X = topLeft.Y = 0f;
|
||||
bool firstCharacterInLine = true;
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
char currentCharacter = text[i];
|
||||
if (currentCharacter == '\r')
|
||||
continue;
|
||||
|
||||
if (currentCharacter == '\n')
|
||||
{
|
||||
firstCharacterInLine = true;
|
||||
topLeft.X = 0f;
|
||||
topLeft.Y += LineSpacing;
|
||||
continue;
|
||||
}
|
||||
|
||||
int characterIndex = GetIndexForCharacter(currentCharacter);
|
||||
Vector3 kerning = kernings[characterIndex];
|
||||
Rectangle croppingRect = cropping[characterIndex];
|
||||
|
||||
if (firstCharacterInLine)
|
||||
kerning.X = Math.Max(kerning.X, 0f);
|
||||
else
|
||||
topLeft.X += Spacing;
|
||||
|
||||
topLeft.X += kerning.X;
|
||||
|
||||
position.X = topLeft.X + croppingRect.X + textPos.X;
|
||||
position.Y = topLeft.Y + croppingRect.Y + textPos.Y;
|
||||
spriteBatch.DrawOptimizedText(texture, position, ref glyphs[characterIndex], ref color);
|
||||
firstCharacterInLine = false;
|
||||
topLeft.X += kerning.Y + kerning.Z;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region InternalMeasure
|
||||
private Vector2 InternalMeasure(string text)
|
||||
{
|
||||
if (text.Length < 1)
|
||||
{
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
Vector2 size = Vector2.Zero;
|
||||
size.Y = this.lineSpacing;
|
||||
size.Y = this.LineSpacing;
|
||||
float maxWidth = 0f;
|
||||
int currentCharacter = 0;
|
||||
float z = 0f;
|
||||
bool firstCharacterInLine = true;
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
char currentChar = text[i];
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
char currentChar = text[i];
|
||||
if (currentChar == '\r')
|
||||
continue;
|
||||
|
||||
if (currentChar == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (currentChar == '\n')
|
||||
{
|
||||
size.X += Math.Max(z, 0f);
|
||||
z = 0f;
|
||||
maxWidth = Math.Max(size.X, maxWidth);
|
||||
size = Vector2.Zero;
|
||||
size.Y = LineSpacing;
|
||||
firstCharacterInLine = true;
|
||||
currentCharacter++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentChar == '\n')
|
||||
{
|
||||
size.X += Math.Max(z, 0f);
|
||||
z = 0f;
|
||||
maxWidth = Math.Max(size.X, maxWidth);
|
||||
size = Vector2.Zero;
|
||||
size.Y = this.lineSpacing;
|
||||
firstCharacterInLine = true;
|
||||
currentCharacter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int currentCharIndex = this.GetIndexForCharacter(currentChar);
|
||||
Vector3 kerning = this.kerning[currentCharIndex];
|
||||
if (firstCharacterInLine)
|
||||
{
|
||||
kerning.X = Math.Max(kerning.X, 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
size.X += this.Spacing + z;
|
||||
}
|
||||
size.X += kerning.X + kerning.Y;
|
||||
z = kerning.Z;
|
||||
size.Y = Math.Max(size.Y, (float)this.cropping[currentCharIndex].Height);
|
||||
firstCharacterInLine = false;
|
||||
}
|
||||
}
|
||||
size.Y += currentCharacter * this.lineSpacing;
|
||||
int currentCharIndex = GetIndexForCharacter(currentChar);
|
||||
Vector3 kerning = kernings[currentCharIndex];
|
||||
if (firstCharacterInLine)
|
||||
kerning.X = Math.Max(kerning.X, 0f);
|
||||
else
|
||||
size.X += this.Spacing + z;
|
||||
|
||||
size.X += kerning.X + kerning.Y;
|
||||
z = kerning.Z;
|
||||
size.Y = Math.Max(size.Y, (float)cropping[currentCharIndex].Height);
|
||||
firstCharacterInLine = false;
|
||||
}
|
||||
|
||||
size.Y += currentCharacter * LineSpacing;
|
||||
size.X = Math.Max(Math.Max(z, 0) + size.X, maxWidth);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private int GetIndexForCharacter(char character)
|
||||
{
|
||||
int currentIndex = 0;
|
||||
int upperBound = this.characterMap.Count - 1;
|
||||
char testChar;
|
||||
int searchPos;
|
||||
#region GetIndexForCharacter
|
||||
private int GetIndexForCharacter(char character)
|
||||
{
|
||||
int currentIndex = 0;
|
||||
int upperBound = this.characterMap.Count - 1;
|
||||
char testChar;
|
||||
int searchPos;
|
||||
|
||||
while (currentIndex <= upperBound)
|
||||
{
|
||||
searchPos = currentIndex + ((upperBound - currentIndex) >> 1);
|
||||
testChar = this.characterMap[searchPos];
|
||||
if (testChar == character)
|
||||
{
|
||||
return searchPos;
|
||||
}
|
||||
else if (testChar > character)
|
||||
{
|
||||
upperBound = searchPos - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentIndex = searchPos + 1;
|
||||
}
|
||||
}
|
||||
while (currentIndex <= upperBound)
|
||||
{
|
||||
searchPos = currentIndex + ((upperBound - currentIndex) >> 1);
|
||||
testChar = characterMap[searchPos];
|
||||
if (testChar == character)
|
||||
return searchPos;
|
||||
else if (testChar > character)
|
||||
upperBound = searchPos - 1;
|
||||
else
|
||||
currentIndex = searchPos + 1;
|
||||
}
|
||||
|
||||
if (this.defaultCharacter.HasValue)
|
||||
{
|
||||
return this.GetIndexForCharacter(this.defaultCharacter.Value);
|
||||
}
|
||||
|
||||
throw new ArgumentException("character not found");
|
||||
}
|
||||
if (defaultCharacter.HasValue)
|
||||
return GetIndexForCharacter(defaultCharacter.Value);
|
||||
|
||||
throw new ArgumentException("character not found");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -8,16 +8,13 @@ namespace ANX.Framework.Graphics
|
||||
{
|
||||
internal struct SpriteInfo
|
||||
{
|
||||
//public Vector2 TopLeft;
|
||||
//public Vector2 BottomRight;
|
||||
|
||||
public Vector2[] Corners;
|
||||
|
||||
public Color Tint;
|
||||
public Texture2D texture;
|
||||
public Single rotation;
|
||||
public float rotation;
|
||||
public Vector2 origin;
|
||||
public Single layerDepth;
|
||||
public float layerDepth;
|
||||
|
||||
public Vector2 topLeftUV;
|
||||
public Vector2 bottomRightUV;
|
||||
|
@ -16,6 +16,9 @@ namespace ANX.Framework.Graphics
|
||||
protected internal int width;
|
||||
protected internal int height;
|
||||
|
||||
internal float OneOverWidth;
|
||||
internal float OneOverHeight;
|
||||
|
||||
private INativeTexture2D nativeTexture2D;
|
||||
private INativeTexture2D NativeTexture2D
|
||||
{
|
||||
@ -66,6 +69,8 @@ namespace ANX.Framework.Graphics
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
OneOverWidth = 1f / width;
|
||||
OneOverHeight = 1f / height;
|
||||
|
||||
base.levelCount = 1;
|
||||
base.format = SurfaceFormat.Color;
|
||||
@ -79,6 +84,9 @@ namespace ANX.Framework.Graphics
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
OneOverWidth = 1f / width;
|
||||
OneOverHeight = 1f / height;
|
||||
|
||||
// TODO: pass the mipmap parameter to the creation of the texture to let the graphics card generate mipmaps!
|
||||
base.levelCount = 1;
|
||||
base.format = format;
|
||||
@ -91,6 +99,8 @@ namespace ANX.Framework.Graphics
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
OneOverWidth = 1f / width;
|
||||
OneOverHeight = 1f / height;
|
||||
|
||||
base.levelCount = mipCount;
|
||||
base.format = format;
|
||||
|
@ -16,9 +16,6 @@ namespace ANX.Framework.Graphics
|
||||
public class VertexBuffer : GraphicsResource, IGraphicsResource
|
||||
{
|
||||
#region Private
|
||||
private VertexDeclaration vertexDeclaration;
|
||||
private int vertexCount;
|
||||
private BufferUsage bufferUsage;
|
||||
private INativeVertexBuffer nativeVertexBuffer;
|
||||
#endregion
|
||||
|
||||
@ -29,55 +26,31 @@ namespace ANX.Framework.Graphics
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.nativeVertexBuffer == null)
|
||||
{
|
||||
if (nativeVertexBuffer == null)
|
||||
CreateNativeBuffer();
|
||||
}
|
||||
|
||||
return this.nativeVertexBuffer;
|
||||
return nativeVertexBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
public BufferUsage BufferUsage
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.bufferUsage;
|
||||
}
|
||||
}
|
||||
|
||||
public int VertexCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.vertexCount;
|
||||
}
|
||||
}
|
||||
|
||||
public VertexDeclaration VertexDeclaration
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.vertexDeclaration;
|
||||
}
|
||||
}
|
||||
public BufferUsage BufferUsage { get; private set; }
|
||||
public int VertexCount { get; private set; }
|
||||
public VertexDeclaration VertexDeclaration { get; private set; }
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
public VertexBuffer(GraphicsDevice graphicsDevice, Type vertexType,
|
||||
int vertexCount, BufferUsage usage)
|
||||
: this(graphicsDevice, VertexBuffer.TypeToVertexDeclaration(vertexType),
|
||||
vertexCount, usage)
|
||||
public VertexBuffer(GraphicsDevice graphicsDevice, Type vertexType, int vertexCount, BufferUsage usage)
|
||||
: this(graphicsDevice, VertexTypeHelper.GetDeclaration(vertexType), vertexCount, usage)
|
||||
{
|
||||
}
|
||||
|
||||
public VertexBuffer(GraphicsDevice graphicsDevice,
|
||||
VertexDeclaration vertexDeclaration, int vertexCount, BufferUsage usage)
|
||||
public VertexBuffer(GraphicsDevice graphicsDevice, VertexDeclaration vertexDeclaration, int vertexCount,
|
||||
BufferUsage usage)
|
||||
: base(graphicsDevice)
|
||||
{
|
||||
this.vertexCount = vertexCount;
|
||||
this.vertexDeclaration = vertexDeclaration;
|
||||
this.bufferUsage = usage;
|
||||
VertexCount = vertexCount;
|
||||
VertexDeclaration = vertexDeclaration;
|
||||
BufferUsage = usage;
|
||||
|
||||
base.GraphicsDevice.ResourceCreated += GraphicsDevice_ResourceCreated;
|
||||
base.GraphicsDevice.ResourceDestroyed += GraphicsDevice_ResourceDestroyed;
|
||||
@ -120,17 +93,16 @@ namespace ANX.Framework.Graphics
|
||||
#region CreateNativeBuffer
|
||||
private void CreateNativeBuffer()
|
||||
{
|
||||
this.nativeVertexBuffer =
|
||||
AddInSystemFactory.Instance.GetDefaultCreator<IRenderSystemCreator>().CreateVertexBuffer(GraphicsDevice, this, vertexDeclaration, vertexCount, bufferUsage);
|
||||
var creator = AddInSystemFactory.Instance.GetDefaultCreator<IRenderSystemCreator>();
|
||||
this.nativeVertexBuffer = creator.CreateVertexBuffer(GraphicsDevice, this, VertexDeclaration, VertexCount,
|
||||
BufferUsage);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetData
|
||||
public void GetData<T>(int offsetInBytes, T[] data, int startIndex,
|
||||
int elementCount, int vertexStride) where T : struct
|
||||
public void GetData<T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct
|
||||
{
|
||||
NativeVertexBuffer.GetData(offsetInBytes, data, startIndex,
|
||||
elementCount, vertexStride);
|
||||
NativeVertexBuffer.GetData(offsetInBytes, data, startIndex, elementCount, vertexStride);
|
||||
}
|
||||
|
||||
public void GetData<T>(T[] data) where T : struct
|
||||
@ -138,19 +110,16 @@ namespace ANX.Framework.Graphics
|
||||
NativeVertexBuffer.GetData(data);
|
||||
}
|
||||
|
||||
public void GetData<T>(T[] data, int startIndex, int elementCount)
|
||||
where T : struct
|
||||
public void GetData<T>(T[] data, int startIndex, int elementCount) where T : struct
|
||||
{
|
||||
NativeVertexBuffer.GetData(data, startIndex, elementCount);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SetData
|
||||
public void SetData<T>(int offsetInBytes, T[] data, int startIndex,
|
||||
int elementCount, int vertexStride) where T : struct
|
||||
public void SetData<T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct
|
||||
{
|
||||
NativeVertexBuffer.SetData(GraphicsDevice, offsetInBytes, data,
|
||||
startIndex, elementCount, vertexStride);
|
||||
NativeVertexBuffer.SetData(GraphicsDevice, offsetInBytes, data, startIndex, elementCount, vertexStride);
|
||||
}
|
||||
|
||||
public void SetData<T>(T[] data) where T : struct
|
||||
@ -164,19 +133,6 @@ namespace ANX.Framework.Graphics
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TypeToVertexDeclaration
|
||||
private static VertexDeclaration TypeToVertexDeclaration(Type t)
|
||||
{
|
||||
IVertexType vt = Activator.CreateInstance(t) as IVertexType;
|
||||
if (vt != null)
|
||||
{
|
||||
return vt.VertexDeclaration;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Dispose
|
||||
public override void Dispose()
|
||||
{
|
||||
@ -186,16 +142,17 @@ namespace ANX.Framework.Graphics
|
||||
nativeVertexBuffer = null;
|
||||
}
|
||||
|
||||
if (vertexDeclaration != null)
|
||||
{
|
||||
// do not dispose the VertexDeclaration here, because it's only a reference
|
||||
vertexDeclaration = null;
|
||||
}
|
||||
// do not dispose the VertexDeclaration here, because it's only a reference
|
||||
if (VertexDeclaration != null)
|
||||
VertexDeclaration = null;
|
||||
}
|
||||
|
||||
protected override void Dispose([MarshalAs(UnmanagedType.U1)] bool disposeManaged)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (disposeManaged)
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -2,6 +2,10 @@
|
||||
using System.Collections.Generic;
|
||||
using ANX.Framework.Graphics;
|
||||
|
||||
// This file is part of the ANX.Framework created by the
|
||||
// "ANX.Framework developer group" and released under the Ms-PL license.
|
||||
// For details see: http://anxframework.codeplex.com/license
|
||||
|
||||
namespace ANX.Framework.NonXNA.RenderSystem
|
||||
{
|
||||
internal static class VertexTypeHelper
|
||||
@ -14,7 +18,17 @@ namespace ANX.Framework.NonXNA.RenderSystem
|
||||
if (rememberedInstances.ContainsKey(type) == false)
|
||||
rememberedInstances.Add(type, Activator.CreateInstance<T>());
|
||||
|
||||
return rememberedInstances[type].VertexDeclaration;
|
||||
var result = rememberedInstances[type];
|
||||
return result != null ? result.VertexDeclaration : null;
|
||||
}
|
||||
|
||||
public static VertexDeclaration GetDeclaration(Type type)
|
||||
{
|
||||
if (rememberedInstances.ContainsKey(type) == false)
|
||||
rememberedInstances.Add(type, Activator.CreateInstance(type) as IVertexType);
|
||||
|
||||
var result = rememberedInstances[type];
|
||||
return result != null ? result.VertexDeclaration : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,11 +21,18 @@ namespace TextRendering
|
||||
|
||||
SpriteFont debugFont;
|
||||
|
||||
int fps = 60;
|
||||
int fpsCount = 0;
|
||||
float fpsTimer = 0f;
|
||||
|
||||
public Game1()
|
||||
{
|
||||
graphics = new GraphicsDeviceManager(this);
|
||||
graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
|
||||
Content.RootDirectory = "SampleContent";
|
||||
|
||||
IsFixedTimeStep = false;
|
||||
graphics.SynchronizeWithVerticalRetrace = false;
|
||||
}
|
||||
|
||||
void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
|
||||
@ -55,6 +62,15 @@ namespace TextRendering
|
||||
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
|
||||
this.Exit();
|
||||
|
||||
fpsCount++;
|
||||
fpsTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
if (fpsTimer >= 1f)
|
||||
{
|
||||
fpsTimer -= 1f;
|
||||
fps = fpsCount;
|
||||
fpsCount = 0;
|
||||
}
|
||||
|
||||
base.Update(gameTime);
|
||||
}
|
||||
|
||||
@ -63,7 +79,7 @@ namespace TextRendering
|
||||
GraphicsDevice.Clear(Color.CornflowerBlue);
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.FrontToBack, null);
|
||||
spriteBatch.DrawString(this.debugFont, "Hello World!", new Vector2(100, 100), Color.White);
|
||||
spriteBatch.DrawString(this.debugFont, "Hello World! FPS: " + fps, new Vector2(100, 100), Color.White);
|
||||
|
||||
spriteBatch.DrawString(this.debugFont, "This screen is powered by the ANX.Framework!\r\nsecond line", new Vector2(100, 100 + this.debugFont.LineSpacing), Color.Black, 0.0f, new Vector2(1, -1), Vector2.One, SpriteEffects.None, 0.0f);
|
||||
spriteBatch.DrawString(this.debugFont, "This screen is powered by the ANX.Framework!\r\nsecond line", new Vector2(100, 100 + this.debugFont.LineSpacing), Color.Red, 0.0f, Vector2.Zero, Vector2.One, SpriteEffects.None, 1.0f);
|
||||
|
@ -11,6 +11,7 @@ namespace TextRendering
|
||||
static void Main(string[] args)
|
||||
{
|
||||
//AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "OpenGL3");
|
||||
AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "DirectX10");
|
||||
//AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "DirectX11");
|
||||
|
||||
using (Game1 game = new Game1())
|
||||
|
Loading…
x
Reference in New Issue
Block a user