Browse Source

turned vector into a template

Kajetan Johannes Hammerle 3 years ago
parent
commit
237e1993c9

+ 50 - 52
client/Game.cpp

@@ -15,19 +15,20 @@ pointIndex(0), moveSpeed(0.125f), movedLength(0.0f), mode(Mode::AUTO) {
     float mid = World::WORLD_SIZE * 0.5f;
     float randLength = World::WORLD_SIZE * 0.125f * 0.25f;
     pos.set(0, h, 0);
-    lastPos.set(pos);
+    lastPos = pos;
 
-    rotation = Quaternion(Vector(1, 0, 0), -80);
+    rotation = Quaternion(Vector3(1, 0, 0), -80);
     lastRotation = rotation;
 
     Quaternion q;
     for(uint i = 0; i < cameraPoints.getCapacity(); i++) {
-        Vector offset(mid, h, mid);
-        offset.add(Vector(r.nextFloat(randLength), r.nextFloat(randLength), r.nextFloat(randLength)));
-        Vector v;
-        v.setAngles(i * 360.0f / cameraPoints.getCapacity(), 0.0f).mul(mid * 0.5f).add(offset);
+        Vector3 offset(mid, h, mid);
+        offset += Vector3(r.nextFloat(randLength), r.nextFloat(randLength), r.nextFloat(randLength));
+        Vector3 v(i * 360.0f / cameraPoints.getCapacity(), 0.0f);
+        v *= mid * 0.5f;
+        v += offset;
 
-        q.mul(Quaternion(Vector(r.nextFloat() * 360.0f, r.nextFloat() * -90.0f), -10.0f));
+        q.mul(Quaternion(Vector3(r.nextFloat() * 360.0f, r.nextFloat() * -90.0f), -10.0f));
         cameraPoints.add({v, q, 0.0f});
     }
     updateDistances();
@@ -37,33 +38,29 @@ void Game::tick() {
     lastRotation = rotation;
     lastPos = pos;
     if(mode == Mode::PLAYER) {
-        Vector right(1.0f, 0.0f, 0.0f);
-        Vector up(0.0f, 1.0f, 0.0f);
-        Vector back(0.0f, 0.0f, -1.0f);
-
         Matrix m = rotation.toMatrix();
-        right.mul(m);
-        up.mul(m);
-        back.mul(m);
+        Vector3 right = m * Vector3(1.0f, 0.0f, 0.0f);
+        Vector3 up = m * Vector3(0.0f, 1.0f, 0.0f);
+        Vector3 back = m * Vector3(0.0f, 0.0f, -1.0f);
 
         const float speed = 1.0f;
         if(control.keys.down.isDown()) {
-            pos.addMul(back, speed);
+            pos += back * speed;
         }
         if(control.keys.up.isDown()) {
-            pos.addMul(back, -speed);
+            pos -= back * speed;
         }
         if(control.keys.left.isDown()) {
-            pos.addMul(right, -speed);
+            pos -= right * speed;
         }
         if(control.keys.right.isDown()) {
-            pos.addMul(right, speed);
+            pos += right * speed;
         }
         if(control.keys.jump.isDown()) {
-            pos.addMul(up, speed);
+            pos += up * speed;
         }
         if(control.keys.sneak.isDown()) {
-            pos.addMul(up, -speed);
+            pos -= up * speed;
         }
 
         const float rotationSpeed = 5.0f;
@@ -130,7 +127,7 @@ void Game::renderWorld(float lag, Renderer& renderer) const {
             index = (index + 1) % cameraPoints.getLength();
         }
         float t = leftLength / cameraPoints[index].distance;
-        Vector interpolatedPos = pointUntilDistance(leftLength, index, 4000);
+        Vector3 interpolatedPos = pointUntilDistance(leftLength, index, 4000);
 
         uint a = index == 0 ? cameraPoints.getLength() - 1 : index - 1;
         uint b = (a + 1) % cameraPoints.getLength();
@@ -140,8 +137,7 @@ void Game::renderWorld(float lag, Renderer& renderer) const {
         renderer.update(interpolatedPos, cameraPoints[b].q.squad(t, cameraPoints[a].q, cameraPoints[c].q, cameraPoints[d].q));
         pos = interpolatedPos;
     } else if(mode == Mode::PLAYER) {
-        Vector v(lastPos);
-        v.addMul(pos, lag).addMul(lastPos, -lag);
+        Vector3 v = lastPos + (pos - lastPos) * lag;
         renderer.update(v, lastRotation.slerp(lag, rotation));
     }
     worldRenderer.render(lag, renderer);
@@ -154,11 +150,12 @@ void Game::renderTextOverlay(float lag, Renderer& renderer, FontRenderer& fr) co
     String s;
     fr.drawString(10, 10, s.append("FPS: ").append(fps.getUpdatesPerSecond()).append(" TPS: ").append(tps.getUpdatesPerSecond()));
     fr.drawString(10, 19, s.clear().append("Speed: ").append(moveSpeed));
-    pos.toString(s.clear());
+    s.clear();
+    s += pos;
     fr.drawString(10, 28, s);
     for(uint i = 0; i < cameraPoints.getLength(); i++) {
         s.clear().append(i + 1).append(": ");
-        cameraPoints[i].pos.toString(s);
+        s += cameraPoints[i].pos;
         fr.drawString(10, i * 9 + 37, s);
     }
 }
@@ -167,51 +164,52 @@ bool Game::isRunning() const {
     return true;
 }
 
-Vector Game::splineTangent(const Vector& prev, const Vector& current, const Vector& next) const {
-    Vector v(current);
-    v.sub(prev).mul(0.5f).addMul(next, 0.5f).addMul(current, -0.5f);
-    return v;
+Vector3 Game::splineTangent(const Vector3& prev, const Vector3& current, const Vector3& next) const {
+    (void) current;
+    //Vector3 v(current);
+    //v.sub(prev).mul(0.5f).addMul(next, 0.5f).addMul(current, -0.5f);
+    return (next - prev) * 0.5f;
 }
 
-Vector Game::interpolate(const Vector& a, const Vector& b, const Vector& tanA, const Vector& tanB, float t) const {
+Vector3 Game::interpolate(const Vector3& a, const Vector3& b, const Vector3& tanA, const Vector3& tanB, float t) const {
     float t2 = t * t;
     float t3 = t2 * t;
-    Vector v;
-    v.addMul(a, 2.0f * t3 - 3.0f * t2 + 1.0f).addMul(b, -2.0f * t3 + 3.0f * t2)
-            .addMul(tanA, t3 - 2.0f * t2 + t).addMul(tanB, t3 - t2);
-    return v;
+    return a * (2.0f * t3 - 3.0f * t2 + 1.0f) + 
+            b * (-2.0f * t3 + 3.0f * t2) + 
+            tanA * (t3 - 2.0f * t2 + t) + 
+            tanB * (t3 - t2);
 }
 
 float Game::distance(uint index, uint splits) const {
-    Vector a;
-    Vector b;
-    Vector tanA;
-    Vector tanB;
+    Vector3 a;
+    Vector3 b;
+    Vector3 tanA;
+    Vector3 tanB;
     getPointsAndTangents(index, a, b, tanA, tanB);
 
-    Vector currentPos;
-    Vector currentNext = interpolate(a, b, tanA, tanB, 0.0f);
+    Vector3 currentPos;
+    Vector3 currentNext = interpolate(a, b, tanA, tanB, 0.0f);
 
     float sum = 0.0f;
     for(uint i = 0; i <= splits; i++) {
         currentPos = currentNext;
         float t = (i + 1.0f) / (splits + 1.0f);
         currentNext = interpolate(a, b, tanA, tanB, t);
-        float l = currentPos.sub(currentNext).length();
+        float l = static_cast<Vector3>(currentPos - currentNext).length();
         sum += l;
     }
     return sum;
 }
 
-Vector Game::pointUntilDistance(float leftDistance, uint index, uint splits) const {
-    Vector a;
-    Vector b;
-    Vector tanA;
-    Vector tanB;
+Vector3 Game::pointUntilDistance(float leftDistance, uint index, uint splits) const {
+    Vector3 a;
+    Vector3 b;
+    Vector3 tanA;
+    Vector3 tanB;
     getPointsAndTangents(index, a, b, tanA, tanB);
 
-    Vector currentPos;
-    Vector currentNext = interpolate(a, b, tanA, tanB, 0.0f);
+    Vector3 currentPos;
+    Vector3 currentNext = interpolate(a, b, tanA, tanB, 0.0f);
 
     float sum = 0.0f;
     uint i = 0;
@@ -219,21 +217,21 @@ Vector Game::pointUntilDistance(float leftDistance, uint index, uint splits) con
         currentPos = currentNext;
         float t = (i + 1.0f) / (splits + 1.0f);
         currentNext = interpolate(a, b, tanA, tanB, t);
-        float l = currentPos.sub(currentNext).length();
+        float l = static_cast<Vector3>(currentPos - currentNext).length();
         sum += l;
         i++;
     }
     return currentNext;
 }
 
-void Game::getPointsAndTangents(uint index, Vector& a, Vector& b, Vector& tanA, Vector& tanB) const {
+void Game::getPointsAndTangents(uint index, Vector3& a, Vector3& b, Vector3& tanA, Vector3& tanB) const {
     uint prev = index == 0 ? cameraPoints.getLength() - 1 : index - 1;
     uint currentA = (prev + 1) % cameraPoints.getLength();
     uint currentB = (prev + 2) % cameraPoints.getLength();
     uint next = (prev + 3) % cameraPoints.getLength();
 
-    a.set(cameraPoints[currentA].pos);
-    b.set(cameraPoints[currentB].pos);
+    a = cameraPoints[currentA].pos;
+    b = cameraPoints[currentB].pos;
 
     tanA = splineTangent(cameraPoints[prev].pos, a, b);
     tanB = splineTangent(a, b, cameraPoints[next].pos);

+ 7 - 7
client/Game.h

@@ -23,11 +23,11 @@ public:
     bool isRunning() const;
 
 private:
-    Vector splineTangent(const Vector& prev, const Vector& current, const Vector& next) const;
-    Vector interpolate(const Vector& a, const Vector& b, const Vector& tanA, const Vector& tanB, float t) const;
+    Vector3 splineTangent(const Vector3& prev, const Vector3& current, const Vector3& next) const;
+    Vector3 interpolate(const Vector3& a, const Vector3& b, const Vector3& tanA, const Vector3& tanB, float t) const;
     float distance(uint index, uint splits) const;
-    Vector pointUntilDistance(float leftDistance, uint index, uint splits) const;
-    void getPointsAndTangents(uint index, Vector& a, Vector& b, Vector& tanA, Vector& tanB) const;
+    Vector3 pointUntilDistance(float leftDistance, uint index, uint splits) const;
+    void getPointsAndTangents(uint index, Vector3& a, Vector3& b, Vector3& tanA, Vector3& tanB) const;
     void updateDistances();
     
     const Control& control;
@@ -35,8 +35,8 @@ private:
     const Clock& tps;
     RenderSettings& renderSettings;
 
-    Vector lastPos;
-    mutable Vector pos;
+    Vector3 lastPos;
+    mutable Vector3 pos;
     Quaternion lastRotation;
     Quaternion rotation;
 
@@ -46,7 +46,7 @@ private:
     WorldRenderer worldRenderer;
 
     struct Point {
-        Vector pos;
+        Vector3 pos;
         Quaternion q;
         float distance;
     };

+ 8 - 18
client/math/Plane.cpp

@@ -1,26 +1,16 @@
 #include "client/math/Plane.h"
 
-Plane::Plane() : a(0), b(0), c(0), d(0) {
+Plane::Plane() : d(0) {
 }
 
-void Plane::set(const Vector& va, const Vector& vb, const Vector& vc) {
-    Vector h1 = vb;
-    h1.sub(va);
-    Vector h2 = vc;
-    h2.sub(va);
-    h1.cross(h2);
-    h1.normalize();
-
-    a = h1.getX();
-    b = h1.getY();
-    c = h1.getZ();
+void Plane::set(const Vector3& va, const Vector3& vb, const Vector3& vc) {
+    Vector3 h1 = vb - va;
+    Vector3 h2 = vc - va;
+    abc = h1.cross(h2);
+    abc.normalize();
     d = -h1.dot(va);
 }
 
-float Plane::getSignedDistance(float x, float y, float z) const {
-    return x * a + y * b + z * c + d;
-}
-
-float Plane::getSignedDistance(const Vector& v) const {
-    return getSignedDistance(v.getX(), v.getY(), v.getZ());
+float Plane::getSignedDistance(const Vector3& v) const {
+    return abc.dot(v) + d;
 }

+ 3 - 6
client/math/Plane.h

@@ -7,14 +7,11 @@ class Plane final {
 public:
     Plane();
 
-    void set(const Vector& va, const Vector& vb, const Vector& vc);
-    float getSignedDistance(float x, float y, float z) const;
-    float getSignedDistance(const Vector& v) const;
+    void set(const Vector3& va, const Vector3& vb, const Vector3& vc);
+    float getSignedDistance(const Vector3& v) const;
 
 private:
-    float a;
-    float b;
-    float c;
+    Vector3 abc;
     float d;
 };
 

+ 19 - 22
client/math/Quaternion.cpp

@@ -1,5 +1,4 @@
 #include <cmath>
-#include <iostream>
 
 #include "client/math/Quaternion.h"
 
@@ -9,12 +8,11 @@ Quaternion::Quaternion() : xyz(0.0f, 0.0f, 0.0f), w(1.0f) {
 Quaternion::Quaternion(float x, float y, float z, float w) : xyz(x, y, z), w(w) {
 }
 
-Quaternion::Quaternion(const Vector& axis, float angle) {
-    Vector unit(axis);
-    xyz.set(unit.normalize());
+Quaternion::Quaternion(const Vector3& axis, float angle) : xyz(axis) {
+    xyz.normalize();
     float sin;
     sincosf(angle * (M_PI / 360.0f), &sin, &w);
-    xyz.mul(sin);
+    xyz *= sin;
 }
 
 Quaternion Quaternion::lerp(float f, const Quaternion& other) const {
@@ -34,13 +32,12 @@ Quaternion Quaternion::slerp(float f, const Quaternion& other) const {
 }
 
 Quaternion Quaternion::interpolate(float a, float b, const Quaternion& other) const {
-    Vector interpolated(xyz);
-    interpolated.mul(a).addMul(other.xyz, b);
-    return Quaternion(interpolated.getX(), interpolated.getY(), interpolated.getZ(), w * a + other.w * b);
+    Vector3 interpolated = xyz * a + other.xyz * b;
+    return Quaternion(interpolated[0], interpolated[1], interpolated[2], w * a + other.w * b);
 }
 
 Quaternion Quaternion::squad(float f, const Quaternion& prev, const Quaternion& next, const Quaternion& nextNext) const {
-    float diff = Vector(xyz).sub(next.xyz).squareLength() + (w - next.w) * (w - next.w);
+    float diff = static_cast<Vector3>(xyz - next.xyz).squareLength() + (w - next.w) * (w - next.w);
     if(diff < 0.0001f) {
         return *this;
     }
@@ -58,16 +55,16 @@ Quaternion Quaternion::squadControl(const Quaternion& prev, const Quaternion& ne
 }
 
 Quaternion& Quaternion::normalize() {
-    float f = 1.0f / sqrtf(xyz.dot(xyz) + w * w);
-    xyz.mul(f);
+    float f = 1.0f / sqrtf(xyz.squareLength() + w * w);
+    xyz *= f;
     w *= f;
     return *this;
 }
 
 Matrix Quaternion::toMatrix() const {
-    float x = xyz.getX();
-    float y = xyz.getY();
-    float z = xyz.getZ();
+    float x = xyz[0];
+    float y = xyz[1];
+    float z = xyz[2];
 
     float x2 = 2 * x * x;
     float y2 = 2 * y * y;
@@ -88,27 +85,26 @@ Matrix Quaternion::toMatrix() const {
 }
 
 Quaternion& Quaternion::mul(const Quaternion& other) {
-    Vector v;
-    v.addMul(other.xyz, w).addMul(xyz, other.w).add(Vector(xyz).cross(other.xyz));
+    Vector3 v = other.xyz * w + xyz * other.w + xyz.cross(other.xyz);
     w = w * other.w - xyz.dot(other.xyz);
-    xyz.set(v);
+    xyz = v;
     return *this;
 }
 
 Quaternion& Quaternion::mul(float f) {
-    xyz.mul(f);
+    xyz *= f;
     w *= f;
     return *this;
 }
 
 Quaternion& Quaternion::add(const Quaternion& other) {
-    xyz.add(other.xyz);
+    xyz += other.xyz;
     w += other.w;
     return *this;
 }
 
 Quaternion& Quaternion::conjugate() {
-    xyz.setInverse(xyz);
+    xyz = -xyz;
     return *this;
 }
 
@@ -120,7 +116,8 @@ Quaternion& Quaternion::log() {
     //xyz.mul(arccos / xyz.length());
 
     // optimized use case log
-    xyz.normalize().mul(acos(w));
+    xyz.normalize();
+    xyz *= acos(w);
     w = 0.0f;
     return *this;
 }
@@ -135,6 +132,6 @@ Quaternion& Quaternion::exp() {
     // optimized use case exp
     float length = xyz.length();
     w = cosf(length);
-    xyz.mul((sin(length)) / length);
+    xyz *= sinf(length) / length;
     return *this;
 }

+ 2 - 2
client/math/Quaternion.h

@@ -7,7 +7,7 @@
 class Quaternion {
 public:
     Quaternion();
-    Quaternion(const Vector& axis, float angle);
+    Quaternion(const Vector3& axis, float angle);
     
     Quaternion lerp(float f, const Quaternion& other) const;
     Quaternion slerp(float f, const Quaternion& other) const;
@@ -30,7 +30,7 @@ private:
     Quaternion& mul(float f);
     Quaternion& add(const Quaternion& other);
     
-    Vector xyz;
+    Vector3 xyz;
     float w;
 };
 

+ 37 - 131
client/math/Vector.cpp

@@ -1,149 +1,55 @@
-#include <cmath>
-
 #include "client/math/Vector.h"
 
-Vector::Vector() : x(0), y(0), z(0) {
-}
-
-Vector::Vector(float ix, float iy, float iz) : x(ix), y(iy), z(iz) {
-}
-
-Vector::Vector(float lengthAngle, float widthAngle) {
-    setAngles(lengthAngle, widthAngle);
-}
-
-float Vector::getX() const {
-    return x;
-}
-
-float Vector::getY() const {
-    return y;
-}
-
-float Vector::getZ() const {
-    return z;
-}
-
-Vector& Vector::setX(float ix) {
-    x = ix;
-    return *this;
-}
-
-Vector& Vector::setY(float iy) {
-    y = iy;
-    return *this;
-}
-
-Vector& Vector::setZ(float iz) {
-    z = iz;
-    return *this;
-}
-
-Vector& Vector::set(const Vector& v) {
-    return set(v.x, v.y, v.z);
-}
-
-Vector& Vector::set(float ix, float iy, float iz) {
-    x = ix;
-    y = iy;
-    z = iz;
-    return *this;
-}
-
-Vector& Vector::setInverse(const Vector& v) {
-    x = -v.x;
-    y = -v.y;
-    z = -v.z;
-    return *this;
+template<>
+Vector<3>::Vector(float x, float y, float z) {
+    values[0] = x;
+    values[1] = y;
+    values[2] = z;
 }
 
-Vector& Vector::setMul(const Vector& v, float f) {
-    x = v.x * f;
-    y = v.y * f;
-    z = v.z * f;
-    return *this;
+template<>
+Vector<2>::Vector(float x, float y) {
+    values[0] = x;
+    values[1] = y;
 }
 
-Vector& Vector::setAngles(float lengthAngle, float widthAngle) {
-    lengthAngle = lengthAngle * (M_PI / 180.0f);
-    widthAngle = widthAngle * (M_PI / 180.0f);
-    x = cosf(widthAngle) * sinf(lengthAngle);
-    y = sinf(widthAngle);
-    z = cosf(widthAngle) * cosf(lengthAngle);
+template<>
+Vector<3>& Vector<3>::setAngles(float lengthAngle, float widthAngle) {
+    lengthAngle *= (M_PI / 180.0f);
+    widthAngle *= (M_PI / 180.0f);
+    values[0] = cosf(widthAngle) * sinf(lengthAngle);
+    values[1] = sinf(widthAngle);
+    values[2] = cosf(widthAngle) * cosf(lengthAngle);
     return *this;
 }
 
-Vector& Vector::add(const Vector& v) {
-    x += v.x;
-    y += v.y;
-    z += v.z;
-    return *this;
+template<>
+Vector<3>::Vector(float lengthAngle, float widthAngle) {
+    setAngles(lengthAngle, widthAngle);
 }
 
-Vector& Vector::sub(const Vector& v) {
-    x -= v.x;
-    y -= v.y;
-    z -= v.z;
+template<>
+Vector<3>& Vector<3>::set(float x, float y, float z) {
+    values[0] = x;
+    values[1] = y;
+    values[2] = z;
     return *this;
 }
 
-Vector& Vector::mul(float f) {
-    x *= f;
-    y *= f;
-    z *= f;
-    return *this;
+template<>
+Vector<3> Vector<3>::cross(const Vector<3>& other) const {
+    return Vector<3>(
+            values[1] * other.values[2] - values[2] * other.values[1],
+            values[2] * other.values[0] - values[0] * other.values[2],
+            values[0] * other.values[1] - values[1] * other.values[0]);
 }
 
-Vector& Vector::mul(const Matrix& m) {
+Vector<3> operator*(const Matrix& m, const Vector<3>& v) {
     const float* d = m.getValues();
-    const float w = 1.0f;
-    float nx = x * d[0] + y * d[4] + z * d[8] + w * d[12];
-    float ny = x * d[1] + y * d[5] + z * d[9] + w * d[13];
-    float nz = x * d[2] + y * d[6] + z * d[10] + w * d[14];
-    float nw = x * d[3] + y * d[7] + z * d[11] + w * d[15];
-    set(nx / nw, ny / nw, nz / nw);
-    return *this;
-}
-
-Vector& Vector::addMul(const Vector& v, float f) {
-    x += v.x * f;
-    y += v.y * f;
-    z += v.z * f;
-    return *this;
-}
-
-Vector& Vector::cross(float ix, float iy, float iz) {
-    return set(y * iz - z * iy, z * ix - x * iz, x * iy - y * ix);
-}
-
-Vector& Vector::cross(const Vector& v) {
-    return set(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
-}
-
-Vector& Vector::normalize() {
-    float f = 1.0f / length();
-    x *= f;
-    y *= f;
-    z *= f;
-    return *this;
-}
-
-float Vector::squareLength() const {
-    return x * x + y * y + z * z;
-}
-
-float Vector::length() const {
-    return sqrtf(squareLength());
-}
-
-float Vector::dot(const Vector& v) const {
-    return x * v.x + y * v.y + z * v.z;
-}
-
-float Vector::dotInverse(const Vector& v) const {
-    return x * (-v.x) + y * (-v.y) + z * (-v.z);
-}
-
-void Vector::toString(String& s) const {
-    s.append("(x = ").append(x).append(", y = ").append(y).append(", z = ").append(z).append(")");
+    Vector<3> result(
+            v[0] * d[0] + v[1] * d[4] + v[2] * d[8] + d[12],
+            v[0] * d[1] + v[1] * d[5] + v[2] * d[9] + d[13],
+            v[0] * d[2] + v[1] * d[6] + v[2] * d[10] + d[14]);
+    result *= 1.0f / (v[1] * d[3] + v[1] * d[7] + v[2] * d[11] + d[15]);
+    return result;
 }

+ 111 - 33
client/math/Vector.h

@@ -1,51 +1,129 @@
 #ifndef VECTOR_H
 #define VECTOR_H
 
+#include <cmath>
+
 #include "common/utils/String.h"
 #include "client/math/Matrix.h"
 
-class Vector final {
-public:
-    Vector();
-    Vector(float ix, float iy, float iz);
-    Vector(float lengthAngle, float widthAngle);
+template<uint N>
+struct Vector final {
+
+    Vector() {
+        for(uint i = 0; i < N; i++) {
+            values[i] = 0.0f;
+        }
+    }
+
+    Vector(float, float) = delete;
+    Vector(float, float, float) = delete;
+    Vector& set(float, float, float) = delete;
+    Vector& setAngles(float, float) = delete;
+    Vector cross(const Vector&) const = delete;
+
+    Vector& operator+=(const Vector& other) {
+        for(uint i = 0; i < N; i++) {
+            values[i] += other.values[i];
+        }
+        return *this;
+    }
+
+    Vector operator+(const Vector& other) const {
+        Vector v = *this;
+        v += other;
+        return v;
+    }
+
+    Vector& operator-=(const Vector& other) {
+        for(uint i = 0; i < N; i++) {
+            values[i] -= other.values[i];
+        }
+        return *this;
+    }
 
-    float getX() const;
-    float getY() const;
-    float getZ() const;
+    Vector operator-() const {
+        Vector v = *this;
+        for(uint i = 0; i < N; i++) {
+            v.values[i] = -v.values[i];
+        }
+        return v;
+    }
 
-    Vector& setX(float ix);
-    Vector& setY(float iy);
-    Vector& setZ(float iz);
+    Vector operator-(const Vector& other) const {
+        Vector v = *this;
+        v -= other;
+        return v;
+    }
 
-    Vector& set(const Vector& v);
-    Vector& set(float ix, float iy, float iz);
-    Vector& setInverse(const Vector& v);
-    Vector& setMul(const Vector& v, float f);
-    Vector& setAngles(float lengthAngle, float widthAngle);
+    Vector& operator*=(float factor) {
+        for(uint i = 0; i < N; i++) {
+            values[i] *= factor;
+        }
+        return *this;
+    }
 
-    Vector& add(const Vector& v);
-    Vector& sub(const Vector& v);
-    Vector& mul(float f);
-    Vector& mul(const Matrix& m);
-    Vector& addMul(const Vector& v, float f);
+    Vector operator*(float factor) const {
+        Vector v = *this;
+        v *= factor;
+        return v;
+    }
 
-    Vector& cross(float ix, float iy, float iz);
-    Vector& cross(const Vector& v);
+    float dot(const Vector& v) const {
+        float length = 0.0f;
+        for(uint i = 0; i < N; i++) {
+            length += values[i] * v.values[i];
+        }
+        return length;
+    }
 
-    Vector& normalize();
-    float squareLength() const;
-    float length() const;
+    float squareLength() const {
+        return dot(*this);
+    }
 
-    float dot(const Vector& v) const;
-    float dotInverse(const Vector& v) const;
-    
-    void toString(String& s) const;
+    float length() const {
+        return sqrtf(squareLength());
+    }
+
+    Vector& normalize() {
+        *this *= 1.0f / length();
+        return *this;
+    }
+
+    const float& operator[](uint index) const {
+        return values[index];
+    }
 
 private:
-    float x;
-    float y;
-    float z;
+    float values[N];
 };
 
+template<uint N>
+Vector<N> operator*(float factor, const Vector<N>& v) {
+    return v * factor;
+}
+
+template<> Vector<3>::Vector(float x, float y, float z);
+template<> Vector<2>::Vector(float x, float y);
+template<> Vector<3>& Vector<3>::setAngles(float lengthAngle, float widthAngle);
+template<> Vector<3>::Vector(float lengthAngle, float widthAngle);
+template<> Vector<3>& Vector<3>::set(float x, float y, float z);
+template<> Vector<3> Vector<3>::cross(const Vector<3>& other) const;
+Vector<3> operator*(const Matrix& m, const Vector<3>& v);
+
+template<uint N>
+String& operator+=(String& buffer, const Vector<N>& v) {
+    buffer.append('(');
+    if(N > 0) {
+        buffer.append(v[0]);
+    }
+    for(uint i = 1; i < N; i++) {
+        buffer.append(", ").append(v[i]);
+    }
+    buffer.append(')');
+    return buffer;
+}
+
+typedef Vector<3> Vector3;
+typedef Vector<2> Vector2;
+
 #endif

+ 17 - 17
client/rendering/Engine.cpp

@@ -135,21 +135,21 @@ void Engine::updateWorldView() {
         return;
     }
 
-    Vector right(0.939693f, 0.0f, -0.34202f);
-    Vector back(0.280166f, 0.573576f, 0.769751f);
-    Vector up(-0.196175f, 0.819152f, -0.538986f);
-    Vector center(16.0f, 24.0f, 24.0f);
-
-    worldShadowView.set(0, right.getX());
-    worldShadowView.set(1, up.getX());
-    worldShadowView.set(2, back.getX());
-    worldShadowView.set(4, right.getY());
-    worldShadowView.set(5, up.getY());
-    worldShadowView.set(6, back.getY());
-    worldShadowView.set(8, right.getZ());
-    worldShadowView.set(9, up.getZ());
-    worldShadowView.set(10, back.getZ());
-    worldShadowView.set(12, right.dotInverse(center));
-    worldShadowView.set(13, up.dotInverse(center));
-    worldShadowView.set(14, back.dotInverse(center));
+    Vector3 right(0.939693f, 0.0f, -0.34202f);
+    Vector3 back(0.280166f, 0.573576f, 0.769751f);
+    Vector3 up(-0.196175f, 0.819152f, -0.538986f);
+    Vector3 center(16.0f, 24.0f, 24.0f);
+
+    worldShadowView.set(0, right[0]);
+    worldShadowView.set(1, up[0]);
+    worldShadowView.set(2, back[0]);
+    worldShadowView.set(4, right[1]);
+    worldShadowView.set(5, up[1]);
+    worldShadowView.set(6, back[1]);
+    worldShadowView.set(8, right[2]);
+    worldShadowView.set(9, up[2]);
+    worldShadowView.set(10, back[2]);
+    worldShadowView.set(12, right.dot(-center));
+    worldShadowView.set(13, up.dot(-center));
+    worldShadowView.set(14, back.dot(-center));
 }

+ 33 - 0
client/rendering/NormalTexture.cpp

@@ -0,0 +1,33 @@
+#include <cmath>
+#include <iostream>
+
+#include "client/rendering/NormalTexture.h"
+#include "client/utils/PNGReader.h"
+
+NormalTexture::NormalTexture(const char* path) : texture(Texture::NEAREST) {
+    u32 maxWidth = 256;
+    u32 maxHeight = 256;
+    u32 buffer[256 * 256];
+    if(PNGReader::load(path, buffer, maxWidth, maxHeight)) {
+        for(uint x = 0; x < maxWidth; x++) {
+            for(uint y = 0; y < maxHeight; y++) {
+                /*float fx = (x % 16) * (2.0f * M_PIf32 / 15.0f);
+                
+                float fb = (sinf(fx) + 1.0f) * 0.5f;
+                
+                uint r = 0;
+                uint g = sqrtf(1 - fb * fb) * 255.0f;
+                uint b = fb * 255.0f;
+                if(y == 0)
+                    std::cout << x << " " << fb << "\n";
+                buffer[y * maxWidth + x] = (b << 16) | (g << 8) | r;*/
+                buffer[y * maxWidth + x] = 0x00FF00;
+            }
+        }
+        texture.setRGBAData(maxWidth, maxHeight, buffer);
+    }
+}
+
+void NormalTexture::bind(uint index) const {
+    texture.bind(index);
+}

+ 16 - 0
client/rendering/NormalTexture.h

@@ -0,0 +1,16 @@
+#ifndef NORMALTEXTURE_H
+#define NORMALTEXTURE_H
+
+#include "client/rendering/wrapper/Texture.h"
+
+class NormalTexture final {
+public:
+    NormalTexture(const char* path);
+
+    void bind(uint index) const;
+
+private:
+    Texture texture;
+};
+
+#endif

+ 1 - 1
client/rendering/RenderSettings.cpp

@@ -1,4 +1,4 @@
 #include "client/rendering/RenderSettings.h"
 
-RenderSettings::RenderSettings() : ssao(true), shadows(true), testRadius(0.004f), testBias(0.003f) {
+RenderSettings::RenderSettings() : ssao(true), shadows(false), testRadius(0.004f), testBias(0.003f) {
 }

+ 17 - 21
client/rendering/Renderer.cpp

@@ -16,28 +16,24 @@ Renderer& Renderer::update() {
     return *this;
 }
 
-Renderer& Renderer::update(const Vector& pos, const Quaternion& rotation) {
+Renderer& Renderer::update(const Vector3& pos, const Quaternion& rotation) {
     Matrix m = rotation.toMatrix();
-    Vector right(1.0f, 0.0f, 0.0f);
-    Vector up(0.0f, 1.0f, 0.0f);
-    Vector back(0.0f, 0.0f, -1.0f);
-    
-    right.mul(m);
-    up.mul(m);
-    back.mul(m);
-
-    view.set(0, right.getX());
-    view.set(1, up.getX());
-    view.set(2, back.getX());
-    view.set(4, right.getY());
-    view.set(5, up.getY());
-    view.set(6, back.getY());
-    view.set(8, right.getZ());
-    view.set(9, up.getZ());
-    view.set(10, back.getZ());
-    view.set(12, right.dotInverse(pos));
-    view.set(13, up.dotInverse(pos));
-    view.set(14, back.dotInverse(pos));
+    Vector3 right = m * Vector3(1.0f, 0.0f, 0.0f);
+    Vector3 up = m * Vector3(0.0f, 1.0f, 0.0f);
+    Vector3 back = m * Vector3(0.0f, 0.0f, -1.0f);
+
+    view.set(0, right[0]);
+    view.set(1, up[0]);
+    view.set(2, back[0]);
+    view.set(4, right[1]);
+    view.set(5, up[1]);
+    view.set(6, back[1]);
+    view.set(8, right[2]);
+    view.set(9, up[2]);
+    view.set(10, back[2]);
+    view.set(12, right.dot(-pos));
+    view.set(13, up.dot(-pos));
+    view.set(14, back.dot(-pos));
     
     shader.setMatrix("view", view.getValues());
     return *this;

+ 1 - 1
client/rendering/Renderer.h

@@ -14,7 +14,7 @@ public:
     void push();
     
     Renderer& update();
-    Renderer& update(const Vector& pos, const Quaternion& rotation);
+    Renderer& update(const Vector3& pos, const Quaternion& rotation);
     
     Renderer& scale(float sx, float sy, float sz);
     Renderer& scale(float s);

+ 24 - 0
client/rendering/Triangle.cpp

@@ -0,0 +1,24 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   Triangle.cpp
+ * Author: kajetan
+ * 
+ * Created on November 12, 2020, 8:07 PM
+ */
+
+#include "Triangle.h"
+
+Triangle::Triangle() {
+}
+
+Triangle::Triangle(const Triangle& orig) {
+}
+
+Triangle::~Triangle() {
+}
+

+ 13 - 0
client/rendering/Triangle.h

@@ -0,0 +1,13 @@
+#ifndef TRIANGLE_H
+#define TRIANGLE_H
+
+class Triangle {
+public:
+    Triangle();
+    Triangle(const Triangle& orig);
+    virtual ~Triangle();
+private:
+
+};
+
+#endif

+ 24 - 0
client/rendering/Vertex.cpp

@@ -0,0 +1,24 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   Vertex.cpp
+ * Author: kajetan
+ * 
+ * Created on November 12, 2020, 8:10 PM
+ */
+
+#include "Vertex.h"
+
+Vertex::Vertex() {
+}
+
+Vertex::Vertex(const Vertex& orig) {
+}
+
+Vertex::~Vertex() {
+}
+

+ 18 - 0
client/rendering/Vertex.h

@@ -0,0 +1,18 @@
+#ifndef VERTEX_H
+#define VERTEX_H
+
+#include "client/math/Vector.h"
+
+struct Vertex final {
+public:
+    Vertex();
+    Vertex(const Vertex& orig);
+    virtual ~Vertex();
+private:
+    
+    Vector position;
+    float tx;
+    float ty;
+};
+
+#endif

+ 39 - 37
client/rendering/renderer/WorldRenderer.cpp

@@ -1,7 +1,8 @@
 #include "client/rendering/renderer/WorldRenderer.h"
 #include <iostream>
 
-WorldRenderer::WorldRenderer(const World& world) : world(world), texture("resources/textures.png") {
+WorldRenderer::WorldRenderer(const World& world) : world(world), texture("resources/textures.png"),
+normalTexture("resources/textures.png") {
     for(uint x = 0; x < World::WORLD_SIZE; x++) {
         for(uint y = 0; y < World::WORLD_SIZE; y++) {
             for(uint z = 0; z < World::WORLD_SIZE; z++) {
@@ -21,6 +22,7 @@ void WorldRenderer::render(float lag, Renderer& renderer) const {
     (void) lag;
     (void) renderer;
     texture.bind(0);
+    normalTexture.bind(2);
     mesh.draw();
 }
 
@@ -31,57 +33,57 @@ bool WorldRenderer::isAir(uint x, uint y, uint z) const {
 void WorldRenderer::addCube(float x, float y, float z, bool bottom, bool top, bool left, bool right, bool front, bool back) {
     const float ERROR = 1.0f / 1024.0f;
     if(bottom) {
-        mesh.add( {x - ERROR, y - ERROR, z - ERROR, 0.125f, 0.0f, 0, -1, 0});
-        mesh.add( {x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0f, 0, -1, 0});
-        mesh.add( {x - ERROR, y - ERROR, z + 1 + ERROR, 0.125f, 0.0625f, 0, -1, 0});
+        mesh.add({x - ERROR, y - ERROR, z - ERROR, 0.125f, 0.0f, 0, -1, 0});
+        mesh.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0f, 0, -1, 0});
+        mesh.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.125f, 0.0625f, 0, -1, 0});
 
-        mesh.add( {x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0f, 0, -1, 0});
-        mesh.add( {x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 0, -1, 0});
-        mesh.add( {x - ERROR, y - ERROR, z + 1 + ERROR, 0.125f, 0.0625f, 0, -1, 0});
+        mesh.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0f, 0, -1, 0});
+        mesh.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 0, -1, 0});
+        mesh.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.125f, 0.0625f, 0, -1, 0});
     }
     if(top) {
-        mesh.add( {x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 1, 0});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 1, 0});
-        mesh.add( {x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.3125f, 0.0f, 0, 1, 0});
+        mesh.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 1, 0});
+        mesh.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 1, 0});
+        mesh.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.3125f, 0.0f, 0, 1, 0});
 
-        mesh.add( {x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.3125f, 0.0f, 0, 1, 0});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 1, 0});
-        mesh.add( {x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.3125f, 0.0625f, 0, 1, 0});
+        mesh.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.3125f, 0.0f, 0, 1, 0});
+        mesh.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 1, 0});
+        mesh.add({x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.3125f, 0.0625f, 0, 1, 0});
     }
     if(left) {
-        mesh.add( {x - ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, -1, 0, 0});
-        mesh.add( {x - ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, -1, 0, 0});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, -1, 0, 0});
+        mesh.add({x - ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, -1, 0, 0});
+        mesh.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, -1, 0, 0});
+        mesh.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, -1, 0, 0});
 
-        mesh.add( {x - ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, -1, 0, 0});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0f, -1, 0, 0});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, -1, 0, 0});
+        mesh.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, -1, 0, 0});
+        mesh.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0f, -1, 0, 0});
+        mesh.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, -1, 0, 0});
     }
     if(right) {
-        mesh.add( {x + 1 + ERROR, y - ERROR, z - ERROR, 0.25f, 0.0625f, 1, 0, 0});
-        mesh.add( {x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 1, 0, 0});
-        mesh.add( {x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 1, 0, 0});
+        mesh.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.25f, 0.0625f, 1, 0, 0});
+        mesh.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 1, 0, 0});
+        mesh.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 1, 0, 0});
 
