Add MrGameEng.Atlases: texture atlas builder, runtime loader and CLI tool
CI / build-test (push) Failing after 1m13s
CI / build-test (push) Failing after 1m13s
AtlasBuilder packs a directory tree of loose images into atlas pages plus JSON metadata (deterministic shelf packing, incremental rebuilds, orphan cleanup); TextureAtlas loads them back handing out Texture2DRegions, so sprites from one page batch into a single draw call. The asset handle generator maps .atlas files to TextureAtlas and skips page images. Demonstrated in the sample (Assets/Atlases + 'atlas' console command), wrapped as tools/MrGameEng.AtlasTool for build scripts. Documented dependency exception: Atlases depends on Graphics and Assets.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "Textures",
|
||||
"pageSize": 2048,
|
||||
"padding": 2,
|
||||
"pages": [
|
||||
{
|
||||
"file": "Textures.atlas.0.png",
|
||||
"width": 256,
|
||||
"height": 128
|
||||
}
|
||||
],
|
||||
"regions": [
|
||||
{
|
||||
"key": "player",
|
||||
"page": 0,
|
||||
"x": 68,
|
||||
"y": 2,
|
||||
"w": 64,
|
||||
"h": 32
|
||||
},
|
||||
{
|
||||
"key": "shapes",
|
||||
"page": 0,
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"w": 64,
|
||||
"h": 64
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@@ -11,6 +11,7 @@
|
||||
<ProjectReference Include="..\..\src\MrGameEng.Input\MrGameEng.Input.csproj" />
|
||||
<ProjectReference Include="..\..\src\MrGameEng.Audio\MrGameEng.Audio.csproj" />
|
||||
<ProjectReference Include="..\..\src\MrGameEng.Assets\MrGameEng.Assets.csproj" />
|
||||
<ProjectReference Include="..\..\src\MrGameEng.Atlases\MrGameEng.Atlases.csproj" />
|
||||
<ProjectReference Include="..\..\src\MrGameEng.UI\MrGameEng.UI.csproj" />
|
||||
<ProjectReference Include="..\..\src\MrGameEng.DevConsole\MrGameEng.DevConsole.csproj" />
|
||||
<ProjectReference Include="..\..\src\MrGameEng.Assets.Generator\MrGameEng.Assets.Generator.csproj"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Friflo.Engine.ECS;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MrGameEng.Assets;
|
||||
using MrGameEng.Atlases;
|
||||
using MrGameEng.Audio;
|
||||
using MrGameEng.Core;
|
||||
using MrGameEng.DevConsole;
|
||||
@@ -36,6 +37,11 @@ public sealed class MainScene : Scene
|
||||
var shapesTexture = assets.Load(GameAssets.Textures.Shapes);
|
||||
var beep = assets.Load(GameAssets.Sounds.Beep);
|
||||
|
||||
// Текстурный атлас: Assets/Atlases собран утилитой MrGameEng.AtlasTool из Assets/Textures
|
||||
// (см. README). Регионы адресуются исходным путём без расширения и батчатся в один draw call.
|
||||
Context.UseTextureAtlases();
|
||||
var atlas = assets.Load(GameAssets.Atlases.Textures);
|
||||
|
||||
var shapeRegions = new[]
|
||||
{
|
||||
new Texture2DRegion(shapesTexture, new Rectangle(0, 0, 32, 32)),
|
||||
@@ -87,6 +93,15 @@ public sealed class MainScene : Scene
|
||||
playerSprite,
|
||||
new SpriteAnimator(blink));
|
||||
|
||||
// Пара спрайтов из атласа рядом со стартом игрока — вся пара рисуется одним draw call.
|
||||
var atlasShowcase = new[] { ("player", -80f), ("shapes", 80f) };
|
||||
foreach (var (key, offsetX) in atlasShowcase)
|
||||
{
|
||||
var sprite = new Sprite(atlas.GetRegion(key), SampleLayers.Actors);
|
||||
sprite.CenterOrigin();
|
||||
Store.CreateEntity(new Transform2D(new Vector2(offsetX, -120f)), sprite);
|
||||
}
|
||||
|
||||
var camera = Store.CreateEntity(new Camera(Vector2.Zero, zoom: 1f, bounds: WorldBounds));
|
||||
|
||||
// HUD: золотой квадрат в углу на screen-space слое — не двигается с камерой.
|
||||
@@ -131,6 +146,14 @@ public sealed class MainScene : Scene
|
||||
}
|
||||
});
|
||||
console.Register("beep", "play the beep sound", (_, _) => audio.Play(beep));
|
||||
console.Register("atlas", "list texture atlas regions", (c, _) =>
|
||||
{
|
||||
c.WriteLine($"atlas '{atlas.Name}': {atlas.Pages.Count} page(s), {atlas.Regions.Count} region(s)");
|
||||
foreach (var (key, region) in atlas.Regions.OrderBy(r => r.Key, StringComparer.Ordinal))
|
||||
{
|
||||
c.WriteLine($" {key}: {region.Bounds.Width}x{region.Bounds.Height} at ({region.Bounds.X},{region.Bounds.Y})");
|
||||
}
|
||||
});
|
||||
|
||||
UpdateSystems.Add(new PlayerControlSystem(player, actions, audio, beep, console));
|
||||
UpdateSystems.Add(new BounceSystem(WorldBounds));
|
||||
|
||||
Reference in New Issue
Block a user