From 664eb5872afea223910e341a6d50c7e62d281680 Mon Sep 17 00:00:00 2001 From: Troispoils Date: Tue, 27 Feb 2024 20:57:37 +0100 Subject: [PATCH] Success to blend 4 texture Need improuve for angle. --- .../AtlasMaker/AtlasBuilder.cs | 14 +- .../AtlasMaker/TerrainAtlasManager.cs | 26 +-- .../LandBlockExtractor/LandBlockExtrator.cs | 171 ++++++++++++------ .../Utilities/BlockStruct.cs | 29 --- .../Utilities/VerticesStruct.cs | 15 +- Map3DRendering/MapRender.cs | 10 +- Map3DRendering/Shaders/shader.frag | 20 +- Map3DRendering/Shaders/shader.vert | 6 + 8 files changed, 186 insertions(+), 105 deletions(-) diff --git a/LandblockExtraction/AtlasMaker/AtlasBuilder.cs b/LandblockExtraction/AtlasMaker/AtlasBuilder.cs index d22998d..b4547e5 100644 --- a/LandblockExtraction/AtlasMaker/AtlasBuilder.cs +++ b/LandblockExtraction/AtlasMaker/AtlasBuilder.cs @@ -9,23 +9,27 @@ using System.Text; using System.Threading.Tasks; namespace LandblockExtraction.AtlasMaker; -public class AtlasBuilder { +public class AtlasBuilder : IDisposable { private readonly int TEXTURESIZE = 64; private TexturesImage texturesImage; - private List textures; + public Dictionary textures; public AtlasBuilder(PortalEngine portalEngine) { textures = new(); texturesImage = new TexturesImage(portalEngine); } - public bool AddTexture(DataId matId) { + public bool AddTexture(int index, DataId matId) { var img = texturesImage.GetImage(matId); if(img == null) return false; - textures.Add(img); + textures.Add(index, img); return true; } + public void Dispose() { + textures.Clear(); + } + public void GenerateAtlas() { int count = (int)Math.Ceiling(Math.Sqrt(textures.Count)); int atlasSize = (int)TEXTURESIZE * count; @@ -36,7 +40,7 @@ public class AtlasBuilder { foreach (var kvp in textures) { int x = (index % count) * (int)TEXTURESIZE; int y = (index / count) * (int)TEXTURESIZE; - atlas.Composite(kvp, x, y); + atlas.Composite(kvp.Value, x, y); index++; if (index >= count * count) break; diff --git a/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs b/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs index 6390681..8964ecb 100644 --- a/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs +++ b/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs @@ -1,4 +1,5 @@ using AC2RE.Definitions; +using ImageMagick; using LandblockExtraction.DatEngine; using System; using System.Collections.Generic; @@ -11,28 +12,31 @@ using System.Threading.Tasks; namespace LandblockExtraction.AtlasMaker; public class TerrainAtlasManager { private PortalEngine portalEngine; - private AtlasBuilder atlasBuilder; public Dictionary textureCoord; - + public Dictionary terrainTexture; public TerrainAtlasManager(PortalEngine portalEngine) { this.portalEngine = portalEngine; textureCoord = new Dictionary(); - atlasBuilder = new AtlasBuilder(portalEngine); + terrainTexture = new Dictionary(); } 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); + using (var atlasBuilder = new AtlasBuilder(portalEngine)) { + foreach (var terrain in portalEngine.cTerrainDesc.terrains) { + foreach (var surface in portalEngine.cSurfaceDesc.surfaces) { + if (surface.surfIndex == terrain.surfaceInfo) { + atlasBuilder.AddTexture((int)terrain.terrainIndex, surface.terrainMaterials.First().baseMaterials.First().materialDid); + } } + textureCoord.Add((int)terrain.terrainIndex, Vector2.Zero); + } + + atlasBuilder.GenerateAtlas(); + foreach(var img in atlasBuilder.textures) { + terrainTexture.Add(img.Key, img.Value); } - 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; diff --git a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs index 7295516..26b22fc 100644 --- a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs +++ b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs @@ -21,7 +21,6 @@ namespace LandblockExtraction.LandBlockExtractor { terrainAtlasManager = new TerrainAtlasManager(portalEngine); terrainAtlasManager.ExtractTexture(); - terrainAtlasManager.GenerateAtlas(); terrainAtlasManager.GenerateUV(); } @@ -35,72 +34,48 @@ namespace LandblockExtraction.LandBlockExtractor { public BlockStruct GenerateBlockStructByData(CLandBlockData blockData, int landX, int landY) { BlockStruct blockStruct = new BlockStruct(); - for (int y = 0; y < BlockStruct.BlockSize; y++) { - for (int x = 0; x < BlockStruct.BlockSize; x++) { - var indice = y * BlockStruct.BlockSize + x; + for (int y = 0; y < BlockSize; y++) { + for (int x = 0; x < BlockSize; x++) { + var indice = y * BlockSize + x; blockStruct.verticesStruct.position[indice] = GenerateVertexPosition(landX, landY, x, y, blockData.heights[indice]); blockStruct.verticesStruct.color[indice] = GenerateVertexColor(blockData.cellInfos[indice]); blockStruct.verticesStruct.farcolor[indice] = GenerateVertexFarColor(blockData.cellInfos[indice]); - blockStruct.GenerateIndices(); - //blockStruct.GenerateUVByIndices(); - GenerateVertexTextureCoord(blockData, blockStruct); + blockStruct.verticesStruct.terraintype[indice] = GenerateVertexTerrainType(blockData.cellInfos[indice]); + blockStruct.indices = GenerateBasicIndices(); } } + DoubleEdgeVertices(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 + private int[] GenerateBasicIndices() { + List indices = new List(); - 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]]); + for (int y = 0; y < BlockSize - 1; y++) { + for (int x = 0; x < BlockSize - 1; x++) { + // Indices des sommets du premier triangle + indices.Add(y * BlockSize + x); + indices.Add((y + 1) * BlockSize + x); + indices.Add(y * BlockSize + x + 1); - // 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); + // Indices des sommets du deuxième triangle + indices.Add(y * BlockSize + x + 1); + indices.Add((y + 1) * BlockSize + x); + indices.Add((y + 1) * BlockSize + x + 1); + } } - // 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(); + return indices.ToArray(); } + + private Vector4 GenerateVertexTerrainType(uint cellInfo) { + var terrain = MathOperations.GetTerrainInCellInfo(cellInfo); + + return new(terrain, 0f, 0f, 0f); + } + 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; @@ -141,5 +116,95 @@ namespace LandblockExtraction.LandBlockExtractor { return Vector4.One; } + + //TEST + public void DoubleEdgeVertices(BlockStruct blockStruct) { + List newPositions = new List(); + List newColors = new List(); + List newFarColors = new List(); + List newTexCoord = new List(); + List newTerrainTypes = new List(); + List newRealTerrainType = new List(); + + int originalVertexCount = blockStruct.verticesStruct.position.Length; + int originalIndicesCount = blockStruct.indices.Length; + + // Doubler les sommets sur le bord supérieur et inférieur + + for(int i = 0; i < originalIndicesCount; i = i + 6) { + + var one = blockStruct.indices[i + 0]; + var two = blockStruct.indices[i + 1]; + var three = blockStruct.indices[i + 2]; + var foor = blockStruct.indices[i + 5]; + + newPositions.Add(blockStruct.verticesStruct.position[one]); + newColors.Add(blockStruct.verticesStruct.color[one]); + newFarColors.Add(blockStruct.verticesStruct.farcolor[one]); + newTerrainTypes.Add(new Vector4(blockStruct.verticesStruct.terraintype[one].X, + blockStruct.verticesStruct.terraintype[two].X, + blockStruct.verticesStruct.terraintype[three].X, + blockStruct.verticesStruct.terraintype[foor].X)); + newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[one].X); + + newPositions.Add(blockStruct.verticesStruct.position[two]); + newColors.Add(blockStruct.verticesStruct.color[two]); + newFarColors.Add(blockStruct.verticesStruct.farcolor[two]); + newTerrainTypes.Add(new Vector4(blockStruct.verticesStruct.terraintype[one].X, + blockStruct.verticesStruct.terraintype[two].X, + blockStruct.verticesStruct.terraintype[three].X, + blockStruct.verticesStruct.terraintype[foor].X)); + newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[two].X); + + newPositions.Add(blockStruct.verticesStruct.position[three]); + newColors.Add(blockStruct.verticesStruct.color[three]); + newFarColors.Add(blockStruct.verticesStruct.farcolor[three]); + newTerrainTypes.Add(new Vector4(blockStruct.verticesStruct.terraintype[one].X, + blockStruct.verticesStruct.terraintype[two].X, + blockStruct.verticesStruct.terraintype[three].X, + blockStruct.verticesStruct.terraintype[foor].X)); + newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[three].X); + + + newPositions.Add(blockStruct.verticesStruct.position[foor]); + newColors.Add(blockStruct.verticesStruct.color[foor]); + newFarColors.Add(blockStruct.verticesStruct.farcolor[foor]); + newTerrainTypes.Add(new Vector4(blockStruct.verticesStruct.terraintype[one].X, + blockStruct.verticesStruct.terraintype[two].X, + blockStruct.verticesStruct.terraintype[three].X, + blockStruct.verticesStruct.terraintype[foor].X)); + newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[foor].X); + + newTexCoord.Add(new(0, 0)); + newTexCoord.Add(new(0, 1)); + newTexCoord.Add(new(1, 0)); + newTexCoord.Add(new(1, 1)); + } + + // Ajouter les nouveaux sommets à la structure BlockStruct (étape 2) + // Vous devez également mettre à jour les indices dans blockStruct.indices + blockStruct.verticesStruct.position = newPositions.ToArray(); + blockStruct.verticesStruct.color = newColors.ToArray(); + blockStruct.verticesStruct.farcolor = newFarColors.ToArray(); + blockStruct.verticesStruct.texturecoord = newTexCoord.ToArray(); + blockStruct.verticesStruct.terraintype = newTerrainTypes.ToArray(); + blockStruct.verticesStruct.realtype = newRealTerrainType.ToArray(); + + blockStruct.indices = GenerateNewsIndices(newPositions.Count); + } + + private int[] GenerateNewsIndices(int count) { + List indices = new List(); + for(int i = 0; i < count; i = i + 4) { + indices.Add(i); + indices.Add(i + 1); + indices.Add(i + 2); + indices.Add(i + 2); + indices.Add(i + 1); + indices.Add(i + 3); + } + + return indices.ToArray(); + } } } diff --git a/LandblockExtraction/LandBlockExtractor/Utilities/BlockStruct.cs b/LandblockExtraction/LandBlockExtractor/Utilities/BlockStruct.cs index a7e9a0b..e329c48 100644 --- a/LandblockExtraction/LandBlockExtractor/Utilities/BlockStruct.cs +++ b/LandblockExtraction/LandBlockExtractor/Utilities/BlockStruct.cs @@ -30,34 +30,5 @@ namespace LandblockExtraction.LandBlockExtractor { } } } - - 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 4733cc2..cf02b41 100644 --- a/LandblockExtraction/LandBlockExtractor/Utilities/VerticesStruct.cs +++ b/LandblockExtraction/LandBlockExtractor/Utilities/VerticesStruct.cs @@ -6,18 +6,22 @@ namespace LandblockExtraction.LandBlockExtractor { public Vector4[] color { get; set; } public Vector4[] farcolor { get; set; } public Vector2[] texturecoord { get; set; } + public Vector4[] terraintype { get; set; } + public float[] realtype { 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]; + texturecoord = new Vector2[blockSize * blockSize]; + terraintype = new Vector4[blockSize * blockSize]; + realtype = new float[blockSize * blockSize]; } public float[] Vertices() { int length = position.Length; - 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) { + float[] vertices = new float[length * 18]; // 3 pour position, 4 pour color, et 4 pour farcolor + for (int i = 0, vi = 0; i < length; i++, vi += 18) { vertices[vi] = position[i].X; vertices[vi + 1] = position[i].Y; vertices[vi + 2] = position[i].Z; @@ -31,6 +35,11 @@ namespace LandblockExtraction.LandBlockExtractor { vertices[vi + 10] = farcolor[i].W; vertices[vi + 11] = texturecoord[i].X; vertices[vi + 12] = texturecoord[i].Y; + vertices[vi + 13] = terraintype[i].X; + vertices[vi + 14] = terraintype[i].Y; + vertices[vi + 15] = terraintype[i].Z; + vertices[vi + 16] = terraintype[i].W; + vertices[vi + 17] = realtype[i]; } return vertices; } diff --git a/Map3DRendering/MapRender.cs b/Map3DRendering/MapRender.cs index 6cdbfab..25c15e9 100644 --- a/Map3DRendering/MapRender.cs +++ b/Map3DRendering/MapRender.cs @@ -70,7 +70,7 @@ namespace Map3DRendering { } } private void InitializeBlock(int x, int y, BlockStruct block, Shader _shader) { - int lenghPacket = 13; + int lenghPacket = 18; // 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 +104,14 @@ namespace Map3DRendering { var texturecoordLocation = _shader.GetAttribLocation("aTexCoord"); GL.EnableVertexAttribArray(texturecoordLocation); GL.VertexAttribPointer(texturecoordLocation, 2, VertexAttribPointerType.Float, false, lenghPacket * sizeof(float), 11 * sizeof(float)); + + var terraintypeLocation = _shader.GetAttribLocation("aTexType"); + GL.EnableVertexAttribArray(terraintypeLocation); + GL.VertexAttribPointer(terraintypeLocation, 4, VertexAttribPointerType.Float, false, lenghPacket * sizeof(float), 13 * sizeof(float)); + + var realterraintypeLocation = _shader.GetAttribLocation("aRealTexType"); + GL.EnableVertexAttribArray(realterraintypeLocation); + GL.VertexAttribPointer(realterraintypeLocation, 1, VertexAttribPointerType.Float, false, lenghPacket * sizeof(float), 13 * sizeof(float)); } public void Render(Shader shader) { for (int y = startY; y <= endY; y++) { diff --git a/Map3DRendering/Shaders/shader.frag b/Map3DRendering/Shaders/shader.frag index 93d9b74..a14c099 100644 --- a/Map3DRendering/Shaders/shader.frag +++ b/Map3DRendering/Shaders/shader.frag @@ -8,12 +8,26 @@ uniform sampler2D texture0; in vec4 FarColor; in vec3 FragPos; in vec2 TexCoord; +in vec4 TexType; +in float RealType; void main() { + float tileSize = 64.0 / 512.0; + + vec2 uvOffsets[4]; + uvOffsets[0] = vec2(mod(TexType.x, 8.0), floor(TexType.x / 8.0)) * tileSize; + uvOffsets[1] = vec2(mod(TexType.y, 8.0), floor(TexType.y / 8.0)) * tileSize; + uvOffsets[2] = vec2(mod(TexType.z, 8.0), floor(TexType.z / 8.0)) * tileSize; + uvOffsets[3] = vec2(mod(TexType.w, 8.0), floor(TexType.w / 8.0)) * tileSize; + + vec4 blendedColor = vec4(0.0); + for (int i = 0; i < 4; i++) { + vec2 uv = TexCoord * tileSize + uvOffsets[i]; + blendedColor += texture(texture0, uv) * 0.25; + } + float distance = length(viewPos - FragPos); float interpolationFactor = clamp(distance / 1000.0, 0.0, 1.0); - - vec4 textureColor = texture(texture0, TexCoord); - outputColor = mix(textureColor, FarColor, interpolationFactor); + outputColor = mix(blendedColor, FarColor, interpolationFactor); } \ No newline at end of file diff --git a/Map3DRendering/Shaders/shader.vert b/Map3DRendering/Shaders/shader.vert index cdbfcdf..1e03adc 100644 --- a/Map3DRendering/Shaders/shader.vert +++ b/Map3DRendering/Shaders/shader.vert @@ -3,6 +3,8 @@ layout (location = 0) in vec3 aPos; layout (location = 1) in vec4 aColor; layout (location = 2) in vec4 aColorFar; layout (location = 3) in vec2 aTexCoord; +layout (location = 4) in vec4 aTexType; +layout (location = 5) in float aRealTexType; uniform mat4 model; uniform mat4 view; @@ -12,6 +14,8 @@ out vec3 FragPos; out vec4 Color; out vec4 FarColor; out vec2 TexCoord; +out vec4 TexType; +out float RealType; void main() { @@ -20,4 +24,6 @@ void main() Color = aColor; FarColor = aColorFar; TexCoord = aTexCoord; + TexType = aTexType; + RealType = aRealTexType; } \ No newline at end of file