From b9a2b87fe9f5b3ca1389ff932c27d3f8c19facdc Mon Sep 17 00:00:00 2001 From: Troispoils Date: Tue, 27 Feb 2024 17:04:09 +0100 Subject: [PATCH] Update for AtlasBuilder ok Need to improuve duplicate vertex for mapping texture. --- .../AtlasMaker/AtlasBuilder.cs | 25 ++++---- .../AtlasMaker/TerrainAtlasManager.cs | 20 +++++- .../AtlasMaker/TexturesImage.cs | 4 +- .../LandBlockExtractor/LandBlockExtrator.cs | 62 +++++++++++++++++++ .../Utilities/BlockStruct.cs | 35 ++++++++++- .../Utilities/VerticesStruct.cs | 8 ++- Map3DRendering/Common/Shader.cs | 4 ++ Map3DRendering/MapRender.cs | 16 ++--- Map3DRendering/Shaders/shader.frag | 8 ++- Map3DRendering/Shaders/shader.vert | 3 + Map3DRendering/Window.cs | 8 ++- 11 files changed, 160 insertions(+), 33 deletions(-) diff --git a/LandblockExtraction/AtlasMaker/AtlasBuilder.cs b/LandblockExtraction/AtlasMaker/AtlasBuilder.cs index 1a77432..d22998d 100644 --- a/LandblockExtraction/AtlasMaker/AtlasBuilder.cs +++ b/LandblockExtraction/AtlasMaker/AtlasBuilder.cs @@ -28,21 +28,22 @@ public class AtlasBuilder { public void GenerateAtlas() { int count = (int)Math.Ceiling(Math.Sqrt(textures.Count)); - int atlasSize = (int)TEXTURESIZE * count; + int atlasSize = (int)TEXTURESIZE * count; - using (MagickImage atlas = new MagickImage(new MagickColor("#FFFFFF"), atlasSize, atlasSize)) { - int index = 0; + 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"); + foreach (var kvp in textures) { + int x = (index % count) * (int)TEXTURESIZE; + int y = (index / count) * (int)TEXTURESIZE; + atlas.Composite(kvp, x, y); + + index++; + if (index >= count * count) break; } + atlas.Write("atlas.jpg"); + } + } } diff --git a/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs b/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs index a44e28a..6390681 100644 --- a/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs +++ b/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs @@ -1,8 +1,10 @@ -using LandblockExtraction.DatEngine; +using AC2RE.Definitions; +using LandblockExtraction.DatEngine; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -11,11 +13,11 @@ public class TerrainAtlasManager { private PortalEngine portalEngine; private AtlasBuilder atlasBuilder; - public Dictionary textureCoord; + public Dictionary textureCoord; public TerrainAtlasManager(PortalEngine portalEngine) { this.portalEngine = portalEngine; - textureCoord = new Dictionary(); + textureCoord = new Dictionary(); atlasBuilder = new AtlasBuilder(portalEngine); } public void ExtractTexture() { @@ -25,9 +27,21 @@ public class TerrainAtlasManager { atlasBuilder.AddTexture(surface.terrainMaterials.First().baseMaterials.First().materialDid); } } + textureCoord.Add((int)terrain.terrainIndex, Vector2.Zero); } } public void GenerateAtlas() { atlasBuilder.GenerateAtlas(); } + public void GenerateUV() { + int count = (int)Math.Ceiling(Math.Sqrt(textureCoord.Count)); + int atlasSize = (int)64 * count; + int index = 0; + foreach(var terrain in textureCoord) { + int x = (index % count) * (int)64; + int y = (index / count) * (int)64; + textureCoord[index] = new Vector2(x, y); + index++; + } + } } diff --git a/LandblockExtraction/AtlasMaker/TexturesImage.cs b/LandblockExtraction/AtlasMaker/TexturesImage.cs index b7e4ea3..7e16d37 100644 --- a/LandblockExtraction/AtlasMaker/TexturesImage.cs +++ b/LandblockExtraction/AtlasMaker/TexturesImage.cs @@ -40,6 +40,7 @@ public class TexturesImage { } private MagickImage? TextureInRender(RenderTexture texture) { + MagickImage magickImage; foreach(var img in texture.levelSurfaceDids) { if(!portalEngine.datReader.contains(img)) continue; using(var data = portalEngine.datReader.getFileReader(img)) { @@ -47,8 +48,9 @@ public class TexturesImage { if(image.width != 64) continue; var dataImg = DDSHeader.Generate(image); using(MagickImage realImg = new MagickImage(dataImg)) { - return realImg; + magickImage = new(realImg); } + return magickImage; } } return null; diff --git a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs index 02996eb..7295516 100644 --- a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs +++ b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs @@ -1,12 +1,15 @@ using AC2RE.Definitions; +using LandblockExtraction.AtlasMaker; using LandblockExtraction.DatEngine; using LandblockExtraction.Tools; +using System.Dynamic; using System.Numerics; namespace LandblockExtraction.LandBlockExtractor { public class LandBlockExtrator { private PortalEngine portalEngine; private CellEngine cellEngine; + private TerrainAtlasManager terrainAtlasManager; private readonly int NumberLandBlocks = 255; private readonly int BlockSize = 17; @@ -15,6 +18,11 @@ namespace LandblockExtraction.LandBlockExtractor { public LandBlockExtrator(PortalEngine portalEngine, CellEngine cellEngine) { this.portalEngine = portalEngine; this.cellEngine = cellEngine; + + terrainAtlasManager = new TerrainAtlasManager(portalEngine); + terrainAtlasManager.ExtractTexture(); + terrainAtlasManager.GenerateAtlas(); + terrainAtlasManager.GenerateUV(); } public BlockStruct? GetBlock(int landX, int landY) { @@ -34,11 +42,65 @@ namespace LandblockExtraction.LandBlockExtractor { blockStruct.verticesStruct.color[indice] = GenerateVertexColor(blockData.cellInfos[indice]); blockStruct.verticesStruct.farcolor[indice] = GenerateVertexFarColor(blockData.cellInfos[indice]); blockStruct.GenerateIndices(); + //blockStruct.GenerateUVByIndices(); + GenerateVertexTextureCoord(blockData, blockStruct); } } return blockStruct; } + + private void GenerateVertexTextureCoord(CLandBlockData blockData, BlockStruct blockStruct) { + List vertices = new List(); // Liste pour stocker les positions des sommets dupliqués + List colors = new List(); + List farcolors = new List(); + List uvs = new List(); // Liste pour stocker les coordonnées UV + List indices = new List(); // Liste pour stocker les nouveaux indices + + for (int y = 0; y < blockStruct.indices.Length; y = y + 6) { + // Créez 4 sommets + vertices.Add(blockStruct.verticesStruct.position[blockStruct.indices[y]]); + vertices.Add(blockStruct.verticesStruct.position[blockStruct.indices[y + 1]]); + vertices.Add(blockStruct.verticesStruct.position[blockStruct.indices[y + 2]]); + vertices.Add(blockStruct.verticesStruct.position[blockStruct.indices[y + 5]]); + + // Créez 4 color + colors.Add(blockStruct.verticesStruct.color[blockStruct.indices[y]]); + colors.Add(blockStruct.verticesStruct.color[blockStruct.indices[y + 1]]); + colors.Add(blockStruct.verticesStruct.color[blockStruct.indices[y + 2]]); + colors.Add(blockStruct.verticesStruct.color[blockStruct.indices[y + 5]]); + + // Créez 4 farcolor + farcolors.Add(blockStruct.verticesStruct.farcolor[blockStruct.indices[y]]); + farcolors.Add(blockStruct.verticesStruct.farcolor[blockStruct.indices[y + 1]]); + farcolors.Add(blockStruct.verticesStruct.farcolor[blockStruct.indices[y + 2]]); + farcolors.Add(blockStruct.verticesStruct.farcolor[blockStruct.indices[y + 5]]); + + // Assignez les coordonnées UV à chaque sommet + uvs.Add(new Vector2(0, 0)); // Coin inférieur gauche + uvs.Add(new Vector2(1, 0)); // Coin inférieur droit + uvs.Add(new Vector2(0, 1)); // Coin supérieur gauche + uvs.Add(new Vector2(1, 1)); // Coin supérieur droit + + // Créez les indices pour les deux triangles du quad + int baseIndex = (y / 6) * 4; // Calculez l'index de base pour ce quad + indices.Add(baseIndex); + indices.Add(baseIndex + 1); + indices.Add(baseIndex + 2); + + indices.Add(baseIndex + 2); + indices.Add(baseIndex + 1); + indices.Add(baseIndex + 3); + } + + // Mettez à jour le BlockStruct avec les nouvelles listes de sommets, UVs, et indices + Console.WriteLine(indices.Count); + blockStruct.verticesStruct.position = vertices.ToArray(); + blockStruct.verticesStruct.color = colors.ToArray(); + blockStruct.verticesStruct.farcolor = farcolors.ToArray(); + blockStruct.verticesStruct.texturecoord = uvs.ToArray(); + blockStruct.indices = indices.ToArray(); + } private Vector3 GenerateVertexPosition(int landx, int landy, int x, int y, byte height) { int tmpx = (landx * BlockSize + y) * cellSize; int tmpy = (BlockSize * NumberLandBlocks * cellSize) - ((landy * BlockSize + x) * cellSize) - 1; diff --git a/LandblockExtraction/LandBlockExtractor/Utilities/BlockStruct.cs b/LandblockExtraction/LandBlockExtractor/Utilities/BlockStruct.cs index 062a40d..a7e9a0b 100644 --- a/LandblockExtraction/LandBlockExtractor/Utilities/BlockStruct.cs +++ b/LandblockExtraction/LandBlockExtractor/Utilities/BlockStruct.cs @@ -1,4 +1,8 @@ -namespace LandblockExtraction.LandBlockExtractor { + +using System; +using System.Numerics; + +namespace LandblockExtraction.LandBlockExtractor { public class BlockStruct { public readonly static int BlockSize = 17; @@ -26,5 +30,34 @@ } } } + + public void GenerateUVByIndices() { + // Calculer les UV en fonction de la position de chaque sommet + for (int y = 0; y < BlockSize; y++) { + for (int x = 0; x < BlockSize; x++) { + // Indices des sommets du premier triangle + //float u = ((float)x / (BlockSize - 1)) * 16; + //float v = ((float)y / (BlockSize - 1)) * 16; + // Définir la position de la texture dans l'atlas + int textureIndexX = 1; // Deuxième colonne + int textureIndexY = 0; // Première ligne + int atlasSize = 4; // L'atlas contient 4x4 textures + + // Calculer le décalage dans l'atlas pour la texture ciblée + float offsetX = (float)textureIndexX / atlasSize; + float offsetY = (float)textureIndexY / atlasSize; + + // Calculer la taille d'une texture dans l'atlas + float textureSize = 1.0f / atlasSize; + + // Calculer les coordonnées UV pour la répétition + float u = ((float)x / (BlockSize - 1)) * 16 * textureSize + offsetX; + float v = ((float)y / (BlockSize - 1)) * 16 * textureSize + offsetY; + + + verticesStruct.texturecoord[y * BlockSize + x] = new(u, v); + } + } + } } } diff --git a/LandblockExtraction/LandBlockExtractor/Utilities/VerticesStruct.cs b/LandblockExtraction/LandBlockExtractor/Utilities/VerticesStruct.cs index 2969214..4733cc2 100644 --- a/LandblockExtraction/LandBlockExtractor/Utilities/VerticesStruct.cs +++ b/LandblockExtraction/LandBlockExtractor/Utilities/VerticesStruct.cs @@ -5,17 +5,19 @@ namespace LandblockExtraction.LandBlockExtractor { public Vector3[] position { get; set; } public Vector4[] color { get; set; } public Vector4[] farcolor { get; set; } + public Vector2[] texturecoord { get; set; } public VerticesStruct(int blockSize) { position = new Vector3[blockSize * blockSize]; color = new Vector4[blockSize * blockSize]; farcolor = new Vector4[blockSize * blockSize]; + texturecoord = new Vector2[blockSize * blockSize]; } public float[] Vertices() { int length = position.Length; - float[] vertices = new float[length * 11]; // 3 pour position, 4 pour color, et 4 pour farcolor - for (int i = 0, vi = 0; i < length; i++, vi += 11) { + float[] vertices = new float[length * 13]; // 3 pour position, 4 pour color, et 4 pour farcolor + for (int i = 0, vi = 0; i < length; i++, vi += 13) { vertices[vi] = position[i].X; vertices[vi + 1] = position[i].Y; vertices[vi + 2] = position[i].Z; @@ -27,6 +29,8 @@ namespace LandblockExtraction.LandBlockExtractor { vertices[vi + 8] = farcolor[i].Y; vertices[vi + 9] = farcolor[i].Z; vertices[vi + 10] = farcolor[i].W; + vertices[vi + 11] = texturecoord[i].X; + vertices[vi + 12] = texturecoord[i].Y; } return vertices; } diff --git a/Map3DRendering/Common/Shader.cs b/Map3DRendering/Common/Shader.cs index 6837f2d..d16e150 100644 --- a/Map3DRendering/Common/Shader.cs +++ b/Map3DRendering/Common/Shader.cs @@ -163,6 +163,10 @@ namespace Map3DRendering.Common { /// /// The name of the uniform /// The data to set + public void SetVector2(string name, Vector2 data) { + GL.UseProgram(Handle); + GL.Uniform2(_uniformLocations[name], data); + } public void SetVector3(string name, Vector3 data) { GL.UseProgram(Handle); GL.Uniform3(_uniformLocations[name], data); diff --git a/Map3DRendering/MapRender.cs b/Map3DRendering/MapRender.cs index 6975f9a..6cdbfab 100644 --- a/Map3DRendering/MapRender.cs +++ b/Map3DRendering/MapRender.cs @@ -10,12 +10,12 @@ 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; private readonly int cellSize = 8; - private readonly int radius = 0x10; // Rayon du voisinage + private readonly int radius = 0x5; // Rayon du voisinage public int[,] _vertexArrayObject; public int[,] _vertexBufferObject; @@ -31,10 +31,6 @@ namespace Map3DRendering { public MapRender() { portalEngine = new PortalEngine(); cellEngine = new CellEngine(); - - terrainAtlasManager = new(portalEngine); - terrainAtlasManager.ExtractTexture(); - terrainAtlasManager.GenerateAtlas(); landblockExtraction = new(portalEngine, cellEngine); @@ -74,7 +70,7 @@ namespace Map3DRendering { } } private void InitializeBlock(int x, int y, BlockStruct block, Shader _shader) { - int lenghPacket = 11; + int lenghPacket = 13; // Initialisez le VAO, VBO et EBO pour le bloc à (x, y)... // Utilisez le code de votre méthode OnLoad originale pour configurer le VAO, VBO et EBO. int tempVertexArray = GL.GenVertexArray(); @@ -104,6 +100,10 @@ namespace Map3DRendering { var farcolorLocation = _shader.GetAttribLocation("aColorFar"); GL.EnableVertexAttribArray(farcolorLocation); GL.VertexAttribPointer(farcolorLocation, 4, VertexAttribPointerType.Float, false, lenghPacket * sizeof(float), 7 * sizeof(float)); + + var texturecoordLocation = _shader.GetAttribLocation("aTexCoord"); + GL.EnableVertexAttribArray(texturecoordLocation); + GL.VertexAttribPointer(texturecoordLocation, 2, VertexAttribPointerType.Float, false, lenghPacket * sizeof(float), 11 * sizeof(float)); } public void Render(Shader shader) { for (int y = startY; y <= endY; y++) { @@ -112,7 +112,7 @@ namespace Map3DRendering { var model = Matrix4.Identity;//CreateTranslation(x * BlockSize, 0, y * BlockSize); // Ajustez selon votre système de coordonnées shader.SetMatrix4("model", model); GL.BindVertexArray(_vertexArrayObject[x, y]); - GL.DrawElements(PrimitiveType.Lines, GetIndiceLenght(), DrawElementsType.UnsignedInt, 0); + GL.DrawElements(PrimitiveType.Triangles, GetIndiceLenght(), DrawElementsType.UnsignedInt, 0); } } } diff --git a/Map3DRendering/Shaders/shader.frag b/Map3DRendering/Shaders/shader.frag index 1b3ea88..93d9b74 100644 --- a/Map3DRendering/Shaders/shader.frag +++ b/Map3DRendering/Shaders/shader.frag @@ -3,15 +3,17 @@ out vec4 outputColor; uniform vec3 viewPos; +uniform sampler2D texture0; -in vec4 Color; in vec4 FarColor; in vec3 FragPos; +in vec2 TexCoord; void main() { float distance = length(viewPos - FragPos); - float interpolationFactor = clamp(distance / 1000, 0.0, 1.0); + float interpolationFactor = clamp(distance / 1000.0, 0.0, 1.0); - outputColor = mix(Color, FarColor, interpolationFactor); + vec4 textureColor = texture(texture0, TexCoord); + outputColor = mix(textureColor, FarColor, interpolationFactor); } \ No newline at end of file diff --git a/Map3DRendering/Shaders/shader.vert b/Map3DRendering/Shaders/shader.vert index 7ae0e72..cdbfcdf 100644 --- a/Map3DRendering/Shaders/shader.vert +++ b/Map3DRendering/Shaders/shader.vert @@ -2,6 +2,7 @@ layout (location = 0) in vec3 aPos; layout (location = 1) in vec4 aColor; layout (location = 2) in vec4 aColorFar; +layout (location = 3) in vec2 aTexCoord; uniform mat4 model; uniform mat4 view; @@ -10,6 +11,7 @@ uniform mat4 projection; out vec3 FragPos; out vec4 Color; out vec4 FarColor; +out vec2 TexCoord; void main() { @@ -17,4 +19,5 @@ void main() FragPos = vec3(vec4(aPos, 1.0) * model); Color = aColor; FarColor = aColorFar; + TexCoord = aTexCoord; } \ No newline at end of file diff --git a/Map3DRendering/Window.cs b/Map3DRendering/Window.cs index 0430adf..d5052d7 100644 --- a/Map3DRendering/Window.cs +++ b/Map3DRendering/Window.cs @@ -48,14 +48,16 @@ namespace Map3DRendering { _shader.Use(); mapRender.OnLoad(_shader); - //_texture = Texture.LoadFromFile("atlas.jpg"); - //_texture.Use(TextureUnit.Texture0); + _texture = Texture.LoadFromFile("atlas.jpg"); + _texture.Use(TextureUnit.Texture0); axesGizmo = new AxesGizmo(); _camera = new Camera(Vector3.UnitY * 300, Size.X / (float)Size.Y); _camera.Fov = 60; //CursorState = CursorState.Grabbed; + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); } protected override void OnRenderFrame(FrameEventArgs e) { @@ -66,7 +68,7 @@ namespace Map3DRendering { GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); _shader.Use(); - //_texture.Use(TextureUnit.Texture0); + _texture.Use(TextureUnit.Texture0); _shader.SetMatrix4("view", _camera.GetViewMatrix()); _shader.SetMatrix4("projection", _camera.GetProjectionMatrix());