瀏覽代碼

Merge pull request #3 from tainicom/TextureAtlas

Add AtlasImporter and Samples.Atlas
Nikos Kastellanos 8 年之前
父節點
當前提交
23baed589d
共有 80 個文件被更改,包括 2106 次插入0 次删除
  1. 6 0
      Aether.Extras.PORTABLE.sln
  2. 13 0
      Aether.Extras.WINDOWS.MG.sln
  3. 13 0
      Aether.Extras.WINDOWS.XNA.sln
  4. 52 0
      Atlas/Aether.Atlas.PORTABLE.csproj
  5. 64 0
      Atlas/Aether.Atlas.WINDOWS.MG.csproj
  6. 78 0
      Atlas/Aether.Atlas.WINDOWS.XNA.csproj
  7. 34 0
      Atlas/Atlas/Extensions.cs
  8. 33 0
      Atlas/Atlas/Sprite.cs
  9. 31 0
      Atlas/Atlas/TextureAtlas.cs
  10. 70 0
      Atlas/ContentReaders/TextureAtlasReader.cs
  11. 24 0
      Atlas/Properties/AssemblyInfo.PORTABLE.cs
  12. 41 0
      Atlas/Properties/AssemblyInfo.cs
  13. 4 0
      Atlas/packages.config
  14. 27 0
      Content.Pipeline/AtlasImporter/Atlas/SourceContent.cs
  15. 28 0
      Content.Pipeline/AtlasImporter/Atlas/SpriteContent.cs
  16. 29 0
      Content.Pipeline/AtlasImporter/Atlas/TextureAtlasContent.cs
  17. 69 0
      Content.Pipeline/AtlasImporter/AtlasImporter.WINDOWS.MG.csproj
  18. 63 0
      Content.Pipeline/AtlasImporter/AtlasImporter.WINDOWS.XNA.csproj
  19. 190 0
      Content.Pipeline/AtlasImporter/AtlasImporter.cs
  20. 131 0
      Content.Pipeline/AtlasImporter/Processors/TextureAtlasProcessor.cs
  21. 28 0
      Content.Pipeline/AtlasImporter/Properties/AssemblyInfo.cs
  22. 53 0
      Content.Pipeline/AtlasImporter/Serialization/TextureAtlasWriter.cs
  23. 5 0
      Content.Pipeline/AtlasImporter/packages.config
  24. 1 0
      README.md
  25. 23 0
      Samples.WINDOWS.MG.sln
  26. 25 0
      Samples.WINDOWS.XNA.sln
  27. 二進制
      Samples/Atlas/Game.ico
  28. 146 0
      Samples/Atlas/Game1.cs
  29. 二進制
      Samples/Atlas/GameThumbnail.png
  30. 二進制
      Samples/Atlas/Icon.ico
  31. 19 0
      Samples/Atlas/Program.cs
  32. 34 0
      Samples/Atlas/Properties/AssemblyInfo.cs
  33. 81 0
      Samples/Atlas/Samples.Atlas.WINDOWS.MG.csproj
  34. 129 0
      Samples/Atlas/Samples.Atlas.WINDOWS.XNA.csproj
  35. 3 0
      Samples/Atlas/app.config
  36. 42 0
      Samples/Atlas/app.manifest
  37. 100 0
      Samples/AtlasContent/AtlasNoMipmap.tmx
  38. 二進制
      Samples/AtlasContent/Object/Bush_1.png
  39. 二進制
      Samples/AtlasContent/Object/Bush_2.png
  40. 二進制
      Samples/AtlasContent/Object/Bush_3.png
  41. 二進制
      Samples/AtlasContent/Object/Bush_4.png
  42. 二進制
      Samples/AtlasContent/Object/Crate.png
  43. 二進制
      Samples/AtlasContent/Object/Mushroom_1.png
  44. 二進制
      Samples/AtlasContent/Object/Mushroom_2.png
  45. 二進制
      Samples/AtlasContent/Object/Sign_1.png
  46. 二進制
      Samples/AtlasContent/Object/Sign_2.png
  47. 二進制
      Samples/AtlasContent/Object/Stone.png
  48. 二進制
      Samples/AtlasContent/Object/Tree_1.png
  49. 二進制
      Samples/AtlasContent/Object/Tree_2.png
  50. 二進制
      Samples/AtlasContent/Object/Tree_3.png
  51. 89 0
      Samples/AtlasContent/Samples.AtlasContent.contentproj
  52. 65 0
      Samples/AtlasContent/Samples.AtlasContent.mgcb
  53. 二進制
      Samples/AtlasContent/Tiles/1.png
  54. 二進制
      Samples/AtlasContent/Tiles/10.png
  55. 二進制
      Samples/AtlasContent/Tiles/11.png
  56. 二進制
      Samples/AtlasContent/Tiles/12.png
  57. 二進制
      Samples/AtlasContent/Tiles/13.png
  58. 二進制
      Samples/AtlasContent/Tiles/14.png
  59. 二進制
      Samples/AtlasContent/Tiles/15.png
  60. 二進制
      Samples/AtlasContent/Tiles/16.png
  61. 二進制
      Samples/AtlasContent/Tiles/17.png
  62. 二進制
      Samples/AtlasContent/Tiles/18.png
  63. 二進制
      Samples/AtlasContent/Tiles/2.png
  64. 二進制
      Samples/AtlasContent/Tiles/3.png
  65. 二進制
      Samples/AtlasContent/Tiles/4.png
  66. 二進制
      Samples/AtlasContent/Tiles/5.png
  67. 二進制
      Samples/AtlasContent/Tiles/6.png
  68. 二進制
      Samples/AtlasContent/Tiles/7.png
  69. 二進制
      Samples/AtlasContent/Tiles/8.png
  70. 二進制
      Samples/AtlasContent/Tiles/9.png
  71. 100 0
      Samples/AtlasContent/atlasMipmap.tmx
  72. 100 0
      Samples/AtlasContent/atlasMipmapPerSprite.tmx
  73. 60 0
      Samples/AtlasContent/font.spritefont
  74. 1 0
      Samples/AtlasContent/free-platformer-game-tileset.txt
  75. 二進制
      bin/Release/Portable/Aether.Atlas.dll
  76. 二進制
      bin/Release/Windows.XNA/Aether.Atlas.dll
  77. 二進制
      bin/Release/Windows.XNA/Aether.Content.Pipeline.AtlasImporter.dll
  78. 二進制
      bin/Release/Windows/Aether.Atlas.dll
  79. 二進制
      bin/Release/Windows/Aether.Content.Pipeline.AtlasImporter.dll
  80. 2 0
      packages/repositories.config

+ 6 - 0
Aether.Extras.PORTABLE.sln

