2021-04-04 18:31:51 +02:00
|
|
|
|
using System;
|
2023-05-15 16:13:18 +02:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2021-04-04 18:31:51 +02:00
|
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
|
using MLEM.Data;
|
|
|
|
|
using MLEM.Textures;
|
|
|
|
|
using NUnit.Framework;
|
|
|
|
|
|
2022-12-13 13:11:36 +01:00
|
|
|
|
namespace Tests;
|
2021-04-04 18:31:51 +02:00
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
public class TexturePackerTests {
|
2021-04-04 18:31:51 +02:00
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
private Texture2D testTexture;
|
|
|
|
|
private Texture2D disposedTestTexture;
|
|
|
|
|
private TestGame game;
|
2021-04-04 18:31:51 +02:00
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
[SetUp]
|
|
|
|
|
public void SetUp() {
|
|
|
|
|
this.game = TestGame.Create();
|
2023-05-15 16:13:18 +02:00
|
|
|
|
this.testTexture = new Texture2D(this.game.GraphicsDevice, 2048, 2048);
|
2022-10-27 10:22:25 +02:00
|
|
|
|
this.disposedTestTexture = new Texture2D(this.game.GraphicsDevice, 16, 16);
|
|
|
|
|
}
|
2021-11-01 16:00:13 +01:00
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
[TearDown]
|
|
|
|
|
public void TearDown() {
|
|
|
|
|
this.game?.Dispose();
|
|
|
|
|
this.testTexture?.Dispose();
|
|
|
|
|
this.disposedTestTexture?.Dispose();
|
|
|
|
|
}
|
2021-04-04 18:31:51 +02:00
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
[Test]
|
|
|
|
|
public void TestPacking() {
|
|
|
|
|
using var packer = new RuntimeTexturePacker();
|
|
|
|
|
for (var i = 0; i < 5; i++) {
|
|
|
|
|
var width = 16 * (i + 1);
|
|
|
|
|
packer.Add(new TextureRegion(this.testTexture, 0, 0, width, 64), r => {
|
|
|
|
|
Assert.AreEqual(r.Width, width);
|
|
|
|
|
Assert.AreEqual(r.Height, 64);
|
2021-04-04 18:31:51 +02:00
|
|
|
|
});
|
|
|
|
|
}
|
2022-10-27 10:22:25 +02:00
|
|
|
|
packer.Pack(this.game.GraphicsDevice);
|
|
|
|
|
Assert.AreEqual(packer.PackedTexture.Width, 16 + 32 + 48 + 64 + 80);
|
|
|
|
|
Assert.AreEqual(packer.PackedTexture.Height, 64);
|
|
|
|
|
}
|
2021-04-04 18:31:51 +02:00
|
|
|
|
|
2023-05-15 16:13:18 +02:00
|
|
|
|
[Test]
|
|
|
|
|
public void TestOverlap() {
|
|
|
|
|
var packed = new List<TextureRegion>();
|
2023-05-19 19:25:11 +02:00
|
|
|
|
using (var packer = new RuntimeTexturePacker(8192)) {
|
2023-05-15 16:13:18 +02:00
|
|
|
|
for (var i = 1; i <= 1000; i++)
|
|
|
|
|
packer.Add(new TextureRegion(this.testTexture, 0, 0, i % 239, i % 673), packed.Add);
|
|
|
|
|
packer.Pack(this.game.GraphicsDevice);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var r1 in packed) {
|
|
|
|
|
foreach (var r2 in packed) {
|
|
|
|
|
if (r1 == r2)
|
|
|
|
|
continue;
|
|
|
|
|
Assert.False(r1.Area.Intersects(r2.Area));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
[Test]
|
|
|
|
|
public void TestDisposal() {
|
|
|
|
|
using var packer = new RuntimeTexturePacker(128, disposeTextures: true);
|
|
|
|
|
packer.Add(new TextureRegion(this.disposedTestTexture), TexturePackerTests.StubResult);
|
|
|
|
|
packer.Add(new TextureRegion(this.disposedTestTexture, 0, 0, 8, 8), TexturePackerTests.StubResult);
|
|
|
|
|
packer.Pack(this.game.GraphicsDevice);
|
|
|
|
|
Assert.True(this.disposedTestTexture.IsDisposed);
|
|
|
|
|
Assert.False(packer.PackedTexture.IsDisposed);
|
|
|
|
|
}
|
2022-10-20 23:59:42 +02:00
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
[Test]
|
|
|
|
|
public void TestBounds() {
|
|
|
|
|
// test forced max width
|
|
|
|
|
using var packer = new RuntimeTexturePacker(128);
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() => {
|
|
|
|
|
packer.Add(new TextureRegion(this.testTexture, 0, 0, 256, 128), TexturePackerTests.StubResult);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// test auto-expanding width
|
|
|
|
|
using var packer2 = new RuntimeTexturePacker(128, true);
|
|
|
|
|
Assert.DoesNotThrow(() => {
|
|
|
|
|
packer2.Add(new TextureRegion(this.testTexture, 0, 0, 256, 128), TexturePackerTests.StubResult);
|
|
|
|
|
});
|
|
|
|
|
packer2.Pack(this.game.GraphicsDevice);
|
|
|
|
|
|
|
|
|
|
// test power of two forcing
|
|
|
|
|
using var packer3 = new RuntimeTexturePacker(128, forcePowerOfTwo: true);
|
|
|
|
|
packer3.Add(new TextureRegion(this.testTexture, 0, 0, 37, 170), TexturePackerTests.StubResult);
|
|
|
|
|
packer3.Pack(this.game.GraphicsDevice);
|
|
|
|
|
Assert.AreEqual(64, packer3.PackedTexture.Width);
|
|
|
|
|
Assert.AreEqual(256, packer3.PackedTexture.Height);
|
|
|
|
|
|
|
|
|
|
// test square forcing
|
|
|
|
|
using var packer4 = new RuntimeTexturePacker(128, forceSquare: true);
|
|
|
|
|
packer4.Add(new TextureRegion(this.testTexture, 0, 0, 37, 170), TexturePackerTests.StubResult);
|
|
|
|
|
packer4.Pack(this.game.GraphicsDevice);
|
|
|
|
|
Assert.AreEqual(170, packer4.PackedTexture.Width);
|
|
|
|
|
Assert.AreEqual(170, packer4.PackedTexture.Height);
|
|
|
|
|
}
|
2022-10-20 23:59:42 +02:00
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
[Test]
|
|
|
|
|
public void TestPackMultipleTimes() {
|
|
|
|
|
using var packer = new RuntimeTexturePacker(1024);
|
2022-10-20 23:59:42 +02:00
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
// pack the first time
|
|
|
|
|
var results = 0;
|
|
|
|
|
for (var i = 0; i < 10; i++)
|
2022-10-20 23:59:42 +02:00
|
|
|
|
packer.Add(new TextureRegion(this.testTexture, 0, 0, 64, 64), _ => results++);
|
2022-10-27 10:22:25 +02:00
|
|
|
|
packer.Pack(this.game.GraphicsDevice);
|
|
|
|
|
Assert.AreEqual(10, results);
|
|
|
|
|
|
|
|
|
|
// pack without resizing
|
|
|
|
|
packer.Add(new TextureRegion(this.testTexture, 0, 0, 0, 0), _ => results++);
|
|
|
|
|
packer.Pack(this.game.GraphicsDevice);
|
|
|
|
|
Assert.AreEqual(11, results);
|
|
|
|
|
|
|
|
|
|
// pack and force a resize
|
|
|
|
|
packer.Add(new TextureRegion(this.testTexture, 0, 0, 64, 64), _ => results++);
|
|
|
|
|
packer.Pack(this.game.GraphicsDevice);
|
|
|
|
|
// all callbacks are called again, so we add 11 again, as well as the callback we just added
|
|
|
|
|
Assert.AreEqual(2 * 11 + 1, results);
|
|
|
|
|
}
|
2022-10-20 23:59:42 +02:00
|
|
|
|
|
2023-05-15 16:13:18 +02:00
|
|
|
|
[Test]
|
|
|
|
|
public void TestPackTimes() {
|
2023-05-15 18:36:23 +02:00
|
|
|
|
for (var total = 1; total <= 10001; total += 1000) {
|
2023-05-15 16:13:18 +02:00
|
|
|
|
using var sameSizePacker = new RuntimeTexturePacker();
|
|
|
|
|
using var diffSizePacker = new RuntimeTexturePacker();
|
|
|
|
|
for (var i = 0; i < total; i++) {
|
|
|
|
|
sameSizePacker.Add(new TextureRegion(this.testTexture, 0, 0, 10, 10), TexturePackerTests.StubResult);
|
|
|
|
|
diffSizePacker.Add(new TextureRegion(this.testTexture, 0, 0, 10 + i % 129, 10 * (i % 5 + 1)), TexturePackerTests.StubResult);
|
|
|
|
|
}
|
|
|
|
|
sameSizePacker.Pack(this.game.GraphicsDevice);
|
|
|
|
|
diffSizePacker.Pack(this.game.GraphicsDevice);
|
|
|
|
|
|
|
|
|
|
TestContext.WriteLine($"""
|
|
|
|
|
{total} regions,
|
|
|
|
|
same-size {sameSizePacker.LastCalculationTime.TotalMilliseconds} calc, {sameSizePacker.LastPackTime.TotalMilliseconds} pack, {sameSizePacker.LastTotalTime.TotalMilliseconds} total,
|
|
|
|
|
diff-size {diffSizePacker.LastCalculationTime.TotalMilliseconds} calc, {diffSizePacker.LastPackTime.TotalMilliseconds} pack, {diffSizePacker.LastTotalTime.TotalMilliseconds} total
|
|
|
|
|
""");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-27 10:22:25 +02:00
|
|
|
|
private static void StubResult(TextureRegion region) {}
|
2021-04-04 18:31:51 +02:00
|
|
|
|
|
2022-06-17 18:23:47 +02:00
|
|
|
|
}
|