summary refs log tree commit diff
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-10-23 02:48:51 +0200
committerMel <einebeere@gmail.com>2022-10-23 02:48:51 +0200
commit75a9c87b50cef2f1d749bd9042a9348bc28b4c09 (patch)
tree8d82f3cbbb5bdc63c7e5b6431dac3d49b23a478d
parent589bfb5cad0052856077ce867f3858ca3741d95d (diff)
downloadmeowcraft-75a9c87b50cef2f1d749bd9042a9348bc28b4c09.tar.zst
meowcraft-75a9c87b50cef2f1d749bd9042a9348bc28b4c09.zip
Sun lighting
-rw-r--r--assets/shaders/fragment.glsl8
-rw-r--r--assets/shaders/vertex.glsl6
-rw-r--r--src/GFX/Binder.cpp5
-rw-r--r--src/GFX/Mesh.cpp8
-rw-r--r--src/GFX/Mesh.hpp27
-rw-r--r--src/World/Chunk.cpp19
-rw-r--r--src/World/Chunk.hpp1
-rw-r--r--src/main.cpp5
8 files changed, 69 insertions, 10 deletions
diff --git a/assets/shaders/fragment.glsl b/assets/shaders/fragment.glsl
index f8e9e46..eca50d9 100644
--- a/assets/shaders/fragment.glsl
+++ b/assets/shaders/fragment.glsl
@@ -1,11 +1,17 @@
 #version 330 core
 
 uniform sampler2D tex;
+uniform vec3 sun_direction;
 
+in vec3 surface_normal;
 in vec2 frag_tex_coord;
 
 out vec4 color;
 
 void main() {
-    color = texture(tex, frag_tex_coord);
+    float brightness = dot(normalize(surface_normal), normalize(-sun_direction));
+    vec3 diffuse = vec3(max(brightness, 0.3));
+
+    color = vec4(diffuse, 1.0) * texture(tex, frag_tex_coord);
+    // color = texture(tex, frag_tex_coord);
 }
\ No newline at end of file
diff --git a/assets/shaders/vertex.glsl b/assets/shaders/vertex.glsl
index 1ad43f4..c59d6cd 100644
--- a/assets/shaders/vertex.glsl
+++ b/assets/shaders/vertex.glsl
@@ -5,11 +5,15 @@ uniform mat4 view_matrix;
 uniform mat4 projection_matrix;
 
 layout (location = 0) in vec3 position;
-layout (location = 1) in vec2 tex_coord;
+layout (location = 1) in vec3 normal;
+layout (location = 2) in vec2 tex_coord;
 
 out vec2 frag_tex_coord;
+out vec3 surface_normal;
 
 void main() {
     gl_Position = projection_matrix * view_matrix * model_matrix * vec4(position, 1.0);
     frag_tex_coord = tex_coord;
+
+    surface_normal = (model_matrix * vec4(normal, 0.0)).xyz;
 }
\ No newline at end of file
diff --git a/src/GFX/Binder.cpp b/src/GFX/Binder.cpp
index e7b7e4c..70d045c 100644
--- a/src/GFX/Binder.cpp
+++ b/src/GFX/Binder.cpp
@@ -10,7 +10,8 @@ BindableMesh Binder::load(Mesh& mesh) {
         store_indices(mesh.raw_indices(), mesh.indices_size());
     }
     store_in_attribute_list(0, 3, mesh.raw(), mesh.size() * 3);
-    store_in_attribute_list(1, 2, mesh.raw_tex_coords(), mesh.tex_coords_size() * 2);
+    store_in_attribute_list(1, 3, mesh.raw_normals(), mesh.normals_size() * 3);
+    store_in_attribute_list(2, 2, mesh.raw_tex_coords(), mesh.tex_coords_size() * 2);
     unbind_vao();
 
     return {vao, mesh.indices_size()};