@@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Animation.PORTABLE",
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnimationImporters.PORTABLE", "Content.Pipeline\AnimationImporters\AnimationImporters.PORTABLE.csproj", "{962D579A-91F7-4FAB-940A-423E04B8465E}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Atlas.PORTABLE", "Atlas\Aether.Atlas.PORTABLE.csproj", "{E5907795-BC19-4CAA-9909-9F7145E1BB0D}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -41,6 +43,10 @@ Global
 		{962D579A-91F7-4FAB-940A-423E04B8465E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{962D579A-91F7-4FAB-940A-423E04B8465E}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{962D579A-91F7-4FAB-940A-423E04B8465E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E5907795-BC19-4CAA-9909-9F7145E1BB0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E5907795-BC19-4CAA-9909-9F7145E1BB0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E5907795-BC19-4CAA-9909-9F7145E1BB0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E5907795-BC19-4CAA-9909-9F7145E1BB0D}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 13 - 0
Aether.Extras.WINDOWS.MG.sln

@@ -23,6 +23,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.FXAA.WINDOWS
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.Deferred.WINDOWS.MG", "Shaders\Deferred\Aether.Shaders.Deferred.WINDOWS.MG.csproj", "{96105100-20DB-4187-9BCA-0A20AC9F1298}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtlasImporter.WINDOWS.MG", "Content.Pipeline\AtlasImporter\AtlasImporter.WINDOWS.MG.csproj", "{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Atlas.WINDOWS.MG", "Atlas\Aether.Atlas.WINDOWS.MG.csproj", "{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -61,6 +65,14 @@ Global
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -72,5 +84,6 @@ Global
 		{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 		{FBBDE2BA-F9F3-4041-8584-2C912C235E26} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
 		{96105100-20DB-4187-9BCA-0A20AC9F1298} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 	EndGlobalSection
 EndGlobal

+ 13 - 0
Aether.Extras.WINDOWS.XNA.sln

@@ -17,6 +17,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.FXAA.WINDOWS
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.Deferred.WINDOWS.XNA", "Shaders\Deferred\Aether.Shaders.Deferred.WINDOWS.XNA.csproj", "{B82B862D-C728-4A10-8A56-65D688E022C8}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtlasImporter.WINDOWS.XNA", "Content.Pipeline\AtlasImporter\AtlasImporter.WINDOWS.XNA.csproj", "{90E6017D-198B-4470-BF9B-8B8791C295CC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Atlas.WINDOWS.XNA", "Atlas\Aether.Atlas.WINDOWS.XNA.csproj", "{644629BB-1A4E-4932-8E50-4F93BC938794}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86
@@ -47,6 +51,14 @@ Global
 		{B82B862D-C728-4A10-8A56-65D688E022C8}.Debug|x86.Build.0 = Debug|x86
 		{B82B862D-C728-4A10-8A56-65D688E022C8}.Release|x86.ActiveCfg = Release|x86
 		{B82B862D-C728-4A10-8A56-65D688E022C8}.Release|x86.Build.0 = Release|x86
+		{90E6017D-198B-4470-BF9B-8B8791C295CC}.Debug|x86.ActiveCfg = Debug|x86
+		{90E6017D-198B-4470-BF9B-8B8791C295CC}.Debug|x86.Build.0 = Debug|x86
+		{90E6017D-198B-4470-BF9B-8B8791C295CC}.Release|x86.ActiveCfg = Release|x86
+		{90E6017D-198B-4470-BF9B-8B8791C295CC}.Release|x86.Build.0 = Release|x86
+		{644629BB-1A4E-4932-8E50-4F93BC938794}.Debug|x86.ActiveCfg = Debug|x86
+		{644629BB-1A4E-4932-8E50-4F93BC938794}.Debug|x86.Build.0 = Debug|x86
+		{644629BB-1A4E-4932-8E50-4F93BC938794}.Release|x86.ActiveCfg = Release|x86
+		{644629BB-1A4E-4932-8E50-4F93BC938794}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -54,6 +66,7 @@ Global
 	GlobalSection(NestedProjects) = preSolution
 		{565ACF47-7E36-435E-8727-2AFB39E61134} = {F6B6E505-6037-49E4-9060-8B29A7B99BC1}
 		{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E} = {F6B6E505-6037-49E4-9060-8B29A7B99BC1}
+		{90E6017D-198B-4470-BF9B-8B8791C295CC} = {F6B6E505-6037-49E4-9060-8B29A7B99BC1}
 		{89E0198E-7298-411A-B5C1-61F2754A3F80} = {EFC7A27C-C20B-4BE7-8B3A-2B109991D704}
 		{B82B862D-C728-4A10-8A56-65D688E022C8} = {EFC7A27C-C20B-4BE7-8B3A-2B109991D704}
 	EndGlobalSection

+ 52 - 0
Atlas/Aether.Atlas.PORTABLE.csproj

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ProjectGuid>{E5907795-BC19-4CAA-9909-9F7145E1BB0D}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>tainicom.Aether.Atlas</RootNamespace>
+    <AssemblyName>Aether.Atlas</AssemblyName>
+    <TargetFrameworkProfile>Profile328</TargetFrameworkProfile>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\Portable\</OutputPath>
+    <DefineConstants>DEBUG;PORTABLE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\Portable\</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <DefineConstants>PORTABLE</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Atlas\Extensions.cs" />
+    <Compile Include="Atlas\Sprite.cs" />
+    <Compile Include="Atlas\TextureAtlas.cs" />
+    <Compile Include="ContentReaders\TextureAtlasReader.cs" />
+    <Compile Include="Properties\AssemblyInfo.PORTABLE.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework">
+      <HintPath>..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup />
+</Project>

+ 64 - 0
Atlas/Aether.Atlas.WINDOWS.MG.csproj

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}</ProjectGuid>
+    <ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Atlas</RootNamespace>
+    <AssemblyName>Aether.Atlas</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\Windows\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS MG MAPPEDMEM</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\Windows\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS MG MAPPEDMEM</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework">
+      <HintPath>..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="mscorlib" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Atlas\Extensions.cs" />
+    <Compile Include="Atlas\Sprite.cs" />
+    <Compile Include="Atlas\TextureAtlas.cs" />
+    <Compile Include="ContentReaders\TextureAtlasReader.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+      Other similar extension points exist, see Microsoft.Common.targets.
+      <Target Name="BeforeBuild">
+      </Target>
+      <Target Name="AfterBuild">
+      </Target>
+    -->
+</Project>

+ 78 - 0
Atlas/Aether.Atlas.WINDOWS.XNA.csproj

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{644629BB-1A4E-4932-8E50-4F93BC938794}</ProjectGuid>
+    <ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Atlas</RootNamespace>
+    <AssemblyName>Aether.Atlas</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <XnaPlatform>Windows</XnaPlatform>
+    <XnaProfile>Reach</XnaProfile>
+    <XnaCrossPlatformGroupID>AD078DF8-7D5B-4648-A4FD-684E5EC62024</XnaCrossPlatformGroupID>
+    <XnaOutputType>Library</XnaOutputType>
+    <!--
+    <XnaRefreshLevel>1</XnaRefreshLevel>
+    -->
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\Windows.XNA\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaCompressContent>false</XnaCompressContent>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\Windows.XNA\</OutputPath>
+    <DefineConstants>WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaCompressContent>true</XnaCompressContent>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Atlas\Extensions.cs" />
+    <Compile Include="Atlas\Sprite.cs" />
+    <Compile Include="Atlas\TextureAtlas.cs" />
+    <Compile Include="ContentReaders\TextureAtlasReader.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
+  <!--
+      To modify your build process, add your task inside one of the targets below and uncomment it. 
+      Other similar extension points exist, see Microsoft.Common.targets.
+      <Target Name="BeforeBuild">
+      </Target>
+      <Target Name="AfterBuild">
+      </Target>
+    -->
+</Project>

+ 34 - 0
Atlas/Atlas/Extensions.cs

@@ -0,0 +1,34 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework;
+using tainicom.Aether.Atlas;
+
+namespace Microsoft.Xna.Framework.Graphics
+{
+    public static class Extensions
+    {
+        public static void Draw(this SpriteBatch spriteBatch, Sprite sprite, Vector2 position, Color color)
+        {
+            spriteBatch.Draw(sprite.Texture, position, sprite.SourceRectangle, color);         
+        }
+        
+        public static void Draw(this SpriteBatch spriteBatch, Sprite sprite, Rectangle destinationRectangle, Color color)
+        {
+            spriteBatch.Draw(sprite.Texture, destinationRectangle, sprite.SourceRectangle, color);
+        }
+    }
+}

+ 33 - 0
Atlas/Atlas/Sprite.cs

@@ -0,0 +1,33 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace tainicom.Aether.Atlas
+{
+    public class Sprite
+    {
+        public readonly Texture2D Texture;
+        public readonly Rectangle SourceRectangle;
+
+        internal Sprite(Texture2D texture, Rectangle sourceRectangle)
+        {
+            this.Texture = texture;
+            this.SourceRectangle = sourceRectangle;
+        }
+    }
+}

+ 31 - 0
Atlas/Atlas/TextureAtlas.cs

@@ -0,0 +1,31 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System.Collections.Generic;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace tainicom.Aether.Atlas
+{
+    public class TextureAtlas
+    {
+        public Texture2D Texture {get; internal set;}
+        public readonly Dictionary<string, Sprite> Sprites;
+        internal TextureAtlas()
+        {
+            this.Sprites = new Dictionary<string, Sprite>();
+        }
+    }
+}

+ 70 - 0
Atlas/ContentReaders/TextureAtlasReader.cs

@@ -0,0 +1,70 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using tainicom.Aether.Atlas;
+
+namespace tainicom.Aether.Graphics.Content
+{
+    public class TextureAtlasReader : ContentTypeReader<TextureAtlas>
+    {
+        protected override TextureAtlas Read(ContentReader input, TextureAtlas existingInstance)
+        {
+            System.Diagnostics.Debugger.Launch();
+
+            IGraphicsDeviceService graphicsDeviceService = (IGraphicsDeviceService)input.ContentManager.ServiceProvider.GetService(typeof(IGraphicsDeviceService));
+            var device = graphicsDeviceService.GraphicsDevice;
+
+
+            TextureAtlas output = existingInstance ?? new TextureAtlas();
+
+            // read standard Texture2D
+            output.Texture = ReadTexture2D(input, output.Texture);
+
+            // read Sprites
+            var count = input.ReadInt32();
+            for (int i = 0; i < count; i++)
+            {
+                var name = input.ReadString();
+                var destinationRect = new Rectangle(input.ReadInt32(), input.ReadInt32(), input.ReadInt32(), input.ReadInt32());
+                output.Sprites[name] = new Sprite(output.Texture, destinationRect);
+            }
+
+            return output;
+        }
+
+        private Texture2D ReadTexture2D(ContentReader input, Texture2D existingInstance)
+        {
+            Texture2D output = null;
+            try
+            {
+                output = input.ReadRawObject<Texture2D>(existingInstance);
+            }
+            catch(NotSupportedException)
+            {
+                var assembly = typeof(Microsoft.Xna.Framework.Content.ContentTypeReader).Assembly;
+                var texture2DReaderType = assembly.GetType("Microsoft.Xna.Framework.Content.Texture2DReader");
+                var texture2DReader = (ContentTypeReader)Activator.CreateInstance(texture2DReaderType, true);
+                output = input.ReadRawObject<Texture2D>(texture2DReader, existingInstance);
+            }
+            
+            return output;
+        }
+    }
+}

+ 24 - 0
Atlas/Properties/AssemblyInfo.PORTABLE.cs

@@ -0,0 +1,24 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("Aether.Atlas")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("Aether.Atlas")]
+[assembly: AssemblyCopyright ("Copyright ©  Kastellanos Nikolaos 2016")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+

+ 41 - 0
Atlas/Properties/AssemblyInfo.cs

@@ -0,0 +1,41 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Aether.Atlas")]
+[assembly: AssemblyProduct("Aether.Atlas")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright ©  Kastellanos Nikolaos 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type. Only Windows
+// assemblies support COM.
+[assembly: ComVisible(false)]
+
+// On Windows, the following GUID is for the ID of the typelib if this
+// project is exposed to COM. On other platforms, it unique identifies the
+// title storage container when deploying this assembly to the device.
+[assembly: Guid("089a2665-02e6-4cf3-8571-30c768fe35f9")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+#if WP7_1
+// Enable NEON/SIMD
+[assembly: CodeGeneration(CodeGenerationFlags.EnableFPIntrinsicsUsingSIMD)]
+#endif

+ 4 - 0
Atlas/packages.config

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="MonoGame.Framework.Portable" version="3.2.99.1-Beta" targetFramework="portable-net45+win+wp80+MonoAndroid10+xamarinios10+MonoTouch10" />
+</packages>

+ 27 - 0
Content.Pipeline/AtlasImporter/Atlas/SourceContent.cs

@@ -0,0 +1,27 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+
+namespace tainicom.Aether.Content.Pipeline.Atlas
+{
+    public class SourceContent
+    {
+        public TextureContent Texture;
+        public int Width;
+        public int Height;
+    }
+}

+ 28 - 0
Content.Pipeline/AtlasImporter/Atlas/SpriteContent.cs

@@ -0,0 +1,28 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+namespace tainicom.Aether.Content.Pipeline
+{
+    public class SpriteContent
+    {
+        public TextureContent Texture;
+        public Rectangle DestinationRectangle;
+        public string Name;
+    }
+}

+ 29 - 0
Content.Pipeline/AtlasImporter/Atlas/TextureAtlasContent.cs

@@ -0,0 +1,29 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System.Collections.Generic;
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+
+namespace tainicom.Aether.Content.Pipeline.Atlas
+{
+    public class TextureAtlasContent : Texture2DContent
+    {
+        public int Width, Height;
+
+        public List<SourceContent> Textures = new List<SourceContent>();
+        public List<SpriteContent> Sprites = new List<SpriteContent>();
+    }
+}

+ 69 - 0
Content.Pipeline/AtlasImporter/AtlasImporter.WINDOWS.MG.csproj

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Content.Pipeline</RootNamespace>
+    <AssemblyName>Aether.Content.Pipeline.AtlasImporter</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\bin\Debug\Windows\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS MG</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\bin\Release\Windows\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="MonoGame.Framework, Version=3.1.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <SpecificVersion>False</SpecificVersion>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="MonoGame.Framework.Content.Pipeline, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\MonoGame.Framework.Content.Pipeline.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.Content.Pipeline.dll</HintPath>
+      <SpecificVersion>False</SpecificVersion>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.XML" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AtlasImporter.cs" />
+    <Compile Include="Atlas\SourceContent.cs" />
+    <Compile Include="Atlas\TextureAtlasContent.cs" />
+    <Compile Include="Atlas\SpriteContent.cs" />
+    <Compile Include="Processors\TextureAtlasProcessor.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Serialization\TextureAtlasWriter.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 63 - 0
Content.Pipeline/AtlasImporter/AtlasImporter.WINDOWS.XNA.csproj

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <ProjectGuid>{90E6017D-198B-4470-BF9B-8B8791C295CC}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Content.Pipeline</RootNamespace>
+    <AssemblyName>Aether.Content.Pipeline.AtlasImporter</AssemblyName>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <XnaPlatform>Windows</XnaPlatform>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\bin\Debug\Windows.XNA\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\bin\Release\Windows.XNA\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.TextureImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.XML" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AtlasImporter.cs" />
+    <Compile Include="Atlas\SourceContent.cs" />
+    <Compile Include="Atlas\TextureAtlasContent.cs" />
+    <Compile Include="Atlas\SpriteContent.cs" />
+    <Compile Include="Processors\TextureAtlasProcessor.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Serialization\TextureAtlasWriter.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.ContentPipelineExtensions.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+     Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 190 - 0
Content.Pipeline/AtlasImporter/AtlasImporter.cs

@@ -0,0 +1,190 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+using Microsoft.Xna.Framework.Graphics;
+using tainicom.Aether.Content.Pipeline.Atlas;
+
+namespace tainicom.Aether.Content.Pipeline
+{
+    [ContentImporter(".tmx", DisplayName = "Atlas Importer - Aether", DefaultProcessor = "AtlasProcessor")]
+    public class AtlasImporter : ContentImporter<TextureAtlasContent>
+    {
+        public override TextureAtlasContent Import(string filename, ContentImporterContext context)
+        {
+            TextureAtlasContent output;
+            
+            if (Path.GetExtension(filename) == ".tmx")
+                output = ImportTMX(filename, context);
+            else
+                throw new InvalidContentException("File type not supported");
+
+            RenderAtlas(output);
+            
+            return output;
+        }
+        
+        private static TextureAtlasContent ImportTMX(string filename, ContentImporterContext context)
+        {
+            TextureAtlasContent output = new TextureAtlasContent();
+            output.Identity = new ContentIdentity(filename);
+
+            XmlDocument xmlDoc = new XmlDocument();
+            xmlDoc.Load(filename);
+
+            var map = xmlDoc.DocumentElement;
+            var orientation = GetAttribute(map, "orientation");
+            if (orientation != "orthogonal")
+                throw new InvalidContentException("Invalid orientation. Only 'orthogonal' is supported for atlases.");
+            var renderorder = GetAttribute(map, "renderorder");
+            var mapColumns = GetAttributeAsInt(map, "width").Value;
+            var mapRows = GetAttributeAsInt(map, "height").Value;
+            var tileWidth = GetAttributeAsInt(map, "tilewidth").Value;
+            var tileHeight = GetAttributeAsInt(map, "tileheight").Value;
+            output.Width = mapColumns * tileWidth;
+            output.Height = mapRows * tileHeight;
+            
+            XmlNode tileset = map["tileset"];
+            if (tileset.Attributes["source"] != null)
+                throw new InvalidContentException("External Tileset is not supported.");
+            if (tileset["tileoffset"] != null)
+                throw new InvalidContentException("tileoffset is not supported.");
+            var firstgid = GetAttributeAsInt(tileset, "firstgid").Value;
+
+            Dictionary<int, SourceContent> images = new Dictionary<int, SourceContent>();
+            TextureImporter txImporter = new TextureImporter();
+            
+            foreach (XmlNode tileNode in tileset.ChildNodes)
+            {
+                if (tileNode.Name != "tile") continue;
+                var tileId = GetAttributeAsInt(tileNode, "id").Value;
+                XmlNode imageNode = tileNode["image"];
+                
+                var source = new SourceContent();
+
+                //var format = GetAttribute(imageNode, "format");
+                var imageSource = GetAttribute(imageNode, "source");
+                var fullImageSource = Path.Combine(Path.GetDirectoryName(filename), imageSource);
+                var textureContent = (Texture2DContent)txImporter.Import(fullImageSource, context);
+                textureContent.Name = Path.GetFileNameWithoutExtension(fullImageSource);
+
+                source.Texture = textureContent;
+
+                var width = GetAttributeAsInt(imageNode, "width");
+                var height = GetAttributeAsInt(imageNode, "height");
+
+                source.Width = width ?? textureContent.Mipmaps[0].Width;
+                source.Height = height ?? textureContent.Mipmaps[0].Height;
+
+                var transKeyColor = GetAttributeAsColor(imageNode, "trans");
+                if (transKeyColor != null)
+                    foreach (var mips in textureContent.Faces)
+                        foreach (var mip in mips)
+                            ((PixelBitmapContent<Color>)mip).ReplaceColor(transKeyColor.Value, Color.Transparent);
+
+                images.Add(firstgid + tileId, source);
+            }
+
+            output.Textures.AddRange(images.Values);
+            
+            XmlNode layerNode = map["layer"];
+            var layerColumns = Convert.ToInt32(map.Attributes["width"].Value, CultureInfo.InvariantCulture);
+            var layerRows = Convert.ToInt32(map.Attributes["height"].Value, CultureInfo.InvariantCulture);
+
+            XmlNode layerDataNode = layerNode["data"];
+            var encoding = layerDataNode.Attributes["encoding"].Value;
+            if (encoding!="csv")
+                throw new InvalidContentException("Invalid encoding. Only 'csv' is supported for data.");
+            var data = layerDataNode.InnerText;
+            var dataList = data.Split(',');
+            for (int i = 0; i < dataList.Length; i++)
+                dataList[i] = dataList[i].Trim();
+            
+            for(int y=0;y<layerRows;y++)
+            {
+                for(int x=0;x<layerColumns;x++ )
+                {
+                    var posX = x * tileWidth;
+                    var posY = y * tileHeight;
+                    
+                    var tilegId = Convert.ToInt32(dataList[y * layerColumns + x], CultureInfo.InvariantCulture);
+                    SourceContent image; 
+                    if (!images.TryGetValue(tilegId, out image))
+                        continue;
+
+                    if (renderorder == "right-down" || renderorder == "right-up")
+                        posX += (tileWidth - image.Width);
+                    if (renderorder == "right-down" || renderorder == "left-down")
+                        posY += (tileHeight - image.Height);
+
+                    var sprite = new SpriteContent();
+                    sprite.Name = image.Texture.Name;
+                    sprite.Texture = image.Texture;
+                    sprite.DestinationRectangle = new Rectangle(posX, posY, image.Width, image.Height);
+
+                    output.Sprites.Add(sprite);
+                }
+            }
+            
+            return output;
+        }
+
+        private static void RenderAtlas(TextureAtlasContent output)
+        {
+            var outputBmp = new PixelBitmapContent<Color>(output.Width, output.Height);
+            foreach (var sprite in output.Sprites)
+            {
+                var srcBmp = sprite.Texture.Faces[0][0];
+                var srcRect = new Rectangle(0, 0, srcBmp.Width, srcBmp.Height);
+                BitmapContent.Copy(srcBmp, srcRect, outputBmp, sprite.DestinationRectangle);
+            }
+            var mipmapChain = new MipmapChain(outputBmp);
+            output.Mipmaps = mipmapChain;
+        }
+        
+        private static string GetAttribute(XmlNode xmlNode, string attributeName)
+        {
+            var attribute = xmlNode.Attributes[attributeName];
+            if(attribute==null) return null;
+            return attribute.Value;
+        }
+        
+        private static int? GetAttributeAsInt(XmlNode xmlNode, string attributeName)
+        {
+            var attribute = xmlNode.Attributes[attributeName];
+            if (attribute == null) return null;
+            return Int32.Parse(attribute.Value, CultureInfo.InvariantCulture);
+        }
+
+        private static Color? GetAttributeAsColor(XmlNode xmlNode, string attributeName)
+        {
+            var attribute = xmlNode.Attributes[attributeName];
+            if (attribute == null) return null;
+            attribute.Value = attribute.Value.TrimStart(new char[] { '#' });
+            return new Color(
+                Int32.Parse(attribute.Value.Substring(0, 2), System.Globalization.NumberStyles.HexNumber),
+                Int32.Parse(attribute.Value.Substring(2, 2), System.Globalization.NumberStyles.HexNumber),
+                Int32.Parse(attribute.Value.Substring(4, 2), System.Globalization.NumberStyles.HexNumber));
+        }
+    }
+}

+ 131 - 0
Content.Pipeline/AtlasImporter/Processors/TextureAtlasProcessor.cs

@@ -0,0 +1,131 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using System.ComponentModel;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+using Microsoft.Xna.Framework.Content.Pipeline.Processors;
+using tainicom.Aether.Content.Pipeline.Atlas;
+
+namespace tainicom.Aether.Content.Pipeline
+{
+    [ContentProcessor(DisplayName = "AtlasProcessor - Aether")]
+    public class AtlasProcessor : TextureProcessor, IContentProcessor
+    {        
+        private bool _mipmapsPerSprite = true;
+
+#if WINDOWS
+        // override InputType
+        [Browsable(false)]
+#endif
+        Type IContentProcessor.InputType { get { return typeof(TextureAtlasContent); } }
+
+#if WINDOWS
+        // override OutputType
+        [Browsable(false)]
+#endif
+        Type IContentProcessor.OutputType { get { return typeof(TextureAtlasContent); } }
+        
+
+        [DefaultValue(true)]
+        public new bool MipmapsPerSprite
+        {
+            get { return _mipmapsPerSprite; }
+            set { _mipmapsPerSprite = value; }
+        }
+
+        public AtlasProcessor()
+        {
+        }
+        
+        object IContentProcessor.Process(object input, ContentProcessorContext context)
+        {
+            return Process((TextureAtlasContent)input, context);
+        }
+
+        public TextureAtlasContent Process(TextureAtlasContent input, ContentProcessorContext context)
+        {
+            if (MipmapsPerSprite && GenerateMipmaps)
+                foreach (var texture in input.Textures)
+                    texture.Texture.GenerateMipmaps(false);
+
+            var output = input;
+            
+            if (GenerateMipmaps)
+            {
+                if (MipmapsPerSprite)
+                {
+                    var maxSpriteWidth = 1;
+                    var maxSpriteHeight = 1;
+                    foreach (var sprite in input.Textures)
+                    {
+                        var face0 = sprite.Texture.Faces[0];
+                        maxSpriteWidth = Math.Max(maxSpriteWidth, face0[0].Width);
+                        maxSpriteHeight = Math.Max(maxSpriteHeight, face0[0].Height);
+                    }
+
+                    for (int mipLevel = 1; ; mipLevel++)
+                    {
+                        int mipLevel2 = (int)Math.Pow(2, mipLevel);
+                        Rectangle size = new Rectangle(0, 0, input.Width, input.Height);
+                        size.Width /= mipLevel2;
+                        size.Height /= mipLevel2;
+
+                        if ((maxSpriteWidth / mipLevel2) < 1 && (maxSpriteHeight / mipLevel2) < 1) break;
+
+                        var mipmapBmp = new PixelBitmapContent<Color>(size.Width, size.Height);
+                        foreach (var sprite in input.Sprites)
+                        {
+                            if (mipLevel >= sprite.Texture.Faces[0].Count) continue;
+                            var srcBmp = sprite.Texture.Faces[0][mipLevel];
+                            var srcRect = new Rectangle(0, 0, srcBmp.Width, srcBmp.Height);
+                            var destRect = sprite.DestinationRectangle;
+                            destRect.X = (int)Math.Ceiling((float)destRect.X / mipLevel2);
+                            destRect.Y = (int)Math.Ceiling((float)destRect.Y / mipLevel2);
+                            destRect.Width = (int)(destRect.Width / mipLevel2);
+                            destRect.Height = (int)(destRect.Height / mipLevel2);
+                            if (destRect.Width > 1 && destRect.Height > 1)
+                                BitmapContent.Copy(srcBmp, srcRect, mipmapBmp, destRect);
+                        }
+                        output.Mipmaps.Add(mipmapBmp);
+                    }
+
+                    var outputFace0 = output.Faces[0];
+                    while (outputFace0[outputFace0.Count - 1].Width > 1 || outputFace0[outputFace0.Count - 1].Height > 1)
+                    {
+                        var lastMipmap = outputFace0[outputFace0.Count - 1];
+                        var w = Math.Max(1, lastMipmap.Width/2);
+                        var h = Math.Max(1, lastMipmap.Height/2);
+                        var mipmapBmp = new PixelBitmapContent<Color>(w, h);
+                        //PixelBitmapContent<Color>.Copy(lastMipmap, mipmapBmp);
+                        output.Mipmaps.Add(mipmapBmp);
+                    }
+                }
+                else
+                {
+                    output.GenerateMipmaps(false);
+                }
+            }
+            
+            base.Process(output, context);
+            
+            return output;
+        }
+        
+    }
+}

+ 28 - 0
Content.Pipeline/AtlasImporter/Properties/AssemblyInfo.cs

@@ -0,0 +1,28 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Aether.Content.Pipeline.AtlasImporter")]
+[assembly: AssemblyProduct("AtlasImporter")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright © Kastellanos Nikolaos  2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 53 - 0
Content.Pipeline/AtlasImporter/Serialization/TextureAtlasWriter.cs

@@ -0,0 +1,53 @@
+#region License
+//   Copyright 2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
+using tainicom.Aether.Content.Pipeline.Atlas;
+using Microsoft.Xna.Framework.Graphics;
+using System;
+
+namespace tainicom.Aether.Content.Pipeline.Serialization
+{
+    [ContentTypeWriter]
+    class TextureAtlasWriter : ContentTypeWriter<TextureAtlasContent>
+    {
+        protected override void Write(ContentWriter output, TextureAtlasContent atlas)
+        {
+            output.WriteRawObject((Texture2DContent)atlas);
+            
+            // write Sprites
+            output.Write(atlas.Sprites.Count);
+            foreach(var sprite in atlas.Sprites)
+            {
+                output.Write(sprite.Name);
+                output.Write(sprite.DestinationRectangle.X);
+                output.Write(sprite.DestinationRectangle.Y);
+                output.Write(sprite.DestinationRectangle.Width);
+                output.Write(sprite.DestinationRectangle.Height);
+            }
+            
+            return;
+        }
+        
+        public override string GetRuntimeReader(TargetPlatform targetPlatform)
+        {
+            return "tainicom.Aether.Graphics.Content.TextureAtlasReader, Aether.Atlas";
+        }
+        
+    }
+}

+ 5 - 0
Content.Pipeline/AtlasImporter/packages.config

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="MonoGame.Framework.Content.Pipeline.Portable" version="3.2.99.1-Beta" targetFramework="net40" />
+  <package id="MonoGame.Framework.Portable" version="3.2.99.1-Beta" targetFramework="net40" />
+</packages>

+ 1 - 0
README.md

@@ -11,6 +11,7 @@ MonoGame Content Importers, Shaders, etc
 * 'RawModelProcessor' - Import 3D Models with a raw copy of Vertex/Index data for platforms that don't support GetData().
 * 'DynamicModel' - Base Processor to customize the build in Model. It allows to modify
 VertexBuffer & IndexBuffers, make them Dynamic and WriteOnly.
+* 'AtlasImporter' - Import sprite atlas. Supports .tmx files. Mipmaps are generated individually for each sprite, no color-leak.
 
 ## tainicom.Aether.Animation
 

+ 23 - 0
Samples.WINDOWS.MG.sln

@@ -23,6 +23,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.FXAA.WINDOWS
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.Deferred.WINDOWS.MG", "Shaders\Deferred\Aether.Shaders.Deferred.WINDOWS.MG.csproj", "{96105100-20DB-4187-9BCA-0A20AC9F1298}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtlasImporter.WINDOWS.MG", "Content.Pipeline\AtlasImporter\AtlasImporter.WINDOWS.MG.csproj", "{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Atlas.WINDOWS.MG", "Atlas\Aether.Atlas.WINDOWS.MG.csproj", "{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}"
+EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{584E505E-859A-4DA8-9235-EE6C61C03479}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Animation.WINDOWS.MG", "Samples\Animation\Samples.Animation.WINDOWS.MG.csproj", "{53EA1090-FEE4-4F16-96C2-57DD6B75FA75}"
@@ -31,6 +35,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.FXAA.WINDOWS.MG", "
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Deferred.WINDOWS.MG", "Samples\Deferred\Samples.Deferred.WINDOWS.MG.csproj", "{594B1001-B485-499A-A22B-42125763C2CF}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Atlas.WINDOWS.MG", "Samples\Atlas\Samples.Atlas.WINDOWS.MG.csproj", "{E605A7E1-EAE9-4EBF-941D-D88A6C1DC568}"
+	ProjectSection(ProjectDependencies) = postProject
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5} = {E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -69,6 +78,14 @@ Global
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}.Release|Any CPU.Build.0 = Release|Any CPU
 		{53EA1090-FEE4-4F16-96C2-57DD6B75FA75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{53EA1090-FEE4-4F16-96C2-57DD6B75FA75}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{53EA1090-FEE4-4F16-96C2-57DD6B75FA75}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -81,6 +98,10 @@ Global
 		{594B1001-B485-499A-A22B-42125763C2CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{594B1001-B485-499A-A22B-42125763C2CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{594B1001-B485-499A-A22B-42125763C2CF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E605A7E1-EAE9-4EBF-941D-D88A6C1DC568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E605A7E1-EAE9-4EBF-941D-D88A6C1DC568}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E605A7E1-EAE9-4EBF-941D-D88A6C1DC568}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E605A7E1-EAE9-4EBF-941D-D88A6C1DC568}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -92,8 +113,10 @@ Global
 		{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 		{FBBDE2BA-F9F3-4041-8584-2C912C235E26} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
 		{96105100-20DB-4187-9BCA-0A20AC9F1298} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
+		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 		{53EA1090-FEE4-4F16-96C2-57DD6B75FA75} = {584E505E-859A-4DA8-9235-EE6C61C03479}
 		{4F224B03-7499-4EE0-A072-7CD7FC266E2A} = {584E505E-859A-4DA8-9235-EE6C61C03479}
 		{594B1001-B485-499A-A22B-42125763C2CF} = {584E505E-859A-4DA8-9235-EE6C61C03479}
+		{E605A7E1-EAE9-4EBF-941D-D88A6C1DC568} = {584E505E-859A-4DA8-9235-EE6C61C03479}
 	EndGlobalSection
 EndGlobal

+ 25 - 0
Samples.WINDOWS.XNA.sln

@@ -17,6 +17,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.FXAA.WINDOWS
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.Deferred.WINDOWS.XNA", "Shaders\Deferred\Aether.Shaders.Deferred.WINDOWS.XNA.csproj", "{B82B862D-C728-4A10-8A56-65D688E022C8}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtlasImporter.WINDOWS.XNA", "Content.Pipeline\AtlasImporter\AtlasImporter.WINDOWS.XNA.csproj", "{90E6017D-198B-4470-BF9B-8B8791C295CC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Atlas.WINDOWS.XNA", "Atlas\Aether.Atlas.WINDOWS.XNA.csproj", "{644629BB-1A4E-4932-8E50-4F93BC938794}"
+EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{45FFB286-52CE-4EB7-8ACE-8B6FBD18D616}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Animation.WINDOWS.XNA", "Samples\Animation\Samples.Animation.WINDOWS.XNA.csproj", "{8C971E86-ACD6-45E6-A4C2-7E0C556152FE}"
@@ -31,6 +35,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Deferred.WINDOWS.XN
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.DeferredContent", "Samples\DeferredContent\Samples.DeferredContent.contentproj", "{FEFA33C9-E197-458C-845E-5FA513C38DF4}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Atlas.WINDOWS.XNA", "Samples\Atlas\Samples.Atlas.WINDOWS.XNA.csproj", "{0499C7DC-EBF2-4F77-871B-1EC613B379D9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.AtlasContent", "Samples\AtlasContent\Samples.AtlasContent.contentproj", "{4CA82D0E-2414-460C-9A70-2DA3C3AF96B6}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86
@@ -61,6 +69,14 @@ Global
 		{B82B862D-C728-4A10-8A56-65D688E022C8}.Debug|x86.Build.0 = Debug|x86
 		{B82B862D-C728-4A10-8A56-65D688E022C8}.Release|x86.ActiveCfg = Release|x86
 		{B82B862D-C728-4A10-8A56-65D688E022C8}.Release|x86.Build.0 = Release|x86
+		{90E6017D-198B-4470-BF9B-8B8791C295CC}.Debug|x86.ActiveCfg = Debug|x86
+		{90E6017D-198B-4470-BF9B-8B8791C295CC}.Debug|x86.Build.0 = Debug|x86
+		{90E6017D-198B-4470-BF9B-8B8791C295CC}.Release|x86.ActiveCfg = Release|x86
+		{90E6017D-198B-4470-BF9B-8B8791C295CC}.Release|x86.Build.0 = Release|x86
+		{644629BB-1A4E-4932-8E50-4F93BC938794}.Debug|x86.ActiveCfg = Debug|x86
+		{644629BB-1A4E-4932-8E50-4F93BC938794}.Debug|x86.Build.0 = Debug|x86
+		{644629BB-1A4E-4932-8E50-4F93BC938794}.Release|x86.ActiveCfg = Release|x86
+		{644629BB-1A4E-4932-8E50-4F93BC938794}.Release|x86.Build.0 = Release|x86
 		{8C971E86-ACD6-45E6-A4C2-7E0C556152FE}.Debug|x86.ActiveCfg = Debug|x86
 		{8C971E86-ACD6-45E6-A4C2-7E0C556152FE}.Debug|x86.Build.0 = Debug|x86
 		{8C971E86-ACD6-45E6-A4C2-7E0C556152FE}.Release|x86.ActiveCfg = Release|x86
@@ -79,6 +95,12 @@ Global
 		{6AD3101D-258F-4B90-ADEF-BCA6E89D8128}.Release|x86.Build.0 = Release|x86
 		{FEFA33C9-E197-458C-845E-5FA513C38DF4}.Debug|x86.ActiveCfg = Debug|x86
 		{FEFA33C9-E197-458C-845E-5FA513C38DF4}.Release|x86.ActiveCfg = Release|x86
+		{0499C7DC-EBF2-4F77-871B-1EC613B379D9}.Debug|x86.ActiveCfg = Debug|x86
+		{0499C7DC-EBF2-4F77-871B-1EC613B379D9}.Debug|x86.Build.0 = Debug|x86
+		{0499C7DC-EBF2-4F77-871B-1EC613B379D9}.Release|x86.ActiveCfg = Release|x86
+		{0499C7DC-EBF2-4F77-871B-1EC613B379D9}.Release|x86.Build.0 = Release|x86
+		{4CA82D0E-2414-460C-9A70-2DA3C3AF96B6}.Debug|x86.ActiveCfg = Debug|x86
+		{4CA82D0E-2414-460C-9A70-2DA3C3AF96B6}.Release|x86.ActiveCfg = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -86,6 +108,7 @@ Global
 	GlobalSection(NestedProjects) = preSolution
 		{565ACF47-7E36-435E-8727-2AFB39E61134} = {F6B6E505-6037-49E4-9060-8B29A7B99BC1}
 		{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E} = {F6B6E505-6037-49E4-9060-8B29A7B99BC1}
+		{90E6017D-198B-4470-BF9B-8B8791C295CC} = {F6B6E505-6037-49E4-9060-8B29A7B99BC1}
 		{89E0198E-7298-411A-B5C1-61F2754A3F80} = {EFC7A27C-C20B-4BE7-8B3A-2B109991D704}
 		{B82B862D-C728-4A10-8A56-65D688E022C8} = {EFC7A27C-C20B-4BE7-8B3A-2B109991D704}
 		{8C971E86-ACD6-45E6-A4C2-7E0C556152FE} = {45FFB286-52CE-4EB7-8ACE-8B6FBD18D616}
@@ -94,5 +117,7 @@ Global
 		{578BBDBD-874B-4738-B956-93AAADD67D60} = {45FFB286-52CE-4EB7-8ACE-8B6FBD18D616}
 		{6AD3101D-258F-4B90-ADEF-BCA6E89D8128} = {45FFB286-52CE-4EB7-8ACE-8B6FBD18D616}
 		{FEFA33C9-E197-458C-845E-5FA513C38DF4} = {45FFB286-52CE-4EB7-8ACE-8B6FBD18D616}
+		{0499C7DC-EBF2-4F77-871B-1EC613B379D9} = {45FFB286-52CE-4EB7-8ACE-8B6FBD18D616}
+		{4CA82D0E-2414-460C-9A70-2DA3C3AF96B6} = {45FFB286-52CE-4EB7-8ACE-8B6FBD18D616}
 	EndGlobalSection
 EndGlobal

二進制
Samples/Atlas/Game.ico


+ 146 - 0
Samples/Atlas/Game1.cs

@@ -0,0 +1,146 @@
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using tainicom.Aether.Atlas;
+
+namespace Samples.Atlas
+{
+    public class Game1 : Microsoft.Xna.Framework.Game
+    {
+        GraphicsDeviceManager graphics;
+        SpriteBatch spriteBatch;
+        SpriteFont font;
+
+        KeyboardState previousKeyboardState;
+
+        int mipLevel = 4;
+        bool showAtlas = false;
+        bool useGenerateBitmap = true;
+        bool useMipmapPerSprite = true;
+        Rectangle atlasSize = new Rectangle(0, 0, 1024, 512);
+        RenderTarget2D rt;
+
+
+        TextureAtlas atlasMipmapPerSprite;
+        TextureAtlas atlasMipmap;
+        TextureAtlas atlasNoMipmap;
+        
+        public Game1()
+        {
+            graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+
+            graphics.PreferredBackBufferWidth = atlasSize.Width;
+            graphics.PreferredBackBufferHeight = atlasSize.Height;
+        }
+
+        protected override void LoadContent()
+        {            
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            font = Content.Load<SpriteFont>("font");
+
+            rt = new RenderTarget2D(GraphicsDevice, atlasSize.Width, atlasSize.Height);
+
+            atlasMipmapPerSprite = Content.Load<TextureAtlas>("atlasMipmapPerSprite");
+            atlasMipmap = Content.Load<TextureAtlas>("atlasMipmap");
+            atlasNoMipmap = Content.Load<TextureAtlas>("atlasNoMipmap");
+        }
+        
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Update(GameTime gameTime)
+        {
+            KeyboardState keyState = Keyboard.GetState();
+            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
+
+            if (keyState.IsKeyDown(Keys.Escape) || gamePadState.Buttons.Back == ButtonState.Pressed)
+                Exit();
+
+            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
+                useMipmapPerSprite = !useMipmapPerSprite;
+            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
+                useGenerateBitmap = !useGenerateBitmap;
+            if (keyState.IsKeyDown(Keys.F3) && !previousKeyboardState.IsKeyDown(Keys.F3))
+                showAtlas = !showAtlas;
+            if (keyState.IsKeyDown(Keys.OemPlus) && !previousKeyboardState.IsKeyDown(Keys.OemPlus) && mipLevel < 10)
+                mipLevel++;
+            if (keyState.IsKeyDown(Keys.Add) && !previousKeyboardState.IsKeyDown(Keys.Add) && mipLevel < 10)
+                mipLevel++;
+            if (keyState.IsKeyDown(Keys.OemMinus) && !previousKeyboardState.IsKeyDown(Keys.OemMinus) && mipLevel > 0)
+                mipLevel--;
+            if (keyState.IsKeyDown(Keys.Subtract) && !previousKeyboardState.IsKeyDown(Keys.Subtract) && mipLevel > 0)
+                mipLevel--;
+            
+            previousKeyboardState = keyState;
+            base.Update(gameTime);
+        }
+        
+        protected override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.BlendState = BlendState.Opaque;
+            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
+
+            int mipLevel2 = (int)Math.Pow(2, mipLevel);
+            var mipSize = atlasSize;
+            mipSize.Width /= mipLevel2;
+            mipSize.Height /= mipLevel2;
+            
+            GraphicsDevice.SetRenderTarget(rt);
+            GraphicsDevice.Clear(Color.Black);
+
+            var currentAtlas = (useGenerateBitmap) ? (useMipmapPerSprite ? atlasMipmapPerSprite : atlasMipmap) : atlasNoMipmap;
+
+            spriteBatch.Begin();
+
+            if (showAtlas)
+            {
+                spriteBatch.Draw(currentAtlas.Texture, mipSize, Color.White);
+            }
+            else
+            {
+                var sprite18 = currentAtlas.Sprites["18"];
+                var destRect = new Rectangle(128, 128, sprite18.SourceRectangle.Width, sprite18.SourceRectangle.Height);
+                destRect.X /= mipLevel2;
+                destRect.Y /= mipLevel2;
+                destRect.Width = Math.Max(1, destRect.Width / mipLevel2);
+                destRect.Height = Math.Max(1, destRect.Height / mipLevel2);
+                spriteBatch.Draw(sprite18, destRect, Color.White);
+
+                var spriteMushroom_2 = currentAtlas.Sprites["Mushroom_2"];
+                destRect = new Rectangle(256 + 128, 128, spriteMushroom_2.SourceRectangle.Width, spriteMushroom_2.SourceRectangle.Height);
+                destRect.X /= mipLevel2;
+                destRect.Y /= mipLevel2;
+                destRect.Width = Math.Max(1, destRect.Width / mipLevel2);
+                destRect.Height = Math.Max(1, destRect.Height / mipLevel2);
+                spriteBatch.Draw(spriteMushroom_2, destRect, Color.White);
+                
+                var sprite10 = currentAtlas.Sprites["10"];
+                destRect = new Rectangle(512, 128, sprite10.SourceRectangle.Width, sprite10.SourceRectangle.Height);
+                destRect.X /= mipLevel2;
+                destRect.Y /= mipLevel2;
+                destRect.Width = Math.Max(1, destRect.Width / mipLevel2);
+                destRect.Height = Math.Max(1, destRect.Height / mipLevel2);
+                spriteBatch.Draw(sprite10, destRect, Color.White);
+
+            }
+            spriteBatch.End();
+
+
+            GraphicsDevice.SetRenderTarget(null);
+            GraphicsDevice.Clear(Color.CornflowerBlue);
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null);
+            spriteBatch.Draw(rt, atlasSize, mipSize, Color.White);
+            spriteBatch.End();
+
+            spriteBatch.Begin();
+            spriteBatch.DrawString(font, String.Format("[F1] MipmapPerSprite - ({0})", useMipmapPerSprite ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F2] GenerateMipmap - ({0})", useGenerateBitmap ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F3] {0}", showAtlas? "Show Sprites" : "Show Atlas"), new Vector2(20, 60), Color.White);
+            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(20, 80), Color.White);
+            spriteBatch.End();
+
+            base.Draw(gameTime);
+        }
+        
+    }
+}

二進制
Samples/Atlas/GameThumbnail.png


二進制
Samples/Atlas/Icon.ico


+ 19 - 0
Samples/Atlas/Program.cs

@@ -0,0 +1,19 @@
+using System;
+
+namespace Samples.Atlas
+{
+#if WINDOWS || XBOX || LINUX
+    public static class Program
+    {
+        [STAThread]
+        static void Main(string[] args)
+        {
+            using (Game1 game = new Game1())
+            {
+                game.Run();
+            }
+        }
+    }
+#endif
+}
+

+ 34 - 0
Samples/Atlas/Properties/AssemblyInfo.cs

@@ -0,0 +1,34 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Samples.Atlas")]
+[assembly: AssemblyProduct("Samples.Atlas")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright © Kastellanos Nikolaos 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type. Only Windows
+// assemblies support COM.
+[assembly: ComVisible(false)]
+
+// On Windows, the following GUID is for the ID of the typelib if this
+// project is exposed to COM. On other platforms, it unique identifies the
+// title storage container when deploying this assembly to the device.
+[assembly: Guid("c6cd9013-14d8-476f-95ba-60cc07d3639f")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]

+ 81 - 0
Samples/Atlas/Samples.Atlas.WINDOWS.MG.csproj

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E605A7E1-EAE9-4EBF-941D-D88A6C1DC568}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Samples.Atlas</RootNamespace>
+    <AssemblyName>Samples.Atlas</AssemblyName>
+    <FileAlignment>512</FileAlignment>
+    <MonoGamePlatform>Windows</MonoGamePlatform>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationIcon>Icon.ico</ApplicationIcon>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationManifest>app.manifest</ApplicationManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS MG</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Game1.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework">
+      <HintPath>$(MonoGameInstallDirectory)\MonoGame\v3.0\Assemblies\Windows\MonoGame.Framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Icon.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="..\AtlasContent\Samples.AtlasContent.mgcb">
+      <Link>Content\Content.mgcb</Link>
+    </MonoGameContentReference>
+    <None Include="app.config" />
+    <None Include="app.manifest" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Atlas\Aether.Atlas.WINDOWS.MG.csproj">
+      <Project>{c7522b5e-b255-4fb6-a17a-9e6d217aebd2}</Project>
+      <Name>Aether.Atlas.WINDOWS.MG</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 129 - 0
Samples/Atlas/Samples.Atlas.WINDOWS.XNA.csproj

@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{0499C7DC-EBF2-4F77-871B-1EC613B379D9}</ProjectGuid>
+    <ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Samples.Atlas</RootNamespace>
+    <AssemblyName>Samples.Atlas</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <XnaPlatform>Windows</XnaPlatform>
+    <XnaProfile>Reach</XnaProfile>
+    <XnaCrossPlatformGroupID>F6823739-266B-4AF4-A702-70DFEF0584CC</XnaCrossPlatformGroupID>
+    <XnaOutputType>Game</XnaOutputType>
+    <ApplicationIcon>Game.ico</ApplicationIcon>
+    <Thumbnail>GameThumbnail.png</Thumbnail>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\Windows\XNA\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaCompressContent>false</XnaCompressContent>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\Windows\XNA\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaCompressContent>true</XnaCompressContent>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Game1.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Game.ico" />
+    <Content Include="GameThumbnail.png">
+      <XnaPlatformSpecific>true</XnaPlatformSpecific>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Atlas\Aether.Atlas.WINDOWS.XNA.csproj">
+      <Project>{644629BB-1A4E-4932-8E50-4F93BC938794}</Project>
+      <Name>Aether.Atlas.WINDOWS.XNA</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\AtlasContent\Samples.AtlasContent.contentproj">
+      <Project>{4CA82D0E-2414-460C-9A70-2DA3C3AF96B6}</Project>
+      <Name>Samples.AtlasContent %28Content%29</Name>
+      <XnaReferenceType>Content</XnaReferenceType>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Xna.Framework.4.0">
+      <Visible>False</Visible>
+      <ProductName>Microsoft XNA Framework Redistributable 4.0</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
+  <!--
+      To modify your build process, add your task inside one of the targets below and uncomment it. 
+      Other similar extension points exist, see Microsoft.Common.targets.
+      <Target Name="BeforeBuild">
+      </Target>
+      <Target Name="AfterBuild">
+      </Target>
+    -->
+</Project>

+ 3 - 0
Samples/Atlas/app.config

@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>

+ 42 - 0
Samples/Atlas/app.manifest

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+  <assemblyIdentity version="1.0.0.0" name="Graphics"/>
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+    <security>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+
+  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+    <application>
+      <!-- A list of the Windows versions that this application has been tested on and is
+           is designed to work with. Uncomment the appropriate elements and Windows will 
+           automatically selected the most compatible environment. -->
+
+      <!-- Windows Vista -->
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
+
+      <!-- Windows 7 -->
+      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
+
+      <!-- Windows 8 -->
+      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
+
+      <!-- Windows 8.1 -->
+      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
+
+      <!-- Windows 10 -->
+      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
+
+    </application>
+  </compatibility>
+
+  <application xmlns="urn:schemas-microsoft-com:asm.v3">
+    <windowsSettings>
+      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
+    </windowsSettings>
+  </application>
+
+</assembly>

+ 100 - 0
Samples/AtlasContent/AtlasNoMipmap.tmx

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.0" orientation="orthogonal" renderorder="right-down" width="8" height="4" tilewidth="128" tileheight="128" nextobjectid="1">
+ <tileset firstgid="1" name="1" tilewidth="133" tileheight="128" tilecount="29" columns="0">
+  <tile id="0">
+   <image width="128" height="128" source="Tiles/1.png"/>
+  </tile>
+  <tile id="1">
+   <image width="128" height="128" source="Tiles/2.png"/>
+  </tile>
+  <tile id="2">
+   <image width="128" height="128" source="Tiles/3.png"/>
+  </tile>
+  <tile id="3">
+   <image width="128" height="128" source="Tiles/4.png"/>
+  </tile>
+  <tile id="4">
+   <image width="128" height="128" source="Tiles/5.png"/>
+  </tile>
+  <tile id="5">
+   <image width="128" height="128" source="Tiles/6.png"/>
+  </tile>
+  <tile id="6">
+   <image width="128" height="128" source="Tiles/7.png"/>
+  </tile>
+  <tile id="7">
+   <image width="128" height="128" source="Tiles/8.png"/>
+  </tile>
+  <tile id="8">
+   <image width="128" height="128" source="Tiles/9.png"/>
+  </tile>
+  <tile id="9">
+   <image width="128" height="128" source="Tiles/10.png"/>
+  </tile>
+  <tile id="10">
+   <image width="128" height="128" source="Tiles/11.png"/>
+  </tile>
+  <tile id="11">
+   <image width="128" height="128" source="Tiles/12.png"/>
+  </tile>
+  <tile id="12">
+   <image width="128" height="93" source="Tiles/13.png"/>
+  </tile>
+  <tile id="13">
+   <image width="128" height="93" source="Tiles/14.png"/>
+  </tile>
+  <tile id="14">
+   <image width="128" height="93" source="Tiles/15.png"/>
+  </tile>
+  <tile id="15">
+   <image width="128" height="128" source="Tiles/16.png"/>
+  </tile>
+  <tile id="16">
+   <image width="128" height="99" source="Tiles/17.png"/>
+  </tile>
+  <tile id="17">
+   <image width="128" height="128" source="Tiles/18.png"/>
+  </tile>
+  <tile id="18">
+   <image width="133" height="65" source="Object/Bush_1.png"/>
+  </tile>
+  <tile id="19">
+   <image width="133" height="65" source="Object/Bush_2.png"/>
+  </tile>
+  <tile id="20">
+   <image width="73" height="47" source="Object/Bush_3.png"/>
+  </tile>
+  <tile id="21">
+   <image width="73" height="46" source="Object/Bush_4.png"/>
+  </tile>
+  <tile id="22">
+   <image width="77" height="77" source="Object/Crate.png"/>
+  </tile>
+  <tile id="23">
+   <image width="49" height="41" source="Object/Mushroom_1.png"/>
+  </tile>
+  <tile id="24">
+   <image width="50" height="41" source="Object/Mushroom_2.png"/>
+  </tile>
+  <tile id="25">
+   <image width="63" height="65" source="Object/Sign_1.png"/>
+  </tile>
+  <tile id="26">
+   <image width="62" height="64" source="Object/Sign_2.png"/>
+  </tile>
+  <tile id="27">
+   <image width="90" height="54" source="Object/Stone.png"/>
+  </tile>
+  <tile id="28">
+   <image width="116" height="44" source="Object/Tree_1.png"/>
+  </tile>
+ </tileset>
+ <layer name="Tile Layer 1" width="8" height="4">
+  <data encoding="csv">
+13,14,15,0,0,0,0,0,
+1,2,3,26,27,29,23,17,
+4,5,6,21,22,24,25,28,
+12,9,16,10,11,7,18,8
+</data>
+ </layer>
+</map>

二進制
Samples/AtlasContent/Object/Bush_1.png


二進制
Samples/AtlasContent/Object/Bush_2.png


二進制
Samples/AtlasContent/Object/Bush_3.png


二進制
Samples/AtlasContent/Object/Bush_4.png


二進制
Samples/AtlasContent/Object/Crate.png


二進制
Samples/AtlasContent/Object/Mushroom_1.png


二進制
Samples/AtlasContent/Object/Mushroom_2.png


二進制
Samples/AtlasContent/Object/Sign_1.png


二進制
Samples/AtlasContent/Object/Sign_2.png


二進制
Samples/AtlasContent/Object/Stone.png


二進制
Samples/AtlasContent/Object/Tree_1.png


二進制
Samples/AtlasContent/Object/Tree_2.png


二進制
Samples/AtlasContent/Object/Tree_3.png


+ 89 - 0
Samples/AtlasContent/Samples.AtlasContent.contentproj

@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{4CA82D0E-2414-460C-9A70-2DA3C3AF96B6}</ProjectGuid>
+    <ProjectTypeGuids>{96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <OutputPath>bin\$(Platform)\$(Configuration)</OutputPath>
+    <ContentRootDirectory>Content</ContentRootDirectory>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup>
+    <RootNamespace>Samples.AtlasContent</RootNamespace>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.EffectImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.FBXImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.TextureImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.XImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.AudioImporters, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.VideoImporters, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="font.spritefont">
+      <Name>font</Name>
+      <Importer>FontDescriptionImporter</Importer>
+      <Processor>FontDescriptionProcessor</Processor>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Content.Pipeline\AtlasImporter\AtlasImporter.WINDOWS.XNA.csproj">
+      <Project>{90E6017D-198B-4470-BF9B-8B8791C295CC}</Project>
+      <Name>AtlasImporter.WINDOWS.XNA</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="atlasMipmap.tmx">
+      <Name>atlasMipmap</Name>
+      <Processor>AtlasProcessor</Processor>
+      <Importer>AtlasImporter</Importer>
+      <ProcessorParameters_ColorKeyEnabled>False</ProcessorParameters_ColorKeyEnabled>
+      <ProcessorParameters_GenerateMipmaps>True</ProcessorParameters_GenerateMipmaps>
+      <ProcessorParameters_MipmapsPerSprite>False</ProcessorParameters_MipmapsPerSprite>
+    </Compile>
+    <Compile Include="atlasMipmapPerSprite.tmx">
+      <Name>atlasMipmapPerSprite</Name>
+      <Importer>AtlasImporter</Importer>
+      <Processor>AtlasProcessor</Processor>
+      <ProcessorParameters_ColorKeyEnabled>False</ProcessorParameters_ColorKeyEnabled>
+      <ProcessorParameters_GenerateMipmaps>True</ProcessorParameters_GenerateMipmaps>
+    </Compile>
+    <Compile Include="AtlasNoMipmap.tmx">
+      <Name>AtlasNoMipmap</Name>
+      <Importer>AtlasImporter</Importer>
+      <Processor>AtlasProcessor</Processor>
+      <ProcessorParameters_ColorKeyEnabled>False</ProcessorParameters_ColorKeyEnabled>
+      <ProcessorParameters_MipmapsPerSprite>False</ProcessorParameters_MipmapsPerSprite>
+    </Compile>
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\$(XnaFrameworkVersion)\Microsoft.Xna.GameStudio.ContentPipeline.targets" />
+  <!--  To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 65 - 0
Samples/AtlasContent/Samples.AtlasContent.mgcb

@@ -0,0 +1,65 @@
+
+#----------------------------- Global Properties ----------------------------#
+
+/outputDir:bin/$(Platform)
+/intermediateDir:obj/$(Platform)
+/platform:Windows
+/config:
+/profile:Reach
+/compress:False
+
+#-------------------------------- References --------------------------------#
+
+/reference:..\..\bin\Debug\Windows\Aether.Content.Pipeline.AtlasImporter.dll
+
+#---------------------------------- Content ---------------------------------#
+
+#begin font.spritefont
+/importer:FontDescriptionImporter
+/processor:FontDescriptionProcessor
+/processorParam:PremultiplyAlpha=True
+/processorParam:TextureFormat=Compressed
+/build:font.spritefont
+
+#begin atlasMipmap.tmx
+/importer:AtlasImporter
+/processor:AtlasProcessor
+/processorParam:Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.InputType=tainicom.Aether.Content.Pipeline.Atlas.AtlasContent
+/processorParam:MipmapsPerSprite=False
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=True
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:atlasMipmap.tmx
+
+#begin atlasMipmapPerSprite.tmx
+/importer:AtlasImporter
+/processor:AtlasProcessor
+/processorParam:Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.InputType=tainicom.Aether.Content.Pipeline.Atlas.AtlasContent
+/processorParam:MipmapsPerSprite=True
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=True
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:atlasMipmapPerSprite.tmx
+
+#begin atlasNoMipmap.tmx
+/importer:AtlasImporter
+/processor:AtlasProcessor
+/processorParam:Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.InputType=tainicom.Aether.Content.Pipeline.Atlas.AtlasContent
+/processorParam:MipmapsPerSprite=False
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:atlasNoMipmap.tmx
+

二進制
Samples/AtlasContent/Tiles/1.png


二進制
Samples/AtlasContent/Tiles/10.png


二進制
Samples/AtlasContent/Tiles/11.png


二進制
Samples/AtlasContent/Tiles/12.png


二進制
Samples/AtlasContent/Tiles/13.png


二進制
Samples/AtlasContent/Tiles/14.png


二進制
Samples/AtlasContent/Tiles/15.png


二進制
Samples/AtlasContent/Tiles/16.png


二進制
Samples/AtlasContent/Tiles/17.png


二進制
Samples/AtlasContent/Tiles/18.png


二進制
Samples/AtlasContent/Tiles/2.png


二進制
Samples/AtlasContent/Tiles/3.png


二進制
Samples/AtlasContent/Tiles/4.png


二進制
Samples/AtlasContent/Tiles/5.png


二進制
Samples/AtlasContent/Tiles/6.png


二進制
Samples/AtlasContent/Tiles/7.png


二進制
Samples/AtlasContent/Tiles/8.png


二進制
Samples/AtlasContent/Tiles/9.png


+ 100 - 0
Samples/AtlasContent/atlasMipmap.tmx

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.0" orientation="orthogonal" renderorder="right-down" width="8" height="4" tilewidth="128" tileheight="128" nextobjectid="1">
+ <tileset firstgid="1" name="1" tilewidth="133" tileheight="128" tilecount="29" columns="0">
+  <tile id="0">
+   <image width="128" height="128" source="Tiles/1.png"/>
+  </tile>
+  <tile id="1">
+   <image width="128" height="128" source="Tiles/2.png"/>
+  </tile>
+  <tile id="2">
+   <image width="128" height="128" source="Tiles/3.png"/>
+  </tile>
+  <tile id="3">
+   <image width="128" height="128" source="Tiles/4.png"/>
+  </tile>
+  <tile id="4">
+   <image width="128" height="128" source="Tiles/5.png"/>
+  </tile>
+  <tile id="5">
+   <image width="128" height="128" source="Tiles/6.png"/>
+  </tile>
+  <tile id="6">
+   <image width="128" height="128" source="Tiles/7.png"/>
+  </tile>
+  <tile id="7">
+   <image width="128" height="128" source="Tiles/8.png"/>
+  </tile>
+  <tile id="8">
+   <image width="128" height="128" source="Tiles/9.png"/>
+  </tile>
+  <tile id="9">
+   <image width="128" height="128" source="Tiles/10.png"/>
+  </tile>
+  <tile id="10">
+   <image width="128" height="128" source="Tiles/11.png"/>
+  </tile>
+  <tile id="11">
+   <image width="128" height="128" source="Tiles/12.png"/>
+  </tile>
+  <tile id="12">
+   <image width="128" height="93" source="Tiles/13.png"/>
+  </tile>
+  <tile id="13">
+   <image width="128" height="93" source="Tiles/14.png"/>
+  </tile>
+  <tile id="14">
+   <image width="128" height="93" source="Tiles/15.png"/>
+  </tile>
+  <tile id="15">
+   <image width="128" height="128" source="Tiles/16.png"/>
+  </tile>
+  <tile id="16">
+   <image width="128" height="99" source="Tiles/17.png"/>
+  </tile>
+  <tile id="17">
+   <image width="128" height="128" source="Tiles/18.png"/>
+  </tile>
+  <tile id="18">
+   <image width="133" height="65" source="Object/Bush_1.png"/>
+  </tile>
+  <tile id="19">
+   <image width="133" height="65" source="Object/Bush_2.png"/>
+  </tile>
+  <tile id="20">
+   <image width="73" height="47" source="Object/Bush_3.png"/>
+  </tile>
+  <tile id="21">
+   <image width="73" height="46" source="Object/Bush_4.png"/>
+  </tile>
+  <tile id="22">
+   <image width="77" height="77" source="Object/Crate.png"/>
+  </tile>
+  <tile id="23">
+   <image width="49" height="41" source="Object/Mushroom_1.png"/>
+  </tile>
+  <tile id="24">
+   <image width="50" height="41" source="Object/Mushroom_2.png"/>
+  </tile>
+  <tile id="25">
+   <image width="63" height="65" source="Object/Sign_1.png"/>
+  </tile>
+  <tile id="26">
+   <image width="62" height="64" source="Object/Sign_2.png"/>
+  </tile>
+  <tile id="27">
+   <image width="90" height="54" source="Object/Stone.png"/>
+  </tile>
+  <tile id="28">
+   <image width="116" height="44" source="Object/Tree_1.png"/>
+  </tile>
+ </tileset>
+ <layer name="Tile Layer 1" width="8" height="4">
+  <data encoding="csv">
+13,14,15,0,0,0,0,0,
+1,2,3,26,27,29,23,17,
+4,5,6,21,22,24,25,28,
+12,9,16,10,11,7,18,8
+</data>
+ </layer>
+</map>

+ 100 - 0
Samples/AtlasContent/atlasMipmapPerSprite.tmx

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.0" orientation="orthogonal" renderorder="right-down" width="8" height="4" tilewidth="128" tileheight="128" nextobjectid="1">
+ <tileset firstgid="1" name="1" tilewidth="133" tileheight="128" tilecount="29" columns="0">
+  <tile id="0">
+   <image width="128" height="128" source="Tiles/1.png"/>
+  </tile>
+  <tile id="1">
+   <image width="128" height="128" source="Tiles/2.png"/>
+  </tile>
+  <tile id="2">
+   <image width="128" height="128" source="Tiles/3.png"/>
+  </tile>
+  <tile id="3">
+   <image width="128" height="128" source="Tiles/4.png"/>
+  </tile>
+  <tile id="4">
+   <image width="128" height="128" source="Tiles/5.png"/>
+  </tile>
+  <tile id="5">
+   <image width="128" height="128" source="Tiles/6.png"/>
+  </tile>
+  <tile id="6">
+   <image width="128" height="128" source="Tiles/7.png"/>
+  </tile>
+  <tile id="7">
+   <image width="128" height="128" source="Tiles/8.png"/>
+  </tile>
+  <tile id="8">
+   <image width="128" height="128" source="Tiles/9.png"/>
+  </tile>
+  <tile id="9">
+   <image width="128" height="128" source="Tiles/10.png"/>
+  </tile>
+  <tile id="10">
+   <image width="128" height="128" source="Tiles/11.png"/>
+  </tile>
+  <tile id="11">
+   <image width="128" height="128" source="Tiles/12.png"/>
+  </tile>
+  <tile id="12">
+   <image width="128" height="93" source="Tiles/13.png"/>
+  </tile>
+  <tile id="13">
+   <image width="128" height="93" source="Tiles/14.png"/>
+  </tile>
+  <tile id="14">
+   <image width="128" height="93" source="Tiles/15.png"/>
+  </tile>
+  <tile id="15">
+   <image width="128" height="128" source="Tiles/16.png"/>
+  </tile>
+  <tile id="16">
+   <image width="128" height="99" source="Tiles/17.png"/>
+  </tile>
+  <tile id="17">
+   <image width="128" height="128" source="Tiles/18.png"/>
+  </tile>
+  <tile id="18">
+   <image width="133" height="65" source="Object/Bush_1.png"/>
+  </tile>
+  <tile id="19">
+   <image width="133" height="65" source="Object/Bush_2.png"/>
+  </tile>
+  <tile id="20">
+   <image width="73" height="47" source="Object/Bush_3.png"/>
+  </tile>
+  <tile id="21">
+   <image width="73" height="46" source="Object/Bush_4.png"/>
+  </tile>
+  <tile id="22">
+   <image width="77" height="77" source="Object/Crate.png"/>
+  </tile>
+  <tile id="23">
+   <image width="49" height="41" source="Object/Mushroom_1.png"/>
+  </tile>
+  <tile id="24">
+   <image width="50" height="41" source="Object/Mushroom_2.png"/>
+  </tile>
+  <tile id="25">
+   <image width="63" height="65" source="Object/Sign_1.png"/>
+  </tile>
+  <tile id="26">
+   <image width="62" height="64" source="Object/Sign_2.png"/>
+  </tile>
+  <tile id="27">
+   <image width="90" height="54" source="Object/Stone.png"/>
+  </tile>
+  <tile id="28">
+   <image width="116" height="44" source="Object/Tree_1.png"/>
+  </tile>
+ </tileset>
+ <layer name="Tile Layer 1" width="8" height="4">
+  <data encoding="csv">
+13,14,15,0,0,0,0,0,
+1,2,3,26,27,29,23,17,
+4,5,6,21,22,24,25,28,
+12,9,16,10,11,7,18,8
+</data>
+ </layer>
+</map>

+ 60 - 0
Samples/AtlasContent/font.spritefont

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This file contains an xml description of a font, and will be read by the XNA
+Framework Content Pipeline. Follow the comments to customize the appearance
+of the font in your game, and to change the characters which are available to draw
+with.
+-->
+<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
+  <Asset Type="Graphics:FontDescription">
+
+    <!--
+    Modify this string to change the font that will be imported.
+    -->
+    <FontName>Segoe UI Mono</FontName>
+
+    <!--
+    Size is a float value, measured in points. Modify this value to change
+    the size of the font.
+    -->
+    <Size>14</Size>
+
+    <!--
+    Spacing is a float value, measured in pixels. Modify this value to change
+    the amount of spacing in between characters.
+    -->
+    <Spacing>0</Spacing>
+
+    <!--
+    UseKerning controls the layout of the font. If this value is true, kerning information
+    will be used when placing characters.
+    -->
+    <UseKerning>true</UseKerning>
+
+    <!--
+    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
+    and "Bold, Italic", and are case sensitive.
+    -->
+    <Style>Regular</Style>
+
+    <!--
+    If you uncomment this line, the default character will be substituted if you draw
+    or measure text that contains characters which were not included in the font.
+    -->
+    <!-- <DefaultCharacter>*</DefaultCharacter> -->
+
+    <!--
+    CharacterRegions control what letters are available in the font. Every
+    character from Start to End will be built and made available for drawing. The
+    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
+    character set. The characters are ordered according to the Unicode standard.
+    See the documentation for more information.
+    -->
+    <CharacterRegions>
+      <CharacterRegion>
+        <Start>&#32;</Start>
+        <End>&#126;</End>
+      </CharacterRegion>
+    </CharacterRegions>
+  </Asset>
+</XnaContent>

+ 1 - 0
Samples/AtlasContent/free-platformer-game-tileset.txt

@@ -0,0 +1 @@
+http://www.gameart2d.com/free-platformer-game-tileset.html

二進制
bin/Release/Portable/Aether.Atlas.dll


二進制
bin/Release/Windows.XNA/Aether.Atlas.dll


二進制
bin/Release/Windows.XNA/Aether.Content.Pipeline.AtlasImporter.dll


二進制
bin/Release/Windows/Aether.Atlas.dll


二進制
bin/Release/Windows/Aether.Content.Pipeline.AtlasImporter.dll


+ 2 - 0
packages/repositories.config

@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <repositories>
   <repository path="..\Animation\packages.config" />
+  <repository path="..\Atlas\packages.config" />
   <repository path="..\Content.Pipeline\AnimationImporter\packages.config" />
+  <repository path="..\Content.Pipeline\AtlasImporter\packages.config" />
   <repository path="..\Content.Pipeline\DDSImporter\packages.config" />
   <repository path="..\Content.Pipeline\GraphicsImporters\packages.config" />
   <repository path="..\Content.Pipeline\RawModelProcessor\packages.config" />