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