-        mesh.add( {x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 1, 0, 0});
-        mesh.add( {x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 1, 0, 0});
-        mesh.add( {x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 1, 0, 0});
+        mesh.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 1, 0, 0});
+        mesh.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 1, 0, 0});
+        mesh.add({x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 1, 0, 0});
     }
     if(front) {
-        mesh.add( {x - ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 0, 0, 1});
-        mesh.add( {x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 0, 1});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 0, 0, 1});
+        mesh.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 0, 0, 1});
+        mesh.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 0, 1});
+        mesh.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 0, 0, 1});
 
-        mesh.add( {x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0f, 0, 0, 1});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 0, 0, 1});
-        mesh.add( {x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 0, 1});
+        mesh.add({x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0f, 0, 0, 1});
+        mesh.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 0, 0, 1});
+        mesh.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 0, 1});
     }
     if(back) {
-        mesh.add( {x - ERROR, y - ERROR, z - ERROR, 0.25f, 0.0625f, 0, 0, -1});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 0, -1});
-        mesh.add( {x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, 0, 0, -1});
+        mesh.add({x - ERROR, y - ERROR, z - ERROR, 0.25f, 0.0625f, 0, 0, -1});
+        mesh.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 0, -1});
+        mesh.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, 0, 0, -1});
 
