diff --git a/LandblockExtraction/AtlasMaker/AtlasBuilder.cs b/LandblockExtraction/AtlasMaker/AtlasBuilder.cs index 1d1aa2f..1a77432 100644 --- a/LandblockExtraction/AtlasMaker/AtlasBuilder.cs +++ b/LandblockExtraction/AtlasMaker/AtlasBuilder.cs @@ -11,7 +11,6 @@ using System.Threading.Tasks; namespace LandblockExtraction.AtlasMaker; public class AtlasBuilder { private readonly int TEXTURESIZE = 64; - private TexturesImage texturesImage; private List textures; @@ -20,7 +19,30 @@ public class AtlasBuilder { texturesImage = new TexturesImage(portalEngine); } - public AddTexture(DataId vdesc) { + public bool AddTexture(DataId matId) { + var img = texturesImage.GetImage(matId); + if(img == null) return false; + textures.Add(img); + return true; + } + + public void GenerateAtlas() { + int count = (int)Math.Ceiling(Math.Sqrt(textures.Count)); + int atlasSize = (int)TEXTURESIZE * count; + + using (MagickImage atlas = new MagickImage(new MagickColor("#FFFFFF"), atlasSize, atlasSize)) { + int index = 0; + + foreach (var kvp in textures) { + int x = (index % count) * (int)TEXTURESIZE; + int y = (index / count) * (int)TEXTURESIZE; + atlas.Draw(new Drawables().Composite(x, y, kvp)); + index++; + if (index >= count * count) break; + } + + atlas.Write("atlas.jpg"); + } } } diff --git a/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs b/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs index d9b8e4d..a44e28a 100644 --- a/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs +++ b/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs @@ -9,11 +9,25 @@ using System.Threading.Tasks; namespace LandblockExtraction.AtlasMaker; public class TerrainAtlasManager { private PortalEngine portalEngine; + private AtlasBuilder atlasBuilder; public Dictionary textureCoord; - + public TerrainAtlasManager(PortalEngine portalEngine) { this.portalEngine = portalEngine; textureCoord = new Dictionary(); + atlasBuilder = new AtlasBuilder(portalEngine); + } + public void ExtractTexture() { + foreach(var terrain in portalEngine.cTerrainDesc.terrains) { + foreach(var surface in portalEngine.cSurfaceDesc.surfaces) { + if(surface.surfIndex == terrain.surfaceInfo) { + atlasBuilder.AddTexture(surface.terrainMaterials.First().baseMaterials.First().materialDid); + } + } + } + } + public void GenerateAtlas() { + atlasBuilder.GenerateAtlas(); } } diff --git a/LandblockExtraction/AtlasMaker/TexturesImage.cs b/LandblockExtraction/AtlasMaker/TexturesImage.cs index c15cfcf..b7e4ea3 100644 --- a/LandblockExtraction/AtlasMaker/TexturesImage.cs +++ b/LandblockExtraction/AtlasMaker/TexturesImage.cs @@ -1,4 +1,7 @@ -using LandblockExtraction.DatEngine; +using AC2RE.Definitions; +using ImageMagick; +using LandblockExtraction.DatEngine; +using LandblockExtraction.Tools; using System; using System.Collections.Generic; using System.Linq; @@ -8,10 +11,47 @@ using System.Threading.Tasks; namespace LandblockExtraction.AtlasMaker; public class TexturesImage { private PortalEngine portalEngine; - private TextureEngine textureEngine; + //private TextureEngine textureEngine; public TexturesImage(PortalEngine portalEngine) { this.portalEngine = portalEngine; - this.textureEngine = new(); + //this.textureEngine = new(); } + + public MagickImage? GetImage(DataId matId) { + if(!portalEngine.datReader.contains(matId)) return null; + using(var data = portalEngine.datReader.getFileReader(matId)) { + var materialLayer = new RenderMaterial(data); + if(materialLayer == null) return null; + + return ImageInMaterial(materialLayer); + } + } + + private MagickImage? ImageInMaterial(RenderMaterial materialLayer) { + var vdescId = materialLayer.layers.First().stages.First().textureID; + if(!portalEngine.datReader.contains(new(vdescId))) return null; + using(var data = portalEngine.datReader.getFileReader(new(vdescId))) { + var texture = new RenderTexture(data); + if(texture == null) return null; + return TextureInRender(texture); + } + + } + + private MagickImage? TextureInRender(RenderTexture texture) { + foreach(var img in texture.levelSurfaceDids) { + if(!portalEngine.datReader.contains(img)) continue; + using(var data = portalEngine.datReader.getFileReader(img)) { + var image = new RenderSurface(data); + if(image.width != 64) continue; + var dataImg = DDSHeader.Generate(image); + using(MagickImage realImg = new MagickImage(dataImg)) { + return realImg; + } + } + } + return null; + } + } diff --git a/Map3DRendering/MapRender.cs b/Map3DRendering/MapRender.cs index cea8f65..6975f9a 100644 --- a/Map3DRendering/MapRender.cs +++ b/Map3DRendering/MapRender.cs @@ -1,4 +1,5 @@ -using LandblockExtraction.DatEngine; +using LandblockExtraction.AtlasMaker; +using LandblockExtraction.DatEngine; using LandblockExtraction.LandBlockExtractor; using Map3DRendering.Common; using OpenTK.Graphics.OpenGL4; @@ -9,7 +10,7 @@ namespace Map3DRendering { private PortalEngine portalEngine; private CellEngine cellEngine; private LandBlockExtrator landblockExtraction; - + private TerrainAtlasManager terrainAtlasManager; private readonly int NumberLandBlocks = 255; private readonly int BlockSize = 17; private readonly int allBlocks = 255 * 17 * 255 * 17; @@ -30,6 +31,11 @@ namespace Map3DRendering { public MapRender() { portalEngine = new PortalEngine(); cellEngine = new CellEngine(); + + terrainAtlasManager = new(portalEngine); + terrainAtlasManager.ExtractTexture(); + terrainAtlasManager.GenerateAtlas(); + landblockExtraction = new(portalEngine, cellEngine); _vertexArrayObject = new int[0xFE, 0xFE];