Browse Source

refactoring, shadows support model matrix

Kajetan Johannes Hammerle 3 years ago
parent
commit
6cd45b740c

+ 17 - 9
client/Game.cpp

@@ -1,6 +1,8 @@
 #include <sstream>
 
 #include "client/Game.h"
+#include "client/utils/Utils.h"
+#include "rendering/Renderer.h"
 
 Game::Game(const Control& control, const Camera& camera, Ray& ray, const Clock& fps, const Clock& tps,
         RenderSettings& renderSettings) :
@@ -10,7 +12,7 @@ widthAngle(35.0f), texture("resources/textures.png") {
         for(int y = -6; y <= 6; y++) {
             for(int z = -6; z <= 6; z++) {
                 if(x * x + y * y + z * z < 16) {
-                    addCube(x - 3, y - 5, z - 10,
+                    addCube(x, y, z,
                             x * x + (y - 1) * (y - 1) + z * z >= 16,
                             x * x + (y + 1) * (y + 1) + z * z >= 16 && !(x == 0 && y == 3 && z == 0),
                             (x - 1) * (x - 1) + y * y + z * z >= 16,
@@ -21,8 +23,8 @@ widthAngle(35.0f), texture("resources/textures.png") {
             }
         }
     }
-    addCube(-3, -1, -10, false, true, true, true, true, true);
-    //pos.set(-3, 0, -10);
+    addCube(0, 4, 0, false, true, true, true, true, true);
+    pos.set(0, 10, 0);
     m.build();
 }
 
@@ -84,6 +86,8 @@ void Game::addCube(float x, float y, float z, bool bottom, bool top, bool left,
     }
 }
 
+float testAngle = 0.0f;
+
 void Game::tick() {
     const float speed = 0.25f;
     if(control.keys.down.isDown()) {
@@ -137,20 +141,24 @@ void Game::tick() {
     if(control.keys.test4.isDown()) {
         renderSettings.testBias *= 0.95f;
     }
+
+    testAngle += 5.0;
 }
 
-void Game::renderWorld(float lag, MatrixStack& stack, Shader& sh) const {
+void Game::renderWorld(float lag, Renderer& renderer) const {
     (void) lag;
-    (void) stack;
-    (void) sh;
+    (void) renderer;
+    renderer.translateTo(0.0f, 0.0f, -0.5f)
+            .rotateY(interpolate(lag, testAngle - 5.0, testAngle))
+            .translate(-0.5f, 0.0f, -0.5f)
+            .update();
     texture.bind(0);
     m.draw();
 }
 
-void Game::renderTextOverlay(float lag, MatrixStack& stack, Shader& sh, FontRenderer& fr) const {
+void Game::renderTextOverlay(float lag, Renderer& renderer, FontRenderer& fr) const {
     (void) lag;
-    //stack.get().scale(2.0f, 2.0f, 2.0f);
-    sh.setMatrix("model", stack.get().getValues());
+    renderer.scale(2.0f).update();
 
     char buffer[50];
     snprintf(buffer, 50, "FPS: %.2f", fps.getUpdatesPerSecond());

+ 5 - 6
client/Game.h

@@ -5,10 +5,9 @@
 #include "client/math/Camera.h"
 #include "client/utils/Clock.h"
 #include "client/rendering/RenderSettings.h"
-#include "client/rendering/wrapper/Shader.h"
-#include "client/math/MatrixStack.h"
+#include "client/rendering/Renderer.h"
 #include "client/rendering/Mesh.h"
-#include "client/rendering/Texture.h"
+#include "client/rendering/FileTexture.h"
 #include "client/rendering/FontRenderer.h"
 
 class Game final {
@@ -17,8 +16,8 @@ public:
             RenderSettings& renderSettings);
 
     void tick();
-    void renderWorld(float lag, MatrixStack& stack, Shader& sh) const;
-    void renderTextOverlay(float lag, MatrixStack& stack, Shader& sh, FontRenderer& fr) const;
+    void renderWorld(float lag, Renderer& renderer) const;
+    void renderTextOverlay(float lag, Renderer& renderer, FontRenderer& fr) const;
     
     bool isRunning() const;
 
@@ -36,7 +35,7 @@ private:
     float widthAngle;
     Vector pos;
     Mesh m;
-    Texture texture;
+    FileTexture texture;
 };
 
 #endif

+ 1 - 1
client/Main.cpp

@@ -6,7 +6,7 @@
 #include "client/rendering/Shaders.h"
 #include "client/rendering/Framebuffers.h"
 #include "client/input/Control.h"
-#include "client/Engine.h"
+#include "client/rendering/Engine.h"
 #include "client/utils/Clock.h"
 #include "client/rendering/RenderSettings.h"
 

+ 0 - 8
client/Utils.h

@@ -1,8 +0,0 @@
-#ifndef UTILS_H
-#define UTILS_H
-
-bool checkAndPrintError(const char* message);
-float interpolate(float lag, float from, float to);
-void printMatrix(const float* data);
-
-#endif

+ 0 - 1
client/math/Camera.cpp

@@ -1,5 +1,4 @@
 #include "client/math/Camera.h"
-#include "client/Utils.h"
 
 Camera::Camera(const Ray& ray) : ray(ray) {
 }

+ 1 - 1
client/math/Ray.cpp

@@ -1,5 +1,5 @@
 #include "client/math/Ray.h"
-#include "client/Utils.h"
+#include "client/utils/Utils.h"
 
 Ray::Ray() : lastLengthAngle(0), lengthAngle(0), lastWidthAngle(0), widthAngle(0) {
 }

+ 8 - 5
client/Engine.cpp → client/rendering/Engine.cpp

@@ -1,4 +1,4 @@
-#include "client/Engine.h"
+#include "client/rendering/Engine.h"
 #include "client/rendering/wrapper/GLFWWrapper.h"
 
 Engine::Engine(Shaders& shaders, Framebuffers& fb, Camera& camera, const WindowSize& size,
@@ -34,7 +34,8 @@ void Engine::renderShadow(float lag, const Game& game) {
     shaders.shadow.use();
     worldShadowProjView.set(worldShadowProj).mul(worldShadowView);
     shaders.shadow.setMatrix("projView", worldShadowProjView.getValues());
-    game.renderWorld(lag, model, shaders.shadow);
+    Renderer renderer(shaders.shadow, model);
+    game.renderWorld(lag, renderer);
 }
 
 void Engine::renderWorld(float lag, const Game& game) {
@@ -53,7 +54,8 @@ void Engine::renderWorld(float lag, const Game& game) {
     fb.shadow.bindDepthTexture(1);
     shaders.world.setFloat("radius", renderSettings.testRadius);
     shaders.world.setFloat("bias", renderSettings.testBias);
-    game.renderWorld(lag, model, shaders.world);
+    Renderer renderer(shaders.world, model);
+    game.renderWorld(lag, renderer);
 }
 
 void Engine::renderSSAO() {
@@ -106,7 +108,8 @@ void Engine::renderTextOverlay(float lag, const Game& game) {
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     glBlendEquation(GL_FUNC_ADD);
-    game.renderTextOverlay(lag, model, shaders.text, fontRenderer);
+    Renderer renderer(shaders.text, model);
+    game.renderTextOverlay(lag, renderer, fontRenderer);
     glDisable(GL_BLEND);
 }
 
@@ -121,7 +124,7 @@ void Engine::updateWorldProjection() {
     float tan = tanf((0.5f * fovY) * M_PI / 180.0f);
     float aspect = (float) size.width / size.height;
 
-    float closeFarClip = 4;
+    float closeFarClip = 16;
     float nearHigh = tan * nearClip;
     float nearWidth = nearHigh * aspect;
     float farHigh = tan * closeFarClip;

+ 1 - 1
client/Engine.h → client/rendering/Engine.h

@@ -10,9 +10,9 @@
 #include "client/rendering/Mesh.h"
 #include "client/rendering/Framebuffers.h"
 #include "client/rendering/Shaders.h"
+#include "client/rendering/Renderer.h"
 #include "client/math/Camera.h"
 #include "client/math/Plane.h"
-#include "client/math/MatrixStack.h"
 #include "client/math/Frustum.h"
 #include "client/Game.h"
 #include "client/rendering/NoiseTexture.h"

+ 16 - 0
client/rendering/FileTexture.cpp

@@ -0,0 +1,16 @@
+#include "client/rendering/FileTexture.h"
+#include "client/utils/PNGReader.h"
+
+FileTexture::FileTexture(const char* path) {
+    u32 width;
+    u32 height;
+    u32* data = PNGReader::load(path, width, height);
+    if(data != nullptr) {
+        texture.setRGBAData(width, height, data);
+        delete[] data;
+    }
+}
+
+void FileTexture::bind(uint index) const {
+    texture.bind(index);
+}

+ 18 - 0
client/rendering/FileTexture.h

@@ -0,0 +1,18 @@
+#ifndef FILE_TEXTURE_H
+#define FILE_TEXTURE_H
+
+#include <GL/glew.h>
+
+#include "client/rendering/wrapper/Texture.h"
+
+class FileTexture final {
+public:
+    FileTexture(const char* path);
+
+    void bind(uint index) const;
+
+private:
+    Texture texture;
+};
+
+#endif

+ 2 - 2
client/rendering/FontRenderer.h

@@ -3,7 +3,7 @@
 
 #include "client/rendering/wrapper/VertexBuffer.h"
 #include "client/rendering/wrapper/StreamBuffer.h"
-#include "client/rendering/Texture.h"
+#include "client/rendering/FileTexture.h"
 
 class FontRenderer final {
 public:
@@ -14,7 +14,7 @@ public:
 private:
     VertexBuffer vertexBuffer;
     StreamBuffer buffer;
-    Texture tex;
+    FileTexture tex;
 };
 
 #endif

+ 6 - 21
client/rendering/NoiseTexture.cpp

@@ -1,37 +1,22 @@
-#include <png.h>
 #include <vector>
 #include <cstdlib>
-#include <iostream>
 
 #include "client/rendering/NoiseTexture.h"
 
-NoiseTexture::NoiseTexture(u32 width, u32 height) {
-    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);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
+NoiseTexture::NoiseTexture(uint width, uint height) {
     std::vector<float> data;
-    for(u32 x = 0; x < width; x++) {
-        for(u32 y = 0; y < height; y++) {
+    for(uint x = 0; x < width; x++) {
+        for(uint y = 0; y < height; y++) {
             data.push_back(getRandom());
             data.push_back(getRandom());
             data.push_back(getRandom());
         }
     }
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, data.data());
-}
-
-NoiseTexture::~NoiseTexture() {
-    glDeleteTextures(1, &texture);
+    texture.setRGBFloatData(width, height, data.data());
 }
 
-void NoiseTexture::bind(unsigned int index) const {
-    glActiveTexture(GL_TEXTURE0 + index);
-    glBindTexture(GL_TEXTURE_2D, texture);
+void NoiseTexture::bind(uint index) const {
+    texture.bind(index);
 }
 
 float NoiseTexture::getRandom() const {

+ 6 - 14
client/rendering/NoiseTexture.h

@@ -4,27 +4,19 @@
 #include <GL/glew.h>
 #include <GLFW/glfw3.h>
 
+#include "client/rendering/wrapper/Texture.h"
 #include "common/utils/Types.h"
 
 class NoiseTexture final {
 public:
-    NoiseTexture(u32 width, u32 height);
-    ~NoiseTexture();
-    NoiseTexture(const NoiseTexture& other) = delete;
-    NoiseTexture(NoiseTexture&& other) = delete;
-    NoiseTexture& operator=(const NoiseTexture& other) = delete;
-    NoiseTexture& operator=(NoiseTexture&& other) = delete;
+    NoiseTexture(uint width, uint height);
 
-    void bind(unsigned int index) const;
+    void bind(uint index) const;
 
 private:
     float getRandom() const;
-
-    u32 width;
-    u32 height;
-
-    GLuint texture = 0;
+    
+    Texture texture;
 };
 
-#endif
-
+#endif

+ 67 - 0
client/rendering/Renderer.cpp

@@ -0,0 +1,67 @@
+#include "Renderer.h"
+
+Renderer::Renderer(Shader& shader, MatrixStack& stack) : shader(shader), stack(stack) {
+}
+
+void Renderer::pop() {
+    stack.pop();
+}
+
+void Renderer::push() {
+    stack.push();
+}
+
+Renderer& Renderer::update() {
+    shader.setMatrix("model", stack.get().getValues());
+    return *this;
+}
+
+Renderer& Renderer::scale(float sx, float sy, float sz) {
+    stack.get().scale(sx, sy, sz);
+    return *this;
+}
+
+Renderer& Renderer::scale(float s) {
+    stack.get().scale(s);
+    return *this;
+}
+
+Renderer& Renderer::translate(float tx, float ty, float tz) {
+    stack.get().translate(tx, ty, tz);
+    return *this;
+}
+
+Renderer& Renderer::translateX(float tx) {
+    stack.get().translateX(tx);
+    return *this;
+}
+
+Renderer& Renderer::translateY(float ty) {
+    stack.get().translateY(ty);
+    return *this;
+}
+
+Renderer& Renderer::translateZ(float tz) {
+    stack.get().translateZ(tz);
+    return *this;
+}
+
+Renderer& Renderer::translateTo(float tx, float ty, float tz) {
+    stack.get().translateTo(tx, ty, tz);
+    return *this;
+}
+
+Renderer& Renderer::rotateX(float degrees) {
+    stack.get().rotateX(degrees);
+    return *this;
+}
+
+Renderer& Renderer::rotateY(float degrees) {
+    stack.get().rotateY(degrees);
+    return *this;
+}
+
+Renderer& Renderer::rotateZ(float degrees) {
+    stack.get().rotateZ(degrees);
+    return *this;
+}

+ 34 - 0
client/rendering/Renderer.h

@@ -0,0 +1,34 @@
+#ifndef RENDERER_H
+#define RENDERER_H
+
+#include "client/rendering/wrapper/Shader.h"
+#include "client/math/MatrixStack.h"
+
+class Renderer {
+public:
+    Renderer(Shader& shader, MatrixStack& stack);
+    
+    void pop();
+    void push();
+    
+    Renderer& update();
+    
+    Renderer& scale(float sx, float sy, float sz);
+    Renderer& scale(float s);
+
+    Renderer& translate(float tx, float ty, float tz);
+    Renderer& translateX(float tx);
+    Renderer& translateY(float ty);
+    Renderer& translateZ(float tz);
+    Renderer& translateTo(float tx, float ty, float tz);
+
+    Renderer& rotateX(float degrees);
+    Renderer& rotateY(float degrees);
+    Renderer& rotateZ(float degrees);
+
+private:
+    Shader& shader;
+    MatrixStack& stack;
+};
+
+#endif

+ 0 - 111
client/rendering/Texture.cpp

@@ -1,111 +0,0 @@
-#include <png.h>
-
-#include "client/rendering/Texture.h"
-
-Texture::Texture(const char* path) : data(nullptr), texture(0) {
-    load(path);
-}
-
-Texture::~Texture() {
-    if(data != nullptr) {
-        delete[] data;
-    }
-    glDeleteTextures(1, &texture);
-}
-
-void Texture::load(const char* path) {
-    FILE* file = fopen(path, "r");
-    if(file == nullptr) {
-        std::cout << "texture '" << path << "' does not exist\n";
-        return;
-    }
-    bool b = load(path, file);
-    fclose(file);
-    if(b) {
-        initGL();
-    }
-}
-
-bool Texture::load(const char* path, FILE* file) {
-    // check signature of png
-    unsigned char buffer[8];
-    if(fread(buffer, sizeof (char), 8, file) != 8) {
-        std::cout << "cannot read signature of texture '" << path << "'\n";
-        return false;
-    }
-
-    if(png_sig_cmp(buffer, 0, 8)) {
-        std::cout << "file '" << path << "' is not a texture\n";
-        return false;
-    }
-
-    // create structures for data
-    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
-    if(png == nullptr) {
-        std::cout << "cannot create texture data structure\n";
-        return false;
-    }
-
-    png_infop info = png_create_info_struct(png);
-    if(info == nullptr) {
-        std::cout << "cannot create image info structure\n";
-        return false;
-    }
-
-    u32** rowPointers = nullptr;
-
-    // set callback for errors
-    if(setjmp(png_jmpbuf(png))) {
-        if(rowPointers != nullptr) {
-            png_free(png, rowPointers);
-        }
-        png_destroy_read_struct(&png, &info, nullptr);
-        std::cout << "texture '" << path << "' has used error callback\n";
-        return false;
-    }
-
-    // set reading function
-    png_init_io(png, file);
-    // notify about already used signature bytes
-    png_set_sig_bytes(png, 8);
-
-    // read info data
-    png_read_info(png, info);
-    width = png_get_image_width(png, info);
-    height = png_get_image_height(png, info);
-
-    // read image data
-    data = new u32[width * height];
-
-    // allocate and set row pointer to correct places in block
-    rowPointers = (u32**) png_malloc(png, height * (sizeof (u32*)));
-    for(unsigned int i = 0; i < height; i++) {
-        rowPointers[i] = (data + i * width);
-    }
-    png_set_rows(png, info, (png_bytepp) rowPointers);
-
-    png_read_image(png, (png_bytepp) rowPointers);
-
-    png_free(png, rowPointers);
-    png_destroy_read_struct(&png, &info, NULL);
-    return true;
-}
-
-void Texture::initGL() {
-    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);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
-    delete[] data;
-    data = nullptr;
-}
-
-void Texture::bind(uint index) const {
-    glActiveTexture(GL_TEXTURE0 + index);
-    glBindTexture(GL_TEXTURE_2D, texture);
-}

+ 2 - 24
client/Utils.cpp → client/rendering/wrapper/GLWrapper.cpp

@@ -1,10 +1,9 @@
 #include <GL/glew.h>
 #include <iostream>
-#include <iomanip>
 
-#include "client/Utils.h"
+#include "client/rendering/wrapper/GLWrapper.h"
 
-bool checkAndPrintError(const char* message) {
+bool GLWrapper::checkAndPrintError(const char* message) {
     GLenum error = glGetError();
     switch(error) {
         case GL_NO_ERROR:
@@ -34,25 +33,4 @@ bool checkAndPrintError(const char* message) {
             std::cout << message << ": unknown OpenGL error: " << error << "\n";
     }
     return true;
-}
-
-float interpolate(float lag, float from, float to) {
-    return from + lag * (to - from);
-}
-
-void printMatrix(const float* data) {
-    std::cout << "MatrixData\n(\n";
-    std::cout << std::fixed << std::setprecision(5);
-    for(int i = 0; i < 4; i++) {
-        std::cout << std::setw(15);
-        std::cout << data[i] << ", ";
-        std::cout << std::setw(15);
-        std::cout << data[i + 4] << ", ";
-        std::cout << std::setw(15);
-        std::cout << data[i + 8] << ", ";
-        std::cout << std::setw(15);
-        std::cout << data[i + 12] << "\n";
-    }
-    std::cout << std::defaultfloat;
-    std::cout << ")\n";
 }

+ 8 - 0
client/rendering/wrapper/GLWrapper.h

@@ -0,0 +1,8 @@
+#ifndef GLWRAPPER_H
+#define GLWRAPPER_H
+
+namespace GLWrapper {
+    bool checkAndPrintError(const char* message);
+}
+
+#endif

+ 3 - 3
client/rendering/wrapper/Shader.cpp

@@ -2,7 +2,7 @@
 #include <iostream>
 
 #include "client/rendering/wrapper/Shader.h"
-#include "client/Utils.h"
+#include "client/rendering/wrapper/GLWrapper.h"
 
 Shader::Shader(const GLchar* vPath, const GLchar* fPath) : vShader(0), fShader(0), program(0) {
     if(readFileAndCompile(vPath, vShader, GL_VERTEX_SHADER) || readFileAndCompile(fPath, fShader, GL_FRAGMENT_SHADER)) {
@@ -12,7 +12,7 @@ Shader::Shader(const GLchar* vPath, const GLchar* fPath) : vShader(0), fShader(0
     glAttachShader(program, vShader);
     glAttachShader(program, fShader);
     glLinkProgram(program);
-    if(checkAndPrintError("shader linking error")) {
+    if(GLWrapper::checkAndPrintError("shader linking error")) {
         return;
     }
     GLint linked;
@@ -58,7 +58,7 @@ bool Shader::compile(GLuint& shader, const GLchar* code, GLenum shaderType) {
     shader = glCreateShader(shaderType);
     glShaderSource(shader, 1, &code, nullptr);
     glCompileShader(shader);
-    if(checkAndPrintError("shader error")) {
+    if(GLWrapper::checkAndPrintError("shader error")) {
         return true;
     }
     GLint compiled;

+ 27 - 0
client/rendering/wrapper/Texture.cpp

@@ -0,0 +1,27 @@
+#include "Texture.h"
+
+Texture::Texture() : 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);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+}
+
+Texture::~Texture() {
+    glDeleteTextures(1, &texture);
+}
+
+void Texture::setRGBAData(int width, int height, const u32* data) {
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+}
+
+void Texture::setRGBFloatData(int width, int height, const float* data) {
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, data);
+}
+
+void Texture::bind(uint index) const {
+    glActiveTexture(GL_TEXTURE0 + index);
+    glBindTexture(GL_TEXTURE_2D, texture);
+}

+ 6 - 13
client/rendering/Texture.h → client/rendering/wrapper/Texture.h

@@ -2,31 +2,24 @@
 #define TEXTURE_H
 
 #include <GL/glew.h>
-#include <GLFW/glfw3.h>
-#include <iostream>
 
 #include "common/utils/Types.h"
 
-class Texture final {
+class Texture {
 public:
-    Texture(const char* path);
+    Texture();
     ~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:
-    void load(const char* path);
-    bool load(const char* path, FILE* file);
-    void initGL();
-
-    u32 width;
-    u32 height;
-    u32* data;
-
     GLuint texture;
 };
 

+ 79 - 0
client/utils/PNGReader.cpp

@@ -0,0 +1,79 @@
+#include <iostream>
+#include <png.h>
+#include <cstring>
+
+#include "client/utils/PNGReader.h"
+
+static bool checkSignature(const char* path, FILE* file) {
+    unsigned char buffer[8];
+    if(fread(buffer, sizeof (char), 8, file) != 8) {
+        std::cout << "cannot read signature of texture '" << path << "'\n";
+        return true;
+    }
+    if(png_sig_cmp(buffer, 0, 8)) {
+        std::cout << "file '" << path << "' is not a texture\n";
+        return true;
+    }
+    return false;
+}
+
+static u32* load(const char* path, FILE* file, u32& width, u32& height) {
+    if(checkSignature(path, file)) {
+        return nullptr;
+    }
+
+    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+    if(png == nullptr) {
+        std::cout << "cannot create texture data structure\n";
+        return nullptr;
+    }
+
+    png_infop info = png_create_info_struct(png);
+    if(info == nullptr) {
+        std::cout << "cannot create image info structure\n";
+        return nullptr;
+    }
+
+    u32** rowPointers = nullptr;
+
+    if(setjmp(png_jmpbuf(png))) { // set callback for errors
+        if(rowPointers != nullptr) {
+            png_free(png, rowPointers);
+        }
+        png_destroy_read_struct(&png, &info, nullptr);
+        std::cout << "texture '" << path << "' has used error callback\n";
+        return nullptr;
+    }
+
+    png_init_io(png, file); // set reading function
+    png_set_sig_bytes(png, 8); // notify about already used signature bytes
+
+    png_read_info(png, info); // read info data
+    width = png_get_image_width(png, info);
+    height = png_get_image_height(png, info);
+
+    // allocate and set row pointer to correct places in block
+    u32* data = new u32[width * height];
+    rowPointers = static_cast<u32**> (png_malloc(png, height * (sizeof (u32*))));
+    for(uint i = 0; i < height; i++) {
+        rowPointers[i] = (data + i * width);
+    }
+    png_set_rows(png, info, reinterpret_cast<png_bytepp> (rowPointers));
+
+    png_read_image(png, reinterpret_cast<png_bytepp> (rowPointers));
+
+    png_free(png, rowPointers);
+    png_destroy_read_struct(&png, &info, nullptr);
+    return data;
+}
+
+u32* PNGReader::load(const char* path, u32& width, u32& height) {
+    FILE* file = fopen(path, "r");
+    if(file == nullptr) {
+        std::cout << "texture '" << path << "' cannot be read: " << strerror(errno) << "\n";
+        return nullptr;
+    }
+    u32* data = load(path, file, width, height);
+    fclose(file);
+    return data;
+}

+ 10 - 0
client/utils/PNGReader.h

@@ -0,0 +1,10 @@
+#ifndef PNGREADER_H
+#define PNGREADER_H
+
+#include "common/utils/Types.h"
+
+namespace PNGReader {
+    u32* load(const char* path, u32& width, u32& height);
+}
+
+#endif

+ 5 - 0
client/utils/Utils.cpp

@@ -0,0 +1,5 @@
+#include "client/utils/Utils.h"
+
+float interpolate(float lag, float from, float to) {
+    return from + lag * (to - from);
+}

+ 6 - 0
client/utils/Utils.h

@@ -0,0 +1,6 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+float interpolate(float lag, float from, float to);
+
+#endif

+ 1 - 1
meson.build

@@ -4,7 +4,7 @@ sourcesCommon = ['common/block/BlockRegistry.cpp', 'common/block/Block.cpp', 'co
 
 sourcesServer = ['server/GameServer.cpp', 'server/commands/CommandUtils.cpp', 'server/commands/ServerCommands.cpp', 'server/commands/CommandManager.cpp', 'server/network/Server.cpp', 'server/Main.cpp']
 
-sourcesClient = ['client/Main.cpp', 'client/rendering/WindowSize.cpp', 'client/math/Frustum.cpp', 'client/math/Ray.cpp', 'client/rendering/Framebuffers.cpp', 'client/rendering/wrapper/GLFWWrapper.cpp', 'client/rendering/wrapper/Window.cpp', 'client/Engine.cpp', 'client/input/Keys.cpp', 'client/rendering/wrapper/Shader.cpp', 'client/rendering/Shaders.cpp', 'client/Utils.cpp', 'client/rendering/Mesh.cpp', 'client/math/Matrix.cpp', 'client/math/MatrixStack.cpp', 'client/math/Vector.cpp', 'client/math/Camera.cpp', 'client/math/Plane.cpp', 'client/Game.cpp', 'client/input/MouseButtons.cpp', 'client/rendering/Texture.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']
+sourcesClient = ['client/Main.cpp', 'client/rendering/WindowSize.cpp', 'client/math/Frustum.cpp', 'client/math/Ray.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/Camera.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']
 
 sourcesTest = ['tests/Main.cpp', 'server/commands/CommandUtils.cpp']
 

+ 2 - 1
resources/shader/worldShadowVertex.vs

@@ -5,7 +5,8 @@ layout (location = 1) in vec2 tex;
 layout (location = 2) in vec3 normal;
 
 uniform mat4 projView;
+uniform mat4 model;
 
 void main(void) { 
-    gl_Position = projView * vec4(position, 1.0);
+    gl_Position = projView * model * vec4(position, 1.0);
 }

+ 4 - 2
resources/shader/worldVertex.vs

@@ -24,9 +24,11 @@ void main(void) {
     
     varTex = tex; 
     
-    vec4 worldPos = view * model * vec4(position, 1.0);
+    vec4 modelPos = model * vec4(position, 1.0);
+    vec4 worldPos = view * modelPos;
+
     varPosition = worldPos.xyz;
     gl_Position = proj * worldPos;
 
-    varShadow = projViewShadow * vec4(position - light * 0.0, 1.0);
+    varShadow = projViewShadow * modelPos;
 }