@@ -50,12 +51,14 @@ void BindableMesh::bind() const {
     glBindVertexArray(m_vao);
     glEnableVertexAttribArray(0);
     glEnableVertexAttribArray(1);
+    glEnableVertexAttribArray(2);
 }
 
 void BindableMesh::unbind() {
     glBindVertexArray(0);
     glDisableVertexAttribArray(0);
     glDisableVertexAttribArray(1);
+    glDisableVertexAttribArray(2);
 }
 
 size_t BindableMesh::size() const {
diff --git a/src/GFX/Mesh.cpp b/src/GFX/Mesh.cpp
index 12f8aaa..1bac9f1 100644
--- a/src/GFX/Mesh.cpp
+++ b/src/GFX/Mesh.cpp
@@ -10,6 +10,14 @@ size_t Mesh::size() {
     return m_positions.size();
 }
 
+float* Mesh::raw_normals() {
+    return (float*) m_normals.data();
+}
+
+size_t Mesh::normals_size() {
+    return m_normals.size();
+}
+
 uint32_t* Mesh::raw_indices() {
     return m_indices.data();
 }
diff --git a/src/GFX/Mesh.hpp b/src/GFX/Mesh.hpp
index f027c8c..c20b419 100644
--- a/src/GFX/Mesh.hpp
+++ b/src/GFX/Mesh.hpp
@@ -9,15 +9,31 @@ namespace MC::GFX {
 
 class Mesh {
 public:
-    Mesh(std::vector<Vector<3>> positions, std::vector<Vector<2>> tex_coords, std::vector<uint32_t> indices)
-        : m_positions(std::move(positions)), m_tex_coords(std::move(tex_coords)), m_indices(std::move(indices)) {};
-
-    Mesh(std::vector<Vector<3>> positions, std::vector<Vector<2>> tex_coords)
-        : m_positions(std::move(positions)), m_tex_coords(std::move(tex_coords)), m_indices() {};
+    Mesh(
+        std::vector<Vector<3>> positions,
+        std::vector<Vector<3>> normals,
+        std::vector<Vector<2>> tex_coords,
+        std::vector<uint32_t> indices
+    ) : m_positions(std::move(positions)),
+        m_normals(std::move(normals)),
+        m_tex_coords(std::move(tex_coords)),
+        m_indices(std::move(indices)) {};
+
+    Mesh(
+        std::vector<Vector<3>> positions,
+        std::vector<Vector<3>> normals,
+        std::vector<Vector<2>> tex_coords
+    ) : m_positions(std::move(positions)),
+        m_normals(std::move(normals)),
+        m_tex_coords(std::move(tex_coords)),
+        m_indices() {};
 
     float* raw();
     size_t size();
 
+    float* raw_normals();
+    size_t normals_size();
+
     uint32_t* raw_indices();
     size_t indices_size();
 
@@ -26,6 +42,7 @@ public:
 
 private:
     std::vector<Vector<3>> m_positions;
+    std::vector<Vector<3>> m_normals;
     std::vector<Vector<2>> m_tex_coords;
     std::vector<uint32_t> m_indices;
 
diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp
index d02e5e5..ee408ae 100644
--- a/src/World/Chunk.cpp
+++ b/src/World/Chunk.cpp
@@ -9,6 +9,7 @@ void Chunk::set(uint32_t x, uint32_t y, uint32_t z, BlockType type) {
 
 GFX::Mesh Chunk::mesh() {
     std::vector<Vector<3>> positions{};
+    std::vector<Vector<3>> normals{};
     std::vector<Vector<2>> tex_coords{};
     std::vector<uint32_t> indices{};
 
@@ -25,8 +26,9 @@ GFX::Mesh Chunk::mesh() {
                         continue;
                     }
 
-                    auto side_tex_coords = Chunk::face_tex_coords(type, side);
                     auto side_positions = side.face();
+                    auto side_normals = Chunk::face_normals(side);
+                    auto side_tex_coords = Chunk::face_tex_coords(type, side);
 
                     for (auto& position : side_positions) {
                         position = position + Vector<3>{static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)};
@@ -35,6 +37,7 @@ GFX::Mesh Chunk::mesh() {
                     uint32_t s = positions.size();
 
                     positions.insert(positions.end(), side_positions.begin(), side_positions.end());
+                    normals.insert(normals.end(), side_normals.begin(), side_normals.end());
                     tex_coords.insert(tex_coords.end(), side_tex_coords.begin(), side_tex_coords.end());
                     indices.insert(indices.end(), {s, s + 1, s + 3, s + 1, s + 2, s + 3});
                 }
@@ -42,7 +45,7 @@ GFX::Mesh Chunk::mesh() {
         }
     }
 
-    return {positions, tex_coords, indices};
+    return {positions, normals, tex_coords, indices};
 }
 
 Vector<3> Chunk::position() {
@@ -121,4 +124,16 @@ std::array<Vector<2>, 4> Chunk::face_tex_coords(BlockType type, BlockSide side)
     }
 }
 
+std::array<Vector<3>, 4> Chunk::face_normals(BlockSide side) {
+    auto is_side = [=](BlockSide s) -> float { return s == side; };
+
+    Vector<3> normal = {
+            is_side(BlockSide::Right) - is_side(BlockSide::Left),
+            is_side(BlockSide::Top) - is_side(BlockSide::Bottom),
+            is_side(BlockSide::Front) - is_side(BlockSide::Back),
+    };
+
+    return {normal, normal, normal, normal};
+}
+
 }
diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp
index 4c7810d..7415d7c 100644
--- a/src/World/Chunk.hpp
+++ b/src/World/Chunk.hpp
@@ -25,6 +25,7 @@ private:
     bool is_face_visible(uint32_t x, uint32_t y, uint32_t z, BlockSide side);
 
     static std::array<Vector<2>, 4> face_tex_coords(BlockType type, BlockSide side);
+    static std::array<Vector<3>, 4> face_normals(BlockSide side);
 
     struct BlockData {
         BlockType type;
diff --git a/src/main.cpp b/src/main.cpp
index 5d5af2f..40034e2 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -66,10 +66,15 @@ void run() {
     auto view_uniform = program.uniform("view_matrix");
     auto projection_uniform = program.uniform("projection_matrix");
 
+    auto sun_direction_uniform = program.uniform("sun_direction");
+
     program.bind();
     auto projection = Math::MVP::projection(ASPECT, FOV, 0.1f, 1000.0f);
     projection_uniform.set(projection);
 
+    Vector<3> sun_direction{1.0f, -1.0f, 0.0f};
+    sun_direction_uniform.set(sun_direction);
+
     glEnable(GL_DEPTH_TEST);
     glDepthFunc(GL_LEQUAL);