From 3a7d169b30c0b2a20b89bef030b19573c6fad00f Mon Sep 17 00:00:00 2001 From: Troispoils Date: Thu, 29 Feb 2024 16:51:41 +0100 Subject: [PATCH 1/3] Test with new technique texturing --- .../AtlasMaker/TerrainAtlasManager.cs | 12 +++ .../AtlasMaker/TexturesImage.cs | 2 +- .../LandBlockExtractor/LandBlockExtrator.cs | 73 +++++++++++++++++-- Map3DRendering/Common/Shader.cs | 19 ++--- Map3DRendering/Common/Texture.cs | 13 ++-- Map3DRendering/Program.cs | 2 +- Map3DRendering/Shaders/shader.frag | 41 +++-------- Map3DRendering/Window.cs | 24 +++++- 8 files changed, 125 insertions(+), 61 deletions(-) diff --git a/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs b/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs index 9a169e2..cf211c2 100644 --- a/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs +++ b/LandblockExtraction/AtlasMaker/TerrainAtlasManager.cs @@ -5,6 +5,7 @@ using System.Numerics; namespace LandblockExtraction.AtlasMaker; public class TerrainAtlasManager { + private readonly string PATHTERRAINIMG = @".\terrains"; private PortalEngine portalEngine; public Dictionary textureCoord; @@ -51,6 +52,17 @@ public class TerrainAtlasManager { } } } + public void SaveAllTerrain() { + if (!Directory.Exists(PATHTERRAINIMG)) { + Directory.CreateDirectory(PATHTERRAINIMG); + } + + foreach(var img in terrainTexture) { + var path = Path.Combine(PATHTERRAINIMG, img.Key.ToString()); + + img.Value.Write(path + ".jpg"); + } + } private int? GetIndexBySurface(uint surfaceIndex) { foreach(var terrain in portalEngine.cTerrainDesc.terrains) { if (terrain.surfaceInfo == surfaceIndex) diff --git a/LandblockExtraction/AtlasMaker/TexturesImage.cs b/LandblockExtraction/AtlasMaker/TexturesImage.cs index 18ca924..cea78c1 100644 --- a/LandblockExtraction/AtlasMaker/TexturesImage.cs +++ b/LandblockExtraction/AtlasMaker/TexturesImage.cs @@ -40,7 +40,7 @@ public class TexturesImage { if (!portalEngine.datReader.contains(img)) continue; using (var data = portalEngine.datReader.getFileReader(img)) { var image = new RenderSurface(data); - if (image.width != 64) continue; + if (image.width != 256) continue; var dataImg = DDSHeader.Generate(image); using (MagickImage realImg = new MagickImage(dataImg)) { magickImage = new(realImg); diff --git a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs index d6597d3..d04368e 100644 --- a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs +++ b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs @@ -2,6 +2,7 @@ using LandblockExtraction.AtlasMaker; using LandblockExtraction.DatEngine; using LandblockExtraction.Tools; +using System; using System.Numerics; namespace LandblockExtraction.LandBlockExtractor { @@ -21,6 +22,7 @@ namespace LandblockExtraction.LandBlockExtractor { terrainAtlasManager = new TerrainAtlasManager(portalEngine); terrainAtlasManager.ExtractTexture(); terrainAtlasManager.GenerateUV(); + terrainAtlasManager.SaveAllTerrain(); } public BlockStruct? GetBlock(int landX, int landY) { @@ -40,15 +42,72 @@ namespace LandblockExtraction.LandBlockExtractor { blockStruct.verticesStruct.color[indice] = GenerateVertexColor(blockData.cellInfos[indice]); blockStruct.verticesStruct.farcolor[indice] = GenerateVertexFarColor(blockData.cellInfos[indice]); blockStruct.verticesStruct.terraintype[indice] = GenerateVertexTerrainType(blockData.cellInfos[indice]); + blockStruct.verticesStruct.texturecoord[indice] = GenerateBasicUV(x, y); blockStruct.indices = GenerateBasicIndices(); + + } + } + blockStruct.verticesStruct.normal = GenerateBasicNormal(blockStruct); + //DoubleEdgeVertices(blockStruct); + + Dictionary testTerr = new Dictionary(); + foreach (var test in blockStruct.verticesStruct.terraintype) { + var type = (int)test.X; + if (testTerr.ContainsKey(type)) { + testTerr[type]++; + } else { + testTerr.Add(type, 1); } } - DoubleEdgeVertices(blockStruct); - return blockStruct; } + private Vector2 GenerateBasicUV(int x, int y) { + float u = (float)x / (BlockSize - 1) * 16; + float v = (float)y / (BlockSize - 1) * 16; + + return new Vector2(u, v); + } + + private Vector3[] GenerateBasicNormal(BlockStruct blockStruct) { + Vector3[] normals = new Vector3[blockStruct.verticesStruct.position.Length]; + + // Initialise tous les vecteurs normaux à zéro + for (int i = 0; i < normals.Length; i++) { + normals[i] = new Vector3(0, 0, 0); + } + + // Parcourt tous les indices et calcule les normales pour chaque triangle + for (int i = 0; i < blockStruct.indices.Length; i += 3) { + int index1 = blockStruct.indices[i]; + int index2 = blockStruct.indices[i + 1]; + int index3 = blockStruct.indices[i + 2]; + + Vector3 vertex1 = blockStruct.verticesStruct.position[index1]; + Vector3 vertex2 = blockStruct.verticesStruct.position[index2]; + Vector3 vertex3 = blockStruct.verticesStruct.position[index3]; + + // Calcule la normale du triangle + /*Vector3 edge1 = vertex2 - vertex1; + Vector3 edge2 = vertex3 - vertex1; + Vector3 normal = Vector3.Cross(edge1, edge2); + normal = Vector3.Normalize(normal);*/ + var normal = MathOperations.CalculateTriangleNormal(vertex1, vertex2, vertex3); + // Ajoute la normale du triangle aux normales des sommets du triangle + normals[index1] += normal; + normals[index2] += normal; + normals[index3] += normal; + } + + // Normalise toutes les normales de sommets pour qu'elles soient de longueur unitaire + for (int i = 0; i < normals.Length; i++) { + normals[i] = Vector3.Normalize(normals[i]); + } + + return normals; + } + private int[] GenerateBasicIndices() { List indices = new List(); @@ -147,7 +206,7 @@ namespace LandblockExtraction.LandBlockExtractor { blockStruct.verticesStruct.terraintype[foor].X)); newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[one].X); - newPositions.Add(blockStruct.verticesStruct.position[two]); + /*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, @@ -178,7 +237,7 @@ namespace LandblockExtraction.LandBlockExtractor { newTexCoord.Add(new(0, 0)); newTexCoord.Add(new(0, 1)); newTexCoord.Add(new(1, 0)); - newTexCoord.Add(new(1, 1)); + newTexCoord.Add(new(1, 1));*/ var normal = MathOperations.CalculateQuadNormal(blockStruct.verticesStruct.position[one], blockStruct.verticesStruct.position[two], @@ -186,9 +245,9 @@ namespace LandblockExtraction.LandBlockExtractor { blockStruct.verticesStruct.position[foor]); newNormals.Add(normal); - newNormals.Add(normal); - newNormals.Add(normal); - newNormals.Add(normal); + //newNormals.Add(normal); + //newNormals.Add(normal); + //newNormals.Add(normal); } // Ajouter les nouveaux sommets à la structure BlockStruct (étape 2) diff --git a/Map3DRendering/Common/Shader.cs b/Map3DRendering/Common/Shader.cs index d16e150..dd7900a 100644 --- a/Map3DRendering/Common/Shader.cs +++ b/Map3DRendering/Common/Shader.cs @@ -1,7 +1,11 @@ -using OpenTK.Graphics.OpenGL4; +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; +using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; -namespace Map3DRendering.Common { +namespace Map3DRendering { // A simple class meant to help create shaders. public class Shader { public readonly int Handle; @@ -163,18 +167,9 @@ 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); } - - public void SetVector4(string name, Vector4 data) { - GL.UseProgram(Handle); - GL.Uniform4(_uniformLocations[name], data); - } } -} +} \ No newline at end of file diff --git a/Map3DRendering/Common/Texture.cs b/Map3DRendering/Common/Texture.cs index d0cf265..2032c28 100644 --- a/Map3DRendering/Common/Texture.cs +++ b/Map3DRendering/Common/Texture.cs @@ -1,7 +1,11 @@ using OpenTK.Graphics.OpenGL4; +using System.Drawing; +using System.Drawing.Imaging; +using PixelFormat = OpenTK.Graphics.OpenGL4.PixelFormat; using StbImageSharp; +using System.IO; -namespace Map3DRendering.Common { +namespace Map3DRendering { // A helper class, much like Shader, meant to simplify loading textures. public class Texture { public readonly int Handle; @@ -77,10 +81,5 @@ namespace Map3DRendering.Common { GL.ActiveTexture(unit); GL.BindTexture(TextureTarget.Texture2D, Handle); } - - public void Assign(int shader, int i) { - int location = GL.GetUniformLocation(shader, "textures[" + i.ToString() + "]"); - GL.Uniform1(location, i); - } } -} +} \ No newline at end of file diff --git a/Map3DRendering/Program.cs b/Map3DRendering/Program.cs index 4df39d6..88992d4 100644 --- a/Map3DRendering/Program.cs +++ b/Map3DRendering/Program.cs @@ -6,7 +6,7 @@ namespace Map3DRendering { public static class Program { private static void Main() { var nativeWindowSettings = new NativeWindowSettings() { - Size = new Vector2i(800, 600), + ClientSize = new Vector2i(800, 600), Title = "LearnOpenTK - Map AC2", // This is needed to run on macos Flags = ContextFlags.ForwardCompatible, diff --git a/Map3DRendering/Shaders/shader.frag b/Map3DRendering/Shaders/shader.frag index 0e12667..b2e8c63 100644 --- a/Map3DRendering/Shaders/shader.frag +++ b/Map3DRendering/Shaders/shader.frag @@ -2,11 +2,14 @@ out vec4 outputColor; +uniform sampler2D texture0; +uniform sampler2D texture1; + uniform vec3 viewPos; uniform vec3 lightPos; uniform vec3 lightColor; -uniform sampler2D texture0; +in vec4 Color; in vec4 FarColor; in vec3 Normal; in vec3 FragPos; @@ -16,40 +19,20 @@ in float RealType; void main() { - float tileSize = 64.0 / 512.0; - - float baseWeight = 0.2; - float dominantWeight = 0.4; - - vec4 weights = vec4(baseWeight); - vec2 uvOffsets[4]; - for (int i = 0; i < 4; i++) { - float type = TexType[i]; - uvOffsets[i] = vec2(mod(type, 8.0), floor(type / 8.0)) * tileSize; - if (type == RealType) { - weights[i] = dominantWeight; - } - } - - vec4 blendedColor[4]; - for (int i = 0; i < 4; i++) { - vec2 uv = TexCoord * tileSize + uvOffsets[i]; - blendedColor[i] = texture(texture0, uv); - } - - float weightX = TexCoord.x; - float weightY = TexCoord.y; - - vec4 mix1 = mix(blendedColor[0], blendedColor[2], weightX); - vec4 mix2 = mix(blendedColor[1], blendedColor[3], weightX); - vec4 finalColor = mix(mix1, mix2, weightY); + vec4 color0 = texture(texture0, TexCoord); + vec4 color1 = texture(texture1, TexCoord); vec3 norm = normalize(Normal); + + float inclineFactor = abs(norm.y); + + vec4 finalColor = mix(color0, color1, inclineFactor); + vec3 lightDir = normalize(lightPos - FragPos); float diff = max(dot(norm, lightDir), 0.0); vec3 diffuse = diff * lightColor; - vec4 litColor = vec4(diffuse, 1.0) * finalColor; + vec4 litColor = vec4(diffuse, 1.0) * finalColor * Color; float distance = length(viewPos - FragPos); float interpolationFactor = clamp(distance / 1000.0, 0.0, 1.0); diff --git a/Map3DRendering/Window.cs b/Map3DRendering/Window.cs index 39ff51c..8040ec4 100644 --- a/Map3DRendering/Window.cs +++ b/Map3DRendering/Window.cs @@ -16,6 +16,7 @@ namespace Map3DRendering { private Shader _shader; private Texture _texture; + private Texture _texture2; private Camera _camera; @@ -53,16 +54,29 @@ namespace Map3DRendering { _shader.Use(); mapRender.OnLoad(_shader); - _texture = Texture.LoadFromFile("atlas.jpg"); + + _texture = Texture.LoadFromFile("terrains/0.jpg"); + // Texture units are explained in Texture.cs, at the Use function. + // First texture goes in texture unit 0. _texture.Use(TextureUnit.Texture0); + // This is helpful because System.Drawing reads the pixels differently than OpenGL expects. + _texture2 = Texture.LoadFromFile("terrains/1.jpg"); + // Then, the second goes in texture unit 1. + _texture2.Use(TextureUnit.Texture1); + + // Next, we must setup the samplers in the shaders to use the right textures. + // The int we send to the uniform indicates which texture unit the sampler should use. + _shader.SetInt("texture0", 0); + _shader.SetInt("texture1", 1); + 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); + //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); _lightPosVec = Vector3.UnitY * 1000; } @@ -73,8 +87,9 @@ namespace Map3DRendering { GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - _shader.Use(); _texture.Use(TextureUnit.Texture0); + _texture2.Use(TextureUnit.Texture1); + _shader.Use(); _shader.SetMatrix4("view", _camera.GetViewMatrix()); _shader.SetMatrix4("projection", _camera.GetProjectionMatrix()); @@ -82,6 +97,7 @@ namespace Map3DRendering { //_shader.SetVector3("objectColor", new Vector3(0.5f, 0.5f, 0.5f)); _shader.SetVector3("lightColor", new Vector3(1.0f, 1.0f, 1.0f)); _shader.SetVector3("lightPos", _lightPosVec); + //_shader.SetVector3("viewPos", _camera.Position); GL.LineWidth(5.0f); From 2b62d3b9e4f21a454d016b255b05b6d86fcedacd Mon Sep 17 00:00:00 2001 From: Troispoils Date: Thu, 29 Feb 2024 17:09:27 +0100 Subject: [PATCH 2/3] Update Normal calcul --- .../LandBlockExtractor/LandBlockExtrator.cs | 11 +++++++---- Map3DRendering/Shaders/shader.frag | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs index d04368e..cf65fac 100644 --- a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs +++ b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs @@ -64,8 +64,8 @@ namespace LandblockExtraction.LandBlockExtractor { } private Vector2 GenerateBasicUV(int x, int y) { - float u = (float)x / (BlockSize - 1) * 16; - float v = (float)y / (BlockSize - 1) * 16; + float u = (float)x / (BlockSize - 1) * 8; + float v = (float)y / (BlockSize - 1) * 8; return new Vector2(u, v); } @@ -79,25 +79,28 @@ namespace LandblockExtraction.LandBlockExtractor { } // Parcourt tous les indices et calcule les normales pour chaque triangle - for (int i = 0; i < blockStruct.indices.Length; i += 3) { + for (int i = 0; i < blockStruct.indices.Length; i += 6) { int index1 = blockStruct.indices[i]; int index2 = blockStruct.indices[i + 1]; int index3 = blockStruct.indices[i + 2]; + int index4 = blockStruct.indices[i + 5]; Vector3 vertex1 = blockStruct.verticesStruct.position[index1]; Vector3 vertex2 = blockStruct.verticesStruct.position[index2]; Vector3 vertex3 = blockStruct.verticesStruct.position[index3]; + Vector3 vertex4 = blockStruct.verticesStruct.position[index4]; // Calcule la normale du triangle /*Vector3 edge1 = vertex2 - vertex1; Vector3 edge2 = vertex3 - vertex1; Vector3 normal = Vector3.Cross(edge1, edge2); normal = Vector3.Normalize(normal);*/ - var normal = MathOperations.CalculateTriangleNormal(vertex1, vertex2, vertex3); + var normal = MathOperations.CalculateQuadNormal(vertex1, vertex2, vertex3, vertex4); // Ajoute la normale du triangle aux normales des sommets du triangle normals[index1] += normal; normals[index2] += normal; normals[index3] += normal; + normals[index4] += normal; } // Normalise toutes les normales de sommets pour qu'elles soient de longueur unitaire diff --git a/Map3DRendering/Shaders/shader.frag b/Map3DRendering/Shaders/shader.frag index b2e8c63..8de05a0 100644 --- a/Map3DRendering/Shaders/shader.frag +++ b/Map3DRendering/Shaders/shader.frag @@ -26,7 +26,7 @@ void main() float inclineFactor = abs(norm.y); - vec4 finalColor = mix(color0, color1, inclineFactor); + vec4 finalColor = mix(color0, color1, norm.y); vec3 lightDir = normalize(lightPos - FragPos); float diff = max(dot(norm, lightDir), 0.0); From 51325d86508320d2338e2273c85d9eb13d68ace3 Mon Sep 17 00:00:00 2001 From: Troispoils Date: Fri, 1 Mar 2024 14:03:04 +0100 Subject: [PATCH 3/3] Test array texture --- .../LandBlockExtractor/LandBlockExtrator.cs | 33 ++++++++++++++- Map3DRendering/Common/Texture.cs | 40 +++++++++++++++++++ Map3DRendering/Shaders/shader.frag | 10 ++--- Map3DRendering/Window.cs | 19 +++------ 4 files changed, 80 insertions(+), 22 deletions(-) diff --git a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs index cf65fac..a9f41a5 100644 --- a/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs +++ b/LandblockExtraction/LandBlockExtractor/LandBlockExtrator.cs @@ -42,11 +42,12 @@ namespace LandblockExtraction.LandBlockExtractor { blockStruct.verticesStruct.color[indice] = GenerateVertexColor(blockData.cellInfos[indice]); blockStruct.verticesStruct.farcolor[indice] = GenerateVertexFarColor(blockData.cellInfos[indice]); blockStruct.verticesStruct.terraintype[indice] = GenerateVertexTerrainType(blockData.cellInfos[indice]); - blockStruct.verticesStruct.texturecoord[indice] = GenerateBasicUV(x, y); + blockStruct.verticesStruct.texturecoord[indice] = GenerateUVForSubTile(x, y); blockStruct.indices = GenerateBasicIndices(); } } + //blockStruct.verticesStruct.texturecoord = GenerateBasicUVTest(blockStruct); blockStruct.verticesStruct.normal = GenerateBasicNormal(blockStruct); //DoubleEdgeVertices(blockStruct); @@ -69,7 +70,37 @@ namespace LandblockExtraction.LandBlockExtractor { return new Vector2(u, v); } + private Vector2 GenerateUVForSubTile(int x, int y) { + // Taille d'une "mini-tuile" en termes de coordonnées UV + float miniTileSize = 1f / BlockSize - 1; // Comme la sous-grille est 5x5 + // Calcul des coordonnées UV basées sur la position (x, y) dans la sous-grille + float u = x * miniTileSize; + float v = y * miniTileSize; + + return new Vector2(u, v); + } + private Vector2[] GenerateBasicUVTest(BlockStruct blockStruct) { + Vector2[] uvs = new Vector2[blockStruct.verticesStruct.position.Length]; + + for (int i = 0; i < uvs.Length; i++) { + uvs[i] = new Vector2(0, 0); + } + + for (int i = 0; i < blockStruct.indices.Length; i += 6) { + int index1 = blockStruct.indices[i]; + int index2 = blockStruct.indices[i + 1]; + int index3 = blockStruct.indices[i + 2]; + int index4 = blockStruct.indices[i + 5]; + + uvs[index1] = new(0, 0); + uvs[index2] = new(0, 1); + uvs[index3] = new(1, 0); + uvs[index4] = new(1, 1); + } + + return uvs; + } private Vector3[] GenerateBasicNormal(BlockStruct blockStruct) { Vector3[] normals = new Vector3[blockStruct.verticesStruct.position.Length]; diff --git a/Map3DRendering/Common/Texture.cs b/Map3DRendering/Common/Texture.cs index 2032c28..96e397c 100644 --- a/Map3DRendering/Common/Texture.cs +++ b/Map3DRendering/Common/Texture.cs @@ -68,6 +68,42 @@ namespace Map3DRendering { return new Texture(handle); } + public static Texture LoadFromArray(string[] paths) { + // Générer un identifiant de texture + int handle = GL.GenTexture(); + + // Activer la texture + GL.ActiveTexture(TextureUnit.Texture0); + GL.BindTexture(TextureTarget.Texture2DArray, handle); + + // Ici, nous supposons que toutes les images ont les mêmes dimensions et le même format + // Charger la première image pour obtenir les dimensions + ImageResult firstImage = ImageResult.FromStream(File.OpenRead(paths[0]), ColorComponents.RedGreenBlueAlpha); + int width = firstImage.Width; + int height = firstImage.Height; + + // Initialiser la texture 2D array sans lui passer de données pour l'instant + GL.TexImage3D(TextureTarget.Texture2DArray, 0, PixelInternalFormat.Rgba, width, height, paths.Length, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); + + // Charger chaque texture dans l'array + for (int i = 0; i < paths.Length; i++) { + using (Stream stream = File.OpenRead(paths[i])) { + ImageResult image = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha); + GL.TexSubImage3D(TextureTarget.Texture2DArray, 0, 0, 0, i, width, height, 1, PixelFormat.Rgba, PixelType.UnsignedByte, image.Data); + } + } + + // Paramètres de texture + GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); + GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); + + // Générer des mipmaps pour la texture array + GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); + + return new Texture(handle); + } public Texture(int glHandle) { Handle = glHandle; @@ -81,5 +117,9 @@ namespace Map3DRendering { GL.ActiveTexture(unit); GL.BindTexture(TextureTarget.Texture2D, Handle); } + public void UseArray(TextureUnit unit) { + GL.ActiveTexture(unit); + GL.BindTexture(TextureTarget.Texture2DArray, Handle); + } } } \ No newline at end of file diff --git a/Map3DRendering/Shaders/shader.frag b/Map3DRendering/Shaders/shader.frag index 8de05a0..a559a77 100644 --- a/Map3DRendering/Shaders/shader.frag +++ b/Map3DRendering/Shaders/shader.frag @@ -2,8 +2,7 @@ out vec4 outputColor; -uniform sampler2D texture0; -uniform sampler2D texture1; +uniform sampler2DArray texture0; uniform vec3 viewPos; uniform vec3 lightPos; @@ -19,14 +18,11 @@ in float RealType; void main() { - vec4 color0 = texture(texture0, TexCoord); - vec4 color1 = texture(texture1, TexCoord); + vec4 color0 = texture(texture0, vec3(TexCoord, TexType.x)); vec3 norm = normalize(Normal); - float inclineFactor = abs(norm.y); - - vec4 finalColor = mix(color0, color1, norm.y); + vec4 finalColor = color0; //mix(color0, color1, norm.y); vec3 lightDir = normalize(lightPos - FragPos); float diff = max(dot(norm, lightDir), 0.0); diff --git a/Map3DRendering/Window.cs b/Map3DRendering/Window.cs index 8040ec4..8958671 100644 --- a/Map3DRendering/Window.cs +++ b/Map3DRendering/Window.cs @@ -16,7 +16,6 @@ namespace Map3DRendering { private Shader _shader; private Texture _texture; - private Texture _texture2; private Camera _camera; @@ -55,20 +54,13 @@ namespace Map3DRendering { mapRender.OnLoad(_shader); - _texture = Texture.LoadFromFile("terrains/0.jpg"); + var file = Directory.EnumerateFiles(@"./terrains"); + + _texture = Texture.LoadFromArray(file.ToArray()); // Texture units are explained in Texture.cs, at the Use function. // First texture goes in texture unit 0. - _texture.Use(TextureUnit.Texture0); + _texture.UseArray(TextureUnit.Texture0); - // This is helpful because System.Drawing reads the pixels differently than OpenGL expects. - _texture2 = Texture.LoadFromFile("terrains/1.jpg"); - // Then, the second goes in texture unit 1. - _texture2.Use(TextureUnit.Texture1); - - // Next, we must setup the samplers in the shaders to use the right textures. - // The int we send to the uniform indicates which texture unit the sampler should use. - _shader.SetInt("texture0", 0); - _shader.SetInt("texture1", 1); axesGizmo = new AxesGizmo(); @@ -87,8 +79,7 @@ namespace Map3DRendering { GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - _texture.Use(TextureUnit.Texture0); - _texture2.Use(TextureUnit.Texture1); + _texture.UseArray(TextureUnit.Texture0); _shader.Use(); _shader.SetMatrix4("view", _camera.GetViewMatrix());