From 0b0d2360d6837adf97bde75fb6d7019acf720fd2 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 1 Feb 2024 20:06:53 +0100 Subject: [PATCH] slightly improved sphere generation --- Nebulix/Rendering/Mesh.cs | 33 +++++++++++++++++---------------- src/Shaders/Sphere/sphere.frag | 2 +- src/Sphere.cs | 29 ++++++++++++++++++++--------- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/Nebulix/Rendering/Mesh.cs b/Nebulix/Rendering/Mesh.cs index 66f22e1..4af35d7 100644 --- a/Nebulix/Rendering/Mesh.cs +++ b/Nebulix/Rendering/Mesh.cs @@ -24,24 +24,26 @@ namespace Nebulix.Rendering public void CalculateNormals() { - // normals = new Vector3D[vertices.Length]; - // for (int j = 0; j < vertices.Length; j++) - // { - // normals[j] = Vector3D.Zero; - // } - - // return; for (int i = 0; i < indices.Length; i += 3) { - Vector3D a = vertices[indices[i]]; - Vector3D b = vertices[indices[i + 1]]; - Vector3D c = vertices[indices[i + 2]]; + uint i0 = indices[i]; + uint i1 = indices[i+1]; + uint i2 = indices[i+2]; + Vector3D v0 = vertices[i0]; + Vector3D v1 = vertices[i1]; + Vector3D v2 = vertices[i2]; - Vector3D normal = Vector3D.Cross(b-a, c-a); + Vector3D normal = Vector3D.Cross(v1-v0, v2-v0); + // Commenting this out, will result in the normals being weighted based on the triangle area normal = Vector3D.Normalize(normal); - normals[indices[i]] = normal; - normals[indices[i + 1]] = normal; - normals[indices[i + 2]] = normal; + normals[i0] += normal; + normals[i1] += normal; + normals[i2] += normal; + } + + for (int i = 0; i < normals.Length; i++) + { + normals[i] = Vector3D.Normalize(normals[i]); // smoothing for shared vertices } } @@ -84,8 +86,7 @@ namespace Nebulix.Rendering meshData[insert + 5] = normals[i].Z; insert += 6; } - // extractedVertices.CopyTo(meshData, 0); - // extractedNormals.CopyTo(meshData, extractedVertices.Length); + gl.BindBuffer(BufferTargetARB.ArrayBuffer, vbo); fixed(void* data = &meshData[0]) { diff --git a/src/Shaders/Sphere/sphere.frag b/src/Shaders/Sphere/sphere.frag index 7e7f075..abe6fb4 100644 --- a/src/Shaders/Sphere/sphere.frag +++ b/src/Shaders/Sphere/sphere.frag @@ -57,7 +57,7 @@ vec3 CalculatePointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewD vec3 ambientLight = light.ambient * attenuation;// * texture(material.diffuseMap, TexCoords).rgb; vec3 diffuseLight = light.diffuse * diff * attenuation;// * texture(material.diffuseMap, TexCoords).rgb; - vec3 specularLight = light.specular * spec * attenuation;// * texture(material.specularMap, TexCoords).rgb; + vec3 specularLight = vec3(0);//light.specular * spec * attenuation;// * texture(material.specularMap, TexCoords).rgb; return ambientLight + diffuseLight + specularLight; } diff --git a/src/Sphere.cs b/src/Sphere.cs index b7ecc91..d03b055 100644 --- a/src/Sphere.cs +++ b/src/Sphere.cs @@ -8,7 +8,7 @@ namespace Engine_silk.NET // also maybe make an ISphere and call this class "CubeSphere"? public class Sphere { - private readonly Face[] sphereFaces = new Face[6]; + private readonly Mesh mesh = new(); private readonly uint resolution; public Sphere(uint resolution) @@ -21,6 +21,7 @@ namespace Engine_silk.NET public void CreateSphere() { + // TODO: merge the individual meshes to one mesh Vector3D[] directions = [ Vector3D.UnitZ, -Vector3D.UnitZ, @@ -28,11 +29,25 @@ namespace Engine_silk.NET Vector3D.UnitX, -Vector3D.UnitX ]; - for (int i = 0; i < sphereFaces.Length; i++) + List> vertices = new(); + List indices = new(); + for (int i = 0; i < directions.Length; i++) { - sphereFaces[i] = new Face(directions[i], new Mesh(), resolution); - sphereFaces[i].GenerateMesh(); + Mesh m = new(); + Face f = new(directions[i], m, resolution); + f.GenerateMesh(); + + vertices.AddRange(m.Vertices); + for (int j = 0; j < m.Indices.Length; j++) + { + indices.Add(m.Indices[j] + (uint)(m.Vertices.Length * i)); + } } + // TODO get rid of overlapping vertices maybe + mesh.Clear(); + mesh.Vertices = vertices.ToArray(); + mesh.Indices = indices.ToArray(); + mesh.CalculateNormals(); } /// @@ -40,11 +55,7 @@ namespace Engine_silk.NET /// public void RenderSphere(GL gl) // Will not be needed { - // Use default shader etc. to render the sphere - for (int i = 0; i < 6; i++) - { - sphereFaces[i].Mesh.Render(gl); - } + mesh.Render(gl); } }