untested texture atlas pipeline system complete.

This commit is contained in:
Harrison Deng 2018-12-05 02:28:09 -06:00
parent 87823b26d6
commit 4136b1ca22
10 changed files with 162 additions and 51 deletions

View File

@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace RecrownedAthenaeum.Pipeline.NinePatch namespace RecrownedAthenaeum.Pipeline.NinePatch
{ {
class NinePatchFile public class NinePatchData
{ {
public string name; public string name;
public string bounds; public string bounds;

View File

@ -50,18 +50,12 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="NinePatch\NinePatchTemplate.cs" /> <Compile Include="NinePatch\NinePatchData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TextureAtlas\TextureAtlasWriter.cs" /> <Compile Include="TextureAtlas\TextureAtlasWriter.cs" />
<Compile Include="TextureAtlas\TextureAtlasImporter.cs" /> <Compile Include="TextureAtlas\TextureAtlasImporter.cs" />
<Compile Include="TextureAtlas\TextureAtlasProcessor.cs" /> <Compile Include="TextureAtlas\TextureAtlasProcessor.cs" />
<Compile Include="TextureAtlas\TextureAtlasTemplate.cs" /> <Compile Include="TextureAtlas\TextureAtlasData.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RecrownedAthenaeum\RecrownedAthenaeum.csproj">
<Project>{95a926dc-1482-4368-91da-8d30ac04740a}</Project>
<Name>RecrownedAthenaeum</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />

View File

@ -1,4 +1,6 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Newtonsoft.Json;
using RecrownedAthenaeum.Pipeline.NinePatch;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -8,15 +10,16 @@ using System.Xml.Serialization;
namespace RecrownedAthenaeum.Pipeline.TextureAtlas namespace RecrownedAthenaeum.Pipeline.TextureAtlas
{ {
public class TextureAtlasFile public class TextureAtlasData
{ {
public string textureName;
public TextureAtlasRegion[] regions; public TextureAtlasRegion[] regions;
public string textureName;
public class TextureAtlasRegion public class TextureAtlasRegion
{ {
public string name; public string name;
public Rectangle location; public Rectangle location;
public NinePatchData ninePatchData;
} }
} }
} }

View File

@ -1,6 +1,6 @@
using Microsoft.Xna.Framework.Content.Pipeline; using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using RecrownedAthenaeum.DataTypes; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -11,15 +11,16 @@ using System.Xml.Serialization;
namespace RecrownedAthenaeum.Pipeline.TextureAtlas namespace RecrownedAthenaeum.Pipeline.TextureAtlas
{ {
internal class TextureAtlasImporter : ContentImporter<TextureAtlasFile> [ContentImporter(".atlas", DisplayName = "Texture Atlas Importer")]
internal class TextureAtlasImporter : ContentImporter<TextureAtlasData>
{ {
public override TextureAtlasFile Import(string filename, ContentImporterContext context) public override TextureAtlasData Import(string filename, ContentImporterContext context)
{ {
StreamReader stream = new StreamReader(filename); TextureAtlasData atlas;
XmlSerializer serializer = new XmlSerializer(typeof(TextureAtlasFile)); using (StreamReader stream = new StreamReader(filename))
TextureAtlasFile atlas = (TextureAtlasFile)serializer.Deserialize(stream); {
context.AddDependency(atlas.textureName); atlas = JsonConvert.DeserializeObject<TextureAtlasData>(stream.ReadToEnd());
stream.Dispose(); }
return atlas; return atlas;
} }
} }

View File

@ -1,21 +1,35 @@
using Microsoft.Xna.Framework.Content.Pipeline; using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using RecrownedAthenaeum.DataTypes; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace RecrownedAthenaeum.Pipeline.TextureAtlas namespace RecrownedAthenaeum.Pipeline.TextureAtlas
{ {
class TextureAtlasProcessor : ContentProcessor<TextureAtlasFile, TextureAtlasFile> [ContentProcessor(DisplayName = "Texture Atlas Processor")]
class TextureAtlasProcessor : ContentProcessor<TextureAtlasData, byte[]>
{ {
public override TextureAtlasFile Process(TextureAtlasFile input, ContentProcessorContext context) public override byte[] Process(TextureAtlasData input, ContentProcessorContext context)
{ {
return input; string serialized = JsonConvert.SerializeObject(input);
byte[] bytes = Encoding.UTF8.GetBytes(serialized);
MemoryStream outStream = new MemoryStream();
GZipStream gZStream = new GZipStream(outStream, CompressionLevel.Optimal);
gZStream.Write(bytes, 0, bytes.Length);
byte[] compressed = outStream.ToArray();
gZStream.Dispose();
outStream.Dispose();
return compressed;
} }
} }
} }

View File

@ -8,16 +8,18 @@ using System.Threading.Tasks;
namespace RecrownedAthenaeum.Pipeline.TextureAtlas namespace RecrownedAthenaeum.Pipeline.TextureAtlas
{ {
class TextureAtlasWriter : ContentTypeWriter<TextureAtlasFile> [ContentTypeWriter]
class TextureAtlasWriter : ContentTypeWriter<byte[]>
{ {
public override string GetRuntimeReader(TargetPlatform targetPlatform) public override string GetRuntimeReader(TargetPlatform targetPlatform)
{ {
throw new NotImplementedException(); return "RecrownedAthenaeum.Pipeline, TextureAtlasDataReader";
} }
protected override void Write(ContentWriter output, TextureAtlasFile value) protected override void Write(ContentWriter output, byte[] value)
{ {
throw new NotImplementedException(); output.Write(value.Length);
output.Write(value);
} }
} }
} }

View File

@ -11,18 +11,16 @@ namespace RecrownedAthenaeum.DataTypes
{ {
public class NinePatch public class NinePatch
{ {
[XmlIgnore]
public Color color; public Color color;
public Rectangle textureRegion;
[XmlIgnore] readonly TextureAtlas.TextureAtlasRegion region;
readonly Texture2D texture; readonly Texture2D texture;
readonly int a, b, c, d; readonly int a, b, c, d;
/// <summary> /// <summary>
/// A nine patch object. /// A nine patch object.
/// </summary> /// </summary>
/// <param name="texture">Texture used for the nine patch. Dimensions must be greater than their sum border counter parts.</param> /// <param name="texture">Texture used for the nine patch. Dimensions must be greater than their sum border counter parts. If used as part of texture atlas, the texture should be the texture of the entire atlas.</param>
/// <param name="a">Left side.</param> /// <param name="a">Left side.</param>
/// <param name="b">Right side.</param> /// <param name="b">Right side.</param>
/// <param name="c">Bottom side.</param> /// <param name="c">Bottom side.</param>
@ -30,8 +28,9 @@ namespace RecrownedAthenaeum.DataTypes
public NinePatch(Texture2D texture, int a, int b, int c, int d) public NinePatch(Texture2D texture, int a, int b, int c, int d)
{ {
this.texture = texture; this.texture = texture;
if (a + b >= texture.Width) throw new ArgumentOutOfRangeException("a and b cannot be greater than or equal to the width of texture."); textureRegion = texture.Bounds;
if (c + d >= texture.Height) throw new ArgumentOutOfRangeException("c and d cannot be greater or equal to the height of the texture."); if (a + b >= textureRegion.Width) throw new ArgumentOutOfRangeException("a and b cannot be greater than or equal to the width of region.");
if (c + d >= textureRegion.Height) throw new ArgumentOutOfRangeException("c and d cannot be greater or equal to the height of the texture.");
this.a = a; this.a = a;
this.b = b; this.b = b;
this.c = c; this.c = c;
@ -42,6 +41,8 @@ namespace RecrownedAthenaeum.DataTypes
public void Draw(SpriteBatch batch, Rectangle destination) public void Draw(SpriteBatch batch, Rectangle destination)
{ {
Rectangle sourceRectangle; Rectangle sourceRectangle;
Rectangle drawnRectangle; Rectangle drawnRectangle;
@ -56,6 +57,9 @@ namespace RecrownedAthenaeum.DataTypes
sourceRectangle.Width = a; sourceRectangle.Width = a;
sourceRectangle.Height = c; sourceRectangle.Height = c;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
//2x1 //2x1
@ -66,8 +70,10 @@ namespace RecrownedAthenaeum.DataTypes
sourceRectangle.X = a; sourceRectangle.X = a;
sourceRectangle.Y = 0; sourceRectangle.Y = 0;
sourceRectangle.Width = texture.Width - a - b; sourceRectangle.Width = textureRegion.Width - a - b;
sourceRectangle.Height = c; sourceRectangle.Height = c;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
@ -77,10 +83,12 @@ namespace RecrownedAthenaeum.DataTypes
drawnRectangle.Width = b; drawnRectangle.Width = b;
drawnRectangle.Height = c; drawnRectangle.Height = c;
sourceRectangle.X = texture.Width - b; sourceRectangle.X = textureRegion.Width - b;
sourceRectangle.Y = 0; sourceRectangle.Y = 0;
sourceRectangle.Width = b; sourceRectangle.Width = b;
sourceRectangle.Height = c; sourceRectangle.Height = c;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
@ -93,7 +101,9 @@ namespace RecrownedAthenaeum.DataTypes
sourceRectangle.X = 0; sourceRectangle.X = 0;
sourceRectangle.Y = c; sourceRectangle.Y = c;
sourceRectangle.Width = a; sourceRectangle.Width = a;
sourceRectangle.Height = texture.Height - c - d; sourceRectangle.Height = textureRegion.Height - c - d;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
@ -105,8 +115,10 @@ namespace RecrownedAthenaeum.DataTypes
sourceRectangle.X = a; sourceRectangle.X = a;
sourceRectangle.Y = c; sourceRectangle.Y = c;
sourceRectangle.Width = texture.Width - a - b; sourceRectangle.Width = textureRegion.Width - a - b;
sourceRectangle.Height = texture.Height - c - d; sourceRectangle.Height = textureRegion.Height - c - d;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
@ -116,10 +128,12 @@ namespace RecrownedAthenaeum.DataTypes
drawnRectangle.Width = b; drawnRectangle.Width = b;
drawnRectangle.Height = destination.Height - c - d; drawnRectangle.Height = destination.Height - c - d;
sourceRectangle.X = texture.Width - b; sourceRectangle.X = textureRegion.Width - b;
sourceRectangle.Y = c; sourceRectangle.Y = c;
sourceRectangle.Width = b; sourceRectangle.Width = b;
sourceRectangle.Height = texture.Height - c - d; sourceRectangle.Height = textureRegion.Height - c - d;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
@ -130,9 +144,11 @@ namespace RecrownedAthenaeum.DataTypes
drawnRectangle.Height = d; drawnRectangle.Height = d;
sourceRectangle.X = a; sourceRectangle.X = a;
sourceRectangle.Y = texture.Height - d; sourceRectangle.Y = textureRegion.Height - d;
sourceRectangle.Width = a; sourceRectangle.Width = a;
sourceRectangle.Height = d; sourceRectangle.Height = d;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
@ -143,9 +159,11 @@ namespace RecrownedAthenaeum.DataTypes
drawnRectangle.Height = d; drawnRectangle.Height = d;
sourceRectangle.X = a; sourceRectangle.X = a;
sourceRectangle.Y = texture.Height - d; sourceRectangle.Y = textureRegion.Height - d;
sourceRectangle.Width = texture.Width - a - b; sourceRectangle.Width = textureRegion.Width - a - b;
sourceRectangle.Height = d; sourceRectangle.Height = d;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
@ -155,10 +173,12 @@ namespace RecrownedAthenaeum.DataTypes
drawnRectangle.Width = b; drawnRectangle.Width = b;
drawnRectangle.Height = d; drawnRectangle.Height = d;
sourceRectangle.X = texture.Width - b; sourceRectangle.X = textureRegion.Width - b;
sourceRectangle.Y = texture.Height - d; sourceRectangle.Y = textureRegion.Height - d;
sourceRectangle.Width = b; sourceRectangle.Width = b;
sourceRectangle.Height = d; sourceRectangle.Height = d;
sourceRectangle.X += textureRegion.X;
sourceRectangle.Y += textureRegion.Y;
batch.Draw(texture, drawnRectangle, sourceRectangle, color); batch.Draw(texture, drawnRectangle, sourceRectangle, color);
} }

View File

@ -1,5 +1,6 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Newtonsoft.Json;
using RecrownedAthenaeum.DataTypes; using RecrownedAthenaeum.DataTypes;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -12,7 +13,9 @@ namespace RecrownedAthenaeum.DataTypes
{ {
public class TextureAtlas public class TextureAtlas
{ {
[JsonIgnore]
private Texture2D texture; private Texture2D texture;
private Dictionary<string, TextureAtlasRegion> dictionaryOfRegions = new Dictionary<string, TextureAtlasRegion>(); private Dictionary<string, TextureAtlasRegion> dictionaryOfRegions = new Dictionary<string, TextureAtlasRegion>();
public TextureAtlas(Texture2D texture, TextureAtlasRegion[] regions) public TextureAtlas(Texture2D texture, TextureAtlasRegion[] regions)
@ -24,9 +27,15 @@ namespace RecrownedAthenaeum.DataTypes
} }
} }
public TextureAtlas(Texture2D texture, Dictionary<string, TextureAtlasRegion> dictionaryOfRegions)
{
this.texture = texture;
this.dictionaryOfRegions = dictionaryOfRegions;
}
public void Draw(string name, SpriteBatch batch, Rectangle destination, Color color, float rotation = 0, Vector2 origin = new Vector2()) public void Draw(string name, SpriteBatch batch, Rectangle destination, Color color, float rotation = 0, Vector2 origin = new Vector2())
{ {
dictionaryOfRegions[name].Draw(batch, destination, texture, color, rotation, origin); dictionaryOfRegions[name].Draw(batch, destination, color, rotation, origin);
} }
@ -38,20 +47,22 @@ namespace RecrownedAthenaeum.DataTypes
public class TextureAtlasRegion : IComparable<TextureAtlasRegion>, IDisposable public class TextureAtlasRegion : IComparable<TextureAtlasRegion>, IDisposable
{ {
public readonly string name; public readonly string name;
readonly Rectangle sourceRectangle; public readonly Rectangle sourceRectangle;
readonly NinePatch ninepatch; readonly NinePatch ninepatch;
Texture2D atlasTexture;
Texture2D regionTexture; Texture2D regionTexture;
public TextureAtlasRegion(string name, Rectangle source, NinePatch ninePatch) public TextureAtlasRegion(string name, Rectangle source, NinePatch ninePatch, Texture2D atlasTexture)
{ {
this.atlasTexture = atlasTexture;
this.name = name; this.name = name;
this.sourceRectangle = source; this.sourceRectangle = source;
this.ninepatch = ninePatch; this.ninepatch = ninePatch;
} }
public void Draw(SpriteBatch batch, Rectangle destination, Texture2D fromTexture, Color color, float rotation, Vector2 origin) public void Draw(SpriteBatch batch, Rectangle destination, Color color, float rotation, Vector2 origin)
{ {
batch.Draw(fromTexture, destination, sourceRectangle, color, rotation, origin, SpriteEffects.None, 0f); batch.Draw(atlasTexture, destination, sourceRectangle, color, rotation, origin, SpriteEffects.None, 0f);
} }
public Texture2D AsTexture2D(GraphicsDevice graphicsDevice, Texture2D textureAtlas) public Texture2D AsTexture2D(GraphicsDevice graphicsDevice, Texture2D textureAtlas)

View File

@ -0,0 +1,59 @@
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Newtonsoft.Json;
using RecrownedAthenaeum.DataTypes;
using RecrownedAthenaeum.Pipeline.NinePatch;
using RecrownedAthenaeum.Pipeline.TextureAtlas;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RecrownedAthenaeum.Pipeline
{
class TextureAtlasDataReader : ContentTypeReader<DataTypes.TextureAtlas>
{
protected override DataTypes.TextureAtlas Read(ContentReader input, DataTypes.TextureAtlas existingInstance)
{
int length = input.ReadInt32();
byte[] compressedBytes = input.ReadBytes(length);
byte[] decompressedBytes;
using (MemoryStream inStream = new MemoryStream(compressedBytes))
{
using (GZipStream gZStream = new GZipStream(inStream, CompressionLevel.Optimal))
{
using (MemoryStream outStream = new MemoryStream())
{
gZStream.CopyTo(outStream);
decompressedBytes = outStream.ToArray();
}
}
}
TextureAtlasData atlasData = JsonConvert.DeserializeObject<TextureAtlasData>(Encoding.UTF8.GetString(decompressedBytes));
DataTypes.TextureAtlas atlas;
Texture2D atlasTexture = input.ContentManager.Load<Texture2D>(atlasData.textureName);
DataTypes.TextureAtlas.TextureAtlasRegion[] regions = new DataTypes.TextureAtlas.TextureAtlasRegion[atlasData.regions.Length];
for (int regionID = 0; regionID < regions.Length; regionID++)
{
TextureAtlasData.TextureAtlasRegion regionData = atlasData.regions[regionID];
DataTypes.NinePatch nPatch = null;
if (regionData.ninePatchData != null)
{
NinePatchData nPatchData = regionData.ninePatchData;
nPatch = new DataTypes.NinePatch(atlasTexture, nPatchData.a, nPatchData.b, nPatchData.c, nPatchData.d);
}
regions[regionID] = new DataTypes.TextureAtlas.TextureAtlasRegion(regionData.name, regionData.location, nPatch, atlasTexture);
}
atlas = new DataTypes.TextureAtlas(atlasTexture, regions);
return atlas;
}
}
}

View File

@ -65,6 +65,7 @@
<Compile Include="obj\Debug\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs" /> <Compile Include="obj\Debug\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs" />
<Compile Include="ParticleSystem\Particle.cs" /> <Compile Include="ParticleSystem\Particle.cs" />
<Compile Include="Persistence\PreferencesManager.cs" /> <Compile Include="Persistence\PreferencesManager.cs" />
<Compile Include="Pipeline\TextureAtlasDataReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScreenSystem\ITransition.cs" /> <Compile Include="ScreenSystem\ITransition.cs" />
<Compile Include="ScreenSystem\LoadingScreen.cs" /> <Compile Include="ScreenSystem\LoadingScreen.cs" />
@ -91,5 +92,11 @@
<Folder Include="bin\Release\" /> <Folder Include="bin\Release\" />
<Folder Include="obj\Debug\TempPE\" /> <Folder Include="obj\Debug\TempPE\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RecrownedAthenaeum.Pipeline\RecrownedAthenaeum.Pipeline.csproj">
<Project>{b38f9812-b1d1-4bfe-89ee-fc4dd4ebaa3f}</Project>
<Name>RecrownedAthenaeum.Pipeline</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>