-        mesh.add( {x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, 0, 0, -1});
-        mesh.add( {x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, 0, 0, -1});
-        mesh.add( {x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 0, -1});
+        mesh.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, 0, 0, -1});
+        mesh.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, 0, 0, -1});
+        mesh.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 0, -1});
     }
 }

+ 2 - 0
client/rendering/renderer/WorldRenderer.h

@@ -5,6 +5,7 @@
 #include "common/world/World.h"
 #include "client/rendering/Mesh.h"
 #include "client/rendering/FileTexture.h"
+#include "client/rendering/NormalTexture.h"
 
 class WorldRenderer {
 public:
@@ -18,6 +19,7 @@ private:
     const World& world;
     Mesh mesh;
     FileTexture texture;
+    NormalTexture normalTexture;
 };
 
 #endif

+ 11 - 3
client/rendering/wrapper/Texture.cpp

@@ -1,10 +1,18 @@
 #include "client/rendering/wrapper/Texture.h"
 
-Texture::Texture() : texture(0) {
+Texture::Texture(Mode mode) : texture(0) {
     glGenTextures(1, &texture);
     glBindTexture(GL_TEXTURE_2D, texture);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    switch(mode) {
+        case NEAREST:
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+            break;
+        case LINEAR:
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+            break;
+    }
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 }

+ 8 - 3
client/rendering/wrapper/Texture.h

@@ -7,16 +7,21 @@
 
 class Texture final {
 public:
-    Texture();
+
+    enum Mode {
+        NEAREST, LINEAR
+    };
+
+    Texture(Mode mode = NEAREST);
     ~Texture();
     Texture(const Texture& other) = delete;
     Texture(Texture&& other) = delete;
     Texture& operator=(const Texture& other) = delete;
     Texture& operator=(Texture&& other) = delete;
-    
+
     void setRGBAData(int width, int height, const u32* data);
     void setRGBFloatData(int width, int height, const float* data);
-    
+
     void bind(uint index) const;
 
 private:

+ 2 - 2
meson.build

@@ -6,9 +6,9 @@ sourcesCommon = ['common/network/Packet.cpp', 'common/block/BlockBuilder.cpp', '
 
 sourcesServer = ['server/Main.cpp', 'server/network/Server.cpp', 'server/network/Client.cpp', 'server/GameServer.cpp', 'server/commands/ServerCommands.cpp', 'server/commands/CommandManager.cpp', 'server/commands/ConsoleEditor.cpp', 'server/Clock.cpp']
 
-sourcesClient = ['client/Main.cpp', 'client/rendering/WindowSize.cpp', 'client/math/Frustum.cpp', 'client/rendering/Framebuffers.cpp', 'client/rendering/wrapper/GLFWWrapper.cpp', 'client/rendering/wrapper/Window.cpp', 'client/rendering/Engine.cpp', 'client/input/Keys.cpp', 'client/rendering/wrapper/Shader.cpp', 'client/rendering/Shaders.cpp', 'client/utils/Utils.cpp', 'client/rendering/Mesh.cpp', 'client/math/Matrix.cpp', 'client/math/MatrixStack.cpp', 'client/math/Vector.cpp', 'client/math/Quaternion.cpp', 'client/math/Plane.cpp', 'client/Game.cpp', 'client/input/MouseButtons.cpp', 'client/rendering/FileTexture.cpp', 'client/rendering/FontRenderer.cpp', 'client/rendering/wrapper/Framebuffer.cpp', 'client/rendering/NoiseTexture.cpp', 'client/utils/Clock.cpp', 'client/input/Control.cpp', 'client/rendering/RenderSettings.cpp', 'client/rendering/wrapper/VertexBuffer.cpp', 'client/rendering/wrapper/StreamBuffer.cpp', 'client/rendering/wrapper/Texture.cpp', 'client/utils/PNGReader.cpp', 'client/rendering/wrapper/GLWrapper.cpp', 'client/rendering/Renderer.cpp', 'client/rendering/renderer/WorldRenderer.cpp']
+sourcesClient = ['client/Main.cpp', 'client/rendering/WindowSize.cpp', 'client/math/Frustum.cpp', 'client/rendering/Framebuffers.cpp', 'client/rendering/wrapper/GLFWWrapper.cpp', 'client/rendering/wrapper/Window.cpp', 'client/rendering/Engine.cpp', 'client/input/Keys.cpp', 'client/rendering/wrapper/Shader.cpp', 'client/rendering/Shaders.cpp', 'client/utils/Utils.cpp', 'client/rendering/Mesh.cpp', 'client/math/Matrix.cpp', 'client/math/MatrixStack.cpp', 'client/math/Quaternion.cpp', 'client/math/Plane.cpp', 'client/Game.cpp', 'client/input/MouseButtons.cpp', 'client/rendering/FileTexture.cpp', 'client/rendering/FontRenderer.cpp', 'client/rendering/wrapper/Framebuffer.cpp', 'client/rendering/NoiseTexture.cpp', 'client/utils/Clock.cpp', 'client/input/Control.cpp', 'client/rendering/RenderSettings.cpp', 'client/rendering/wrapper/VertexBuffer.cpp', 'client/rendering/wrapper/StreamBuffer.cpp', 'client/rendering/wrapper/Texture.cpp', 'client/utils/PNGReader.cpp', 'client/rendering/wrapper/GLWrapper.cpp', 'client/rendering/Renderer.cpp', 'client/rendering/renderer/WorldRenderer.cpp', 'client/rendering/NormalTexture.cpp', 'client/math/Vector.cpp']
 
-sourcesTest = ['tests/Main.cpp', 'common/utils/String.cpp', 'common/utils/SplitString.cpp', 'client/math/Matrix.cpp', 'client/math/Vector.cpp', 'common/utils/HashedString.cpp', 'common/utils/Random.cpp']
+sourcesTest = ['tests/Main.cpp', 'common/utils/String.cpp', 'common/utils/SplitString.cpp', 'client/math/Matrix.cpp', 'common/utils/HashedString.cpp', 'common/utils/Random.cpp']
 
 c_compiler = meson.get_compiler('cpp')
 readline = c_compiler.find_library('readline', required: true)

+ 5 - 1
resources/shader/worldFragment.fs

@@ -7,6 +7,7 @@ layout (location = 3) out float worldShadow;
 
 layout (binding = 0) uniform sampler2D samp;
 layout (binding = 1) uniform sampler2D shadowSamp;
+layout (binding = 2) uniform sampler2D normalSamp;
 
 in vec3 varPosition;
 in vec2 varTex;
@@ -41,6 +42,7 @@ const vec3 light = vec3(-0.280166, -0.573576, -0.769751);
 
 void main(void) {
     worldPosition = varPosition;
+    //worldNormal = texture(normalSamp, varTex).xyz; //normalize(varNormal);
     worldNormal = normalize(varNormal);
 
     if(shadows) {
@@ -56,5 +58,7 @@ void main(void) {
         worldShadow = 1.0;
     }
 
-    worldColor = texture(samp, varTex);
+    worldColor = vec4(worldNormal, 1);
+    //worldColor = texture(normalSamp, varTex);
+    //worldColor = texture(normalSamp, varTex);
 }

+ 2 - 0
resources/shader/worldPostFragment.fs

@@ -25,4 +25,6 @@ void main() {
         float f = diffuseLight * texture(shadowSamp, varTex).r;
         color *= f * 0.5 + 0.5;
     }
+    float diffuseLight = max(dot(texture(worldNormalSamp, varTex).xyz, -light), 0.0);
+    color *= diffuseLight;
 }