Browse Source

entity rendering tests, clean up, tolerance for frustum culling, added
mouse angle movement

Kajetan Johannes Hammerle 5 years ago
parent
commit
d2f8b2224d

+ 4 - 1
Makefile

@@ -16,7 +16,7 @@ game_client: MainClient.cpp\
 	Client.o\
 	Block.o Blocks.o BlockAir.o\
 	Face.o\
-	Chunk.o World.o ChunkRenderer.o ClientChunkProvider.o BlockRenderer.o BlockRenderers.o
+	Chunk.o World.o ChunkRenderer.o ClientChunkProvider.o BlockRenderer.o BlockRenderers.o EntityRenderer.o
 	g++ $(VERSION) -o $@ MainClient.cpp *.o $(LDFLAGS)
 
 # ------------------------------------------------------------------------------	
@@ -89,6 +89,9 @@ BlockRenderer.o: client/rendering/block/BlockRenderer.h client/rendering/block/B
 	
 BlockRenderers.o: client/rendering/block/BlockRenderers.h client/rendering/block/BlockRenderers.cpp
 	g++ $(VERSION) -c client/rendering/block/BlockRenderers.cpp -o $@
+	
+EntityRenderer.o: client/rendering/entity/EntityRenderer.h client/rendering/entity/EntityRenderer.cpp
+	g++ $(VERSION) -c client/rendering/entity/EntityRenderer.cpp -o $@
 
 # ------------------------------------------------------------------------------	
 # Utils

+ 69 - 18
client/Client.cpp

@@ -2,6 +2,8 @@
 #include <iostream>
 #include "../block/Blocks.h"
 #include "../client/rendering/block/BlockRenderers.h"
+#include "rendering/entity/EntityRenderer.h"
+#include <cmath>
 
 using namespace std;
 
@@ -10,9 +12,9 @@ Client::Client() : world(&chunkProvider)
     BlockRegistry::registerBlocks();
     BlockRenderers::init();
 
-    position.set(16, 50, -5);
-    lengthAngle = -15;
-    widthAngle = -20;
+    position.set(0, -9, 3);
+    lengthAngle = 180;
+    widthAngle = 0;
     
     camera.setPosition(position.getX(), position.getY(), position.getZ(), 0, 0);
     camera.storePosition();
@@ -23,17 +25,15 @@ Client::Client() : world(&chunkProvider)
     keyManager.map(KEY_DOWN, GLFW_KEY_S);
     keyManager.map(KEY_JUMP, GLFW_KEY_SPACE);
     keyManager.map(KEY_SNEAK, GLFW_KEY_LEFT_SHIFT);
-    keyManager.map(KEY_CAM_LEFT, GLFW_KEY_H);
-    keyManager.map(KEY_CAM_RIGHT, GLFW_KEY_K);
-    keyManager.map(KEY_CAM_UP, GLFW_KEY_U);
-    keyManager.map(KEY_CAM_DOWN, GLFW_KEY_J);
     
-    keyManager.map(KEY_CAM_TEST, GLFW_KEY_T);
+    keyManager.map(KEY_TEST, GLFW_KEY_T);
     
     mouseManager.map(MOUSE_LEFT, GLFW_MOUSE_BUTTON_1);
     
     world.registerChunkListener(&chunkRenderer);
     world.updateDirtyChunks();
+    
+    Engine::setMouseTrapped(mouseTrapped);
 }
 
 Client::~Client()
@@ -42,11 +42,17 @@ Client::~Client()
 
 void Client::tick()
 {
+    if(keyManager.isReleased(KEY_TEST))
+    {
+        mouseTrapped = !mouseTrapped;
+        Engine::setMouseTrapped(mouseTrapped);
+    }
+    
     tps.update();
     
     camera.storePosition();
     
-    float factor = 0.5f;
+    float factor = 0.05f;
     if(keyManager.isDown(KEY_LEFT))
     {
         position.addMul(camera.getFlatLeft(), factor);
@@ -71,26 +77,35 @@ void Client::tick()
     {
         position.addMul(camera.getFlatDown(), factor);
     }
-    
-    if(keyManager.isDown(KEY_CAM_LEFT))
+       
+    widthAngle += diffMouseY;
+    if(widthAngle < -89)
     {
-        lengthAngle += 2;
+        widthAngle = -89;
     }
-    if(keyManager.isDown(KEY_CAM_RIGHT))
+    else if(widthAngle > 89)
     {
-        lengthAngle -= 2;
+        widthAngle = 89;
     }
-    if(keyManager.isDown(KEY_CAM_UP) && widthAngle < 88)
+    diffMouseY = 0;
+    
+    lengthAngle += diffMouseX;
+    if(lengthAngle < 0)
     {
-        widthAngle += 2;
+        lengthAngle += 360;
+        camera.addToOldLengthAngle(360);
     }
-    if(keyManager.isDown(KEY_CAM_DOWN) && widthAngle > -88)
+    else if(lengthAngle > 360)
     {
-        widthAngle -= 2;
+        lengthAngle -= 360;
+        camera.addToOldLengthAngle(-360);
     }
+    diffMouseX = 0;
     
     camera.setPosition(position.getX(), position.getY(), position.getZ(), lengthAngle, widthAngle);
     
+    entity.tick();
+    
     mouseManager.tick();
     keyManager.tick();
 }
@@ -101,9 +116,12 @@ void Client::render3DTick(float lag)
     
     camera.update(lag);
     Engine::setWorldViewMatrix(camera.getViewMatrix());
+    
     shader.setToIdentity();
     Engine::setWorldModelMatrix(shader.getModelMatrix());    
     chunkRenderer.renderTick(shader, camera, directRenderer, lag);
+    
+    entity.renderTick(shader, camera, directRenderer, lag);
 }
 
 void Client::render2DTick(float lag)
@@ -130,6 +148,39 @@ void Client::onKeyEvent(int key, int scancode, int action, int mods)
     }
 }
 
+double Client::transformMouse(double x)
+{
+    if(x >= -MOUSE_BORDER && x <= MOUSE_BORDER)
+    {
+        return x * x * x;
+    }
+    else if(x >= MOUSE_BORDER)
+    {
+        const double k = (3 * MOUSE_BORDER * MOUSE_BORDER);
+        const double y = MOUSE_BORDER * MOUSE_BORDER * MOUSE_BORDER;
+        const double d = y - k * MOUSE_BORDER;
+        return k * x + d;
+    }
+    else
+    {
+        const double k = (3 * MOUSE_BORDER * MOUSE_BORDER);
+        const double y = -MOUSE_BORDER * MOUSE_BORDER * MOUSE_BORDER;
+        const double d = y - k * MOUSE_BORDER;
+        return k * x + d;
+    }
+}
+
+void Client::onMouseMove(double x, double y)
+{
+    if(mouseTrapped)
+    {
+        diffMouseX = transformMouse(oldMouseX - x) * (1 / (MOUSE_BORDER * MOUSE_BORDER * 3));
+        diffMouseY = transformMouse(oldMouseY - y) * (1 / (MOUSE_BORDER * MOUSE_BORDER * 3));
+        oldMouseX = x;
+        oldMouseY = y;
+    }
+}
+
 void Client::onMouseClick(int button, int action, int mods)
 {
     if(action == GLFW_PRESS)

+ 15 - 6
client/Client.h

@@ -12,6 +12,7 @@
 #include "../world/IChunkProvider.h"
 #include "rendering/ClientChunkProvider.h"
 #include "rendering/ChunkRenderer.h"
+#include "rendering/entity/EntityRenderer.h"
 
 using namespace std;
 
@@ -24,9 +25,13 @@ public:
     void tick() override;
     void render3DTick(float lag) override;
     void render2DTick(float lag) override;
+    
     void onKeyEvent(int key, int scancode, int action, int mods) override;
+    void onMouseMove(double x, double y) override;
     void onMouseClick(int button, int action, int mods) override;
 private:
+    double transformMouse(double in);
+    
     static const int KEY_LEFT = 0;
     static const int KEY_RIGHT = 1;
     static const int KEY_UP = 2;
@@ -34,15 +39,17 @@ private:
     static const int KEY_JUMP = 4;
     static const int KEY_SNEAK = 5;
     
-    static const int KEY_CAM_LEFT = 6;
-    static const int KEY_CAM_RIGHT = 7;
-    static const int KEY_CAM_UP = 8;
-    static const int KEY_CAM_DOWN = 9;
-    
-    static const int KEY_CAM_TEST = 10;
+    static const int KEY_TEST = 10;
     
     static const int MOUSE_LEFT = 0;
     
+    double oldMouseX = 0;
+    double oldMouseY = 0;
+    double diffMouseX = 0;
+    double diffMouseY = 0;
+    bool mouseTrapped = true;
+    const double MOUSE_BORDER = 1.0;
+    
     Clock tps;
     Clock fps;
     
@@ -60,6 +67,8 @@ private:
     Vector3D position;
     float lengthAngle = 0;
     float widthAngle = 0;
+    
+    EntityRenderer entity;
 };
 
 #endif

+ 2 - 12
client/rendering/ChunkRenderer.cpp

@@ -5,7 +5,7 @@
 
 ChunkRenderer::ChunkRenderer() : blockTexture("resources/textures.png")
 {
-    mesh = new ChunkMesh[chunkX * chunkZ * Chunk::HEIGHT_PARTIONS];
+    mesh = new NormalTextureMesh[chunkX * chunkZ * Chunk::HEIGHT_PARTIONS];
 }
 
 ChunkRenderer::~ChunkRenderer()
@@ -16,8 +16,7 @@ ChunkRenderer::~ChunkRenderer()
 void ChunkRenderer::renderTick(Shader& shader, Camera3D camera, DirectRenderer& dr, float lag)
 {
     blockTexture.bind();
-    //int frustumCull1 = 0;
-    //int frustumCull2 = 0;
+    
     for(int x = 0; x < chunkX; x++)
     {
         for(int z = 0; z < chunkZ; z++)
@@ -38,19 +37,10 @@ void ChunkRenderer::renderTick(Shader& shader, Camera3D camera, DirectRenderer&
                     {
                         mesh[l + z * Chunk::HEIGHT_PARTIONS + x * chunkZ * Chunk::HEIGHT_PARTIONS].draw();
                     }
-                    //else
-                    //{
-                    //    frustumCull2++;
-                    //}
                 }
             }
-            //else
-            //{
-            //    frustumCull1 += 16;
-            //}
         }
     }
-    //cout << "CULL :" << frustumCull1 << " " << frustumCull2 << endl;
 }
 
 void ChunkRenderer::updateChunk(Chunk& c, Chunk* north, Chunk* east, Chunk* south, Chunk* west)

+ 1 - 1
client/rendering/ChunkRenderer.h

@@ -21,7 +21,7 @@ private:
     
     const int chunkX = 2;
     const int chunkZ = 2;
-    ChunkMesh* mesh;
+    NormalTextureMesh* mesh;
     
     Texture blockTexture;
 };

+ 18 - 0
client/rendering/block/BlockRenderer.cpp

@@ -10,6 +10,24 @@ void BlockRenderer::addTriangle(float p1x, float p1y, float p1z, float p1nx, flo
                                 float p3x, float p3y, float p3z, float p3nx, float p3ny, float p3nz, float p3texX, float p3texY, 
                                 int cullData)
 {
+    // move texture coords a small amount to the middle of the triagngle
+    // to prevent calculation errors getting out of the range of the texture
+    float f = 1.0f / 256.0f;
+    
+    float mid1x = (((p2texX + p3texX) * 0.5) - p1texX) * f;
+    float mid1y = (((p2texY + p3texY) * 0.5) - p1texY) * f;
+    float mid2x = (((p1texX + p3texX) * 0.5) - p2texX) * f;
+    float mid2y = (((p1texY + p3texY) * 0.5) - p2texY) * f;
+    float mid3x = (((p2texX + p1texX) * 0.5) - p3texX) * f;
+    float mid3y = (((p2texY + p1texY) * 0.5) - p3texY) * f;
+    
+    p1texX += mid1x;
+    p1texY += mid1y;
+    p2texX += mid2x;
+    p2texY += mid2y;
+    p3texX += mid3x;
+    p3texY += mid3y;
+    
     data.push_back(Triangle());
     Triangle& tri = data[data.size() - 1];
     

+ 216 - 0
client/rendering/entity/EntityRenderer.cpp

@@ -0,0 +1,216 @@
+#include "EntityRenderer.h"
+#include "../../../engine/Wrapper.h"
+#include "../../../engine/Utils.h"
+
+EntityRenderer::EntityRenderer() : texture("resources/skin.png")
+{
+    // head
+    addCuboid(0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 
+            0.125f, 0.0f, 0.25f, 0.125f,
+            0.25f, 0.0f, 0.375f, 0.125f,
+            0.25f, 0.125f, 0.375f, 0.25f,
+            0.0f, 0.125f, 0.125f, 0.25f,
+            0.125f, 0.125f, 0.25f, 0.25f,
+            0.375f, 0.125f, 0.5f, 0.25f);
+    // right arm
+    addCuboid(0.0f, 0.0f, 0.0f, 0.25f, 0.75f, 0.25f, 
+            0.6875f, 0.25f, 0.75f, 0.3125f,
+            0.75f, 0.25f, 0.8125f, 0.3125f,
+            0.75f, 0.3125f, 0.8125f, 0.5f,
+            0.625f, 0.3125f, 0.6875f, 0.5f,
+            0.6875f, 0.3125f, 0.75f, 0.5f,
+            0.8125f, 0.3125f, 0.875f, 0.5f);
+    // left arm
+    addCuboid(0.0f, 0.0f, 0.0f, 0.25f, 0.75f, 0.25f, 
+            0.5625f, 0.75f, 0.625f, 0.8125f,
+            0.625f, 0.75f, 0.6875f, 0.8125f,
+            0.625f, 0.8125f, 0.6875f, 1.0f,
+            0.5f, 0.8125f, 0.5625f, 1.0f,
+            0.5625f, 0.8125f, 0.625f, 1.0f,
+            0.6875f, 0.8125f, 0.75f, 1.0f);
+    // body
+    addCuboid(0.0f, 0.0f, 0.0f, 0.5f, 0.75f, 0.25f, 
+            0.3125f, 0.25f, 0.4375f, 0.3125f,
+            0.4375f, 0.25f, 0.5625f, 0.3125f,
+            0.4375f, 0.3125f, 0.5f, 0.5f,
+            0.25f, 0.3125f, 0.3125f, 0.5f,
+            0.3125f, 0.3125f, 0.4375f, 0.5f,
+            0.5f, 0.3125f, 0.625f, 0.5f);
+    // right leg
+    addCuboid(0.0f, 0.0f, 0.0f, 0.25f, 0.75f, 0.25f, 
+            0.0625f, 0.25f, 0.125f, 0.3125f,
+            0.125f, 0.25f, 0.1875f, 0.3125f,
+            0.125f, 0.3125f, 0.1875f, 0.5f,
+            0.0f, 0.3125f, 0.0625f, 0.5f,
+            0.0625f, 0.3125f, 0.125f, 0.5f,
+            0.1875f, 0.3125f, 0.25f, 0.5f);
+    // left leg
+    addCuboid(0.0f, 0.0f, 0.0f, 0.25f, 0.75f, 0.25f, 
+            0.3125f, 0.75f, 0.375f, 0.8125f,
+            0.375f, 0.75f, 0.4375f, 0.8125f,
+            0.375f, 0.8125f, 0.4375f, 1.0f,
+            0.25f, 0.8125f, 0.3125f, 1.0f,
+            0.3125f, 0.8125f, 0.375f, 1.0f,
+            0.4375f, 0.8125f, 0.5f, 1.0f);
+    mesh.build();
+}
+
+EntityRenderer::~EntityRenderer()
+{
+}
+
+void EntityRenderer::tick()
+{
+    lifetime += 15;
+}
+
+void EntityRenderer::renderTick(Shader& shader, Camera3D camera, DirectRenderer& dr, float lag)
+{
+    const int d = 360;
+    
+    float f1 = lifetime % d;
+    if(f1 >= d / 2)
+    {
+        f1 = d - f1;
+    }
+    
+    float f2 = (lifetime + 15) % d;
+    if(f2 >= d / 2)
+    {
+        f2 = d - f2;
+    }
+    
+    float inter = interpolate(lag, f1, f2);
+    
+    texture.bind();
+    
+    shader.setToIdentity();
+    shader.translateTo(0.0f, -10.0f, 0.0f);
+    
+    shader.push();
+    shader.translate(0.25f, 1.5f, 0.0f);
+    Engine::setWorldModelMatrix(shader.getModelMatrix()); 
+    mesh.draw(0, 36);
+    shader.pop();
+    
+    shader.push();
+    shader.translate(0.0f, 1.375f, 0.25f);
+    shader.rotateX(inter / 6 - 15);
+    shader.translate(0.0f, -0.625f, -0.125f);
+    Engine::setWorldModelMatrix(shader.getModelMatrix()); 
+    mesh.draw(36, 36);
+    shader.pop();
+    
+    shader.push();
+    shader.translate(0.75f, 1.375f, 0.25f);
+    shader.rotateX(- inter / 6 + 15);
+    shader.translate(0.0f, -0.625f, -0.125f);
+    Engine::setWorldModelMatrix(shader.getModelMatrix()); 
+    mesh.draw(72, 36);
+    shader.pop();
+    
+    shader.push();
+    shader.translate(0.25f, 0.75f, 0.125f);
+    Engine::setWorldModelMatrix(shader.getModelMatrix()); 
+    mesh.draw(108, 36);
+    shader.pop();
+    
+    shader.push();
+    shader.translate(0.25f, 0.0f, 0.125f);
+    Engine::setWorldModelMatrix(shader.getModelMatrix()); 
+    mesh.draw(144, 36);
+    shader.pop();
+    
+    shader.push();
+    shader.translate(0.5f, 0.0f, 0.125f);
+    Engine::setWorldModelMatrix(shader.getModelMatrix()); 
+    mesh.draw(180, 36);
+    shader.pop();
+}
+
+void EntityRenderer::addTriangle(float p1x, float p1y, float p1z, float p1nx, float p1ny, float p1nz, float p1texX, float p1texY, 
+                                float p2x, float p2y, float p2z, float p2nx, float p2ny, float p2nz, float p2texX, float p2texY, 
+                                float p3x, float p3y, float p3z, float p3nx, float p3ny, float p3nz, float p3texX, float p3texY)
+{
+    mesh.addPosition(p1x, p1y, p1z);
+    mesh.addPosition(p2x, p2y, p2z);
+    mesh.addPosition(p3x, p3y, p3z);
+    
+    mesh.addNormal(p1nx, p1ny, p1nz);
+    mesh.addNormal(p2nx, p2ny, p2nz);
+    mesh.addNormal(p3nx, p3ny, p3nz);
+    
+    mesh.addTexture(p1texX, p1texY);
+    mesh.addTexture(p2texX, p2texY);
+    mesh.addTexture(p3texX, p3texY);
+}
+
+void EntityRenderer::addCuboid(float sx, float sy, float sz, float ex, float ey, float ez,
+               float topTexStartX, float topTexStartY, float topTexEndX, float topTexEndY, 
+               float bottomTexStartX, float bottomTexStartY, float bottomTexEndX, float bottomTexEndY, 
+               float northTexStartX, float northTexStartY, float northTexEndX, float northTexEndY, 
+               float southTexStartX, float southTexStartY, float southTexEndX, float southTexEndY, 
+               float eastTexStartX, float eastTexStartY, float eastTexEndX, float eastTexEndY, 
+               float westTexStartX, float westTexStartY, float westTexEndX, float westTexEndY)
+{
+    // bottom side
+    addTriangle(
+            sx, sy, sz, 0.0f, -1.0f, 0.0f, bottomTexStartX, bottomTexStartY,
+            ex, sy, sz, 0.0f, -1.0f, 0.0f, bottomTexEndX, bottomTexStartY,
+            sx, sy, ez, 0.0f, -1.0f, 0.0f, bottomTexStartX, bottomTexEndY);
+    addTriangle(
+            ex, sy, sz, 0.0f, -1.0f, 0.0f, bottomTexEndX, bottomTexStartY,
+            ex, sy, ez, 0.0f, -1.0f, 0.0f, bottomTexEndX, bottomTexEndY,
+            sx, sy, ez, 0.0f, -1.0f, 0.0f, bottomTexStartX, bottomTexEndY);
+    
+    // top side
+    addTriangle(
+            sx, ey, sz, 0.0f, 1.0f, 0.0f, topTexStartX, topTexStartY,
+            sx, ey, ez, 0.0f, 1.0f, 0.0f, topTexStartX, topTexEndY,
+            ex, ey, sz, 0.0f, 1.0f, 0.0f, topTexEndX, topTexStartY);
+    addTriangle(
+            ex, ey, sz, 0.0f, 1.0f, 0.0f, topTexEndX, topTexStartY,
+            sx, ey, ez, 0.0f, 1.0f, 0.0f, topTexStartX, topTexEndY,
+            ex, ey, ez, 0.0f, 1.0f, 0.0f, topTexEndX, topTexEndY);
+    
+    // north side
+    addTriangle(
+            ex, sy, sz, 1.0f, 0.0f, 0.0f, northTexStartX, northTexEndY,
+            ex, ey, ez, 1.0f, 0.0f, 0.0f, northTexEndX, northTexStartY,
+            ex, sy, ez, 1.0f, 0.0f, 0.0f, northTexEndX, northTexEndY);
+    addTriangle(
+            ex, sy, sz, 1.0f, 0.0f, 0.0f, northTexStartX, northTexEndY,
+            ex, ey, sz, 1.0f, 0.0f, 0.0f, northTexStartX, northTexStartY,
+            ex, ey, ez, 1.0f, 0.0f, 0.0f, northTexEndX, northTexStartY);
+    
+    // south side
+    addTriangle(
+            sx, sy, sz, -1.0f, 0.0f, 0.0f, southTexStartX, southTexEndY,
+            sx, sy, ez, -1.0f, 0.0f, 0.0f, southTexEndX, southTexEndY,
+            sx, ey, ez, -1.0f, 0.0f, 0.0f, southTexEndX, southTexStartY);
+    addTriangle(
+            sx, sy, sz, -1.0f, 0.0f, 0.0f, southTexStartX, southTexEndY,
+            sx, ey, ez, -1.0f, 0.0f, 0.0f, southTexEndX, southTexStartY,
+            sx, ey, sz, -1.0f, 0.0f, 0.0f, southTexStartX, southTexStartY);
+    
+    // east side
+    addTriangle(
+            sx, sy, ez, 0.0f, 0.0f, 1.0f, eastTexStartX, eastTexEndY,
+            ex, sy, ez, 0.0f, 0.0f, 1.0f, eastTexEndX, eastTexEndY,
+            ex, ey, ez, 0.0f, 0.0f, 1.0f, eastTexEndX, eastTexStartY);
+    addTriangle(
+            sx, sy, ez, 0.0f, 0.0f, 1.0f, eastTexStartX, eastTexEndY,
+            ex, ey, ez, 0.0f, 0.0f, 1.0f, eastTexEndX, eastTexStartY,
+            sx, ey, ez, 0.0f, 0.0f, 1.0f, eastTexStartX, eastTexStartY);
+    
+    // west side
+    addTriangle(
+            sx, sy, sz, 0.0f, 0.0f, -1.0f, westTexStartX, westTexEndY,
+            ex, ey, sz, 0.0f, 0.0f, -1.0f, westTexEndX, westTexStartY,
+            ex, sy, sz, 0.0f, 0.0f, -1.0f, westTexEndX, westTexEndY);
+    addTriangle(
+            sx, sy, sz, 0.0f, 0.0f, -1.0f, westTexStartX, westTexEndY,
+            sx, ey, sz, 0.0f, 0.0f, -1.0f, westTexStartX, westTexStartY,
+            ex, ey, sz, 0.0f, 0.0f, -1.0f, westTexEndX, westTexStartY);
+}
+

+ 38 - 0
client/rendering/entity/EntityRenderer.h

@@ -0,0 +1,38 @@
+#ifndef ENTITYRENDERER_H
+#define ENTITYRENDERER_H
+
+#include "../../../engine/Shader.h"
+#include "../../../math/Camera3D.h"
+#include "../../../engine/DirectRenderer.h"
+#include "../../../engine/Mesh.h"
+#include "../../../engine/Texture.h"
+
+class EntityRenderer
+{
+public:
+    EntityRenderer();
+    virtual ~EntityRenderer();
+    
+    void tick();
+    void renderTick(Shader& shader, Camera3D camera, DirectRenderer& dr, float lag);
+    
+private:
+    void addTriangle(float p1x, float p1y, float p1z, float p1nx, float p1ny, float p1nz, float p1texX, float p1texY, 
+                float p2x, float p2y, float p2z, float p2nx, float p2ny, float p2nz, float p2texX, float p2texY, 
+                float p3x, float p3y, float p3z, float p3nx, float p3ny, float p3nz, float p3texX, float p3texY);
+    
+    void addCuboid(float sx, float sy, float sz, float ex, float ey, float ez,
+               float topTexStartX, float topTexStartY, float topTexEndX, float topTexEndY, 
+               float bottomTexStartX, float bottomTexStartY, float bottomTexEndX, float bottomTexEndY, 
+               float northTexStartX, float northTexStartY, float northTexEndX, float northTexEndY, 
+               float southTexStartX, float southTexStartY, float southTexEndX, float southTexEndY, 
+               float eastTexStartX, float eastTexStartY, float eastTexEndX, float eastTexEndY, 
+               float westTexStartX, float westTexStartY, float westTexEndX, float westTexEndY);
+    
+    Texture texture;
+    NormalTextureMesh mesh;
+    unsigned int lifetime = 0;
+};
+
+#endif
+

+ 6 - 0
engine/Clock.cpp

@@ -1,4 +1,5 @@
 #include "Clock.h"
+#include <iostream>
 
 Clock::Clock()
 {
@@ -32,3 +33,8 @@ double Clock::getUpdatesPerSecond() const
     return (1000000000.0 * (SIZE - 1)) / sum;
 }
 
+uint64_t Clock::getCurrentTime() const
+{
+    return time[(index - 1) & (SIZE - 1)];
+}
+

+ 1 - 0
engine/Clock.h

@@ -10,6 +10,7 @@ public:
     Clock(const Clock& orig);
     virtual ~Clock();
     
+    uint64_t getCurrentTime() const;
     void update();
     double getUpdatesPerSecond() const;
 private:

+ 21 - 12
engine/Mesh.cpp

@@ -52,10 +52,6 @@ Mesh::Mesh(int mode)
     glEnableVertexAttribArray(3);
 }
 
-Mesh::Mesh(const Mesh& orig)
-{
-}
-
 Mesh::~Mesh()
 {
     delete[] data;
@@ -115,22 +111,25 @@ void Mesh::addNormal(float nx, float ny, float nz)
     normalIndex++;
 }
 
-void Mesh::build()
+void Mesh::build(bool print)
 {
     glBindBuffer(GL_ARRAY_BUFFER, vbo);
    
     vertices = positionIndex;
     
-    /*cout << "______________" << vertices << " " << vertexSize << endl;
-    for(int i = 0; i < vertices; i++)
+    if(print)
     {
-        cout << "----------vert " << i << endl;
-        int index = i * vertexSize;
-        for(int j = 0; j < vertexSize; j++)
+        cout << "______________" << vertices << " " << vertexSize << endl;
+        for(int i = 0; i < vertices; i++)
         {
-            cout << data[index + j] << " " << endl;
+            cout << "----------vert " << i << endl;
+            int index = i * vertexSize;
+            for(int j = 0; j < vertexSize; j++)
+            {
+                cout << data[index + j] << " " << endl;
+            }
         }
-    }*/
+    }
     
     glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, data, GL_STATIC_DRAW);
     
@@ -151,3 +150,13 @@ void Mesh::draw()
     glDrawArrays(GL_TRIANGLES, 0, vertices);
 }
 
+void Mesh::draw(int start, int count)
+{
+    if(vertices == 0 || start < 0 || start >= vertices || start + count > vertices)
+    {
+        return;
+    }
+    glBindVertexArray(vba);
+    glBindBuffer(GL_ARRAY_BUFFER, vbo);
+    glDrawArrays(GL_TRIANGLES, start, count);
+}

+ 4 - 4
engine/Mesh.h

@@ -8,7 +8,6 @@ class Mesh
 {
 public:
     Mesh(int mode);
-    Mesh(const Mesh& orig);
     virtual ~Mesh();
     
     void addPosition(float x, float y, float z);
@@ -16,8 +15,9 @@ public:
     void addTexture(float tx, float ty);
     void addNormal(float nx, float ny, float nz);
     
-    void build();
+    void build(bool print = false);
     void draw();
+    void draw(int start, int count);
     
     static const int COLOR = 1;
     static const int TEXTURE = 2;
@@ -45,10 +45,10 @@ private:
     float* data = nullptr;
 };
 
-class ChunkMesh : public Mesh
+class NormalTextureMesh : public Mesh
 {
 public:
-    ChunkMesh() : Mesh(Mesh::TEXTURE | Mesh::NORMAL) {};
+    NormalTextureMesh() : Mesh(Mesh::TEXTURE | Mesh::NORMAL) {};
 };
 
 #endif

+ 37 - 11
engine/Wrapper.cpp

@@ -12,6 +12,7 @@ GLFWwindow* Engine::window = nullptr;
 int Engine::scale = 1;
 int Engine::width = 0;
 int Engine::height = 0;
+int Engine::resizeTicks = -1;
 
 // projection data
 float Engine::fovY = 60;
@@ -84,8 +85,7 @@ bool Engine::init(int width, int height, const char* name)
     glfwSetKeyCallback(window, onKeyEvent);
     glfwSetMouseButtonCallback(window, onMouseClick);
     glfwSetFramebufferSizeCallback(window, onWindowResize); 
-    //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
-    //glfwSetCursorPosCallback(window, onMouseMove);
+    glfwSetCursorPosCallback(window, onMouseMove);
     return true;
 }
 
@@ -136,7 +136,18 @@ void Engine::start(IClient* client)
                 lag -= NANOS_PER_TICK;
 
                 Engine::client->tick();           
-                ticksPerFrame++;
+                ticksPerFrame++;  
+                
+                resizeTicks -= (resizeTicks >= 0);
+                if(resizeTicks == 0)
+                {
+                    glViewport(0, 0, width, height);
+                    updateScale();
+                    worldShader.resize();
+                    ssaoShader.resize();
+                    ssaoBlurShader.resize();
+                    worldPostShader.resize();
+                }
 
                 if(ticksPerFrame >= MAX_TICKS_PER_FRAME)
                 {
@@ -158,8 +169,11 @@ void Engine::start(IClient* client)
                 if(lastFrame + NANOS_PER_FRAME - 1000000 < glfwGetTimerValue())
                 {
                     lastFrame = glfwGetTimerValue();
-                    onRenderTick((float) lag / NANOS_PER_TICK);
-                    glfwSwapBuffers(window);
+                    if(resizeTicks == -1)
+                    {
+                        onRenderTick((float) lag / NANOS_PER_TICK);
+                        glfwSwapBuffers(window);
+                    }
                 }
             }
 
@@ -187,6 +201,11 @@ void Engine::onKeyEvent(GLFWwindow* w, int key, int scancode, int action, int mo
     client->onKeyEvent(key, scancode, action, mods);
 }
 
+void Engine::onMouseMove(GLFWwindow* w, double x, double y)
+{
+    client->onMouseMove(x, y);
+}
+
 void Engine::onMouseClick(GLFWwindow* w, int button, int action, int mods)
 {
     client->onMouseClick(button, action, mods);
@@ -194,14 +213,9 @@ void Engine::onMouseClick(GLFWwindow* w, int button, int action, int mods)
 
 void Engine::onWindowResize(GLFWwindow* w, int width, int height)
 {
-    glViewport(0, 0, width, height);
     Engine::width = width;
     Engine::height = height;
-    updateScale();
-    worldShader.resize();
-    ssaoShader.resize();
-    ssaoBlurShader.resize();
-    worldPostShader.resize();
+    resizeTicks = 10;
 }
 
 void Engine::updateScale()
@@ -358,4 +372,16 @@ void Engine::setWorldModelMatrix(const float* data)
 void Engine::setOverlayModelMatrix(const float* data)
 {
     overlayShader.setModelMatrix(data);
+}
+
+void Engine::setMouseTrapped(bool mode)
+{
+    if(mode)
+    {
+        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+    }
+    else
+    {
+        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+    }
 }

+ 7 - 1
engine/Wrapper.h

@@ -24,6 +24,7 @@ public:
     virtual void render3DTick(float lag) = 0;
     virtual void render2DTick(float lag) = 0;
     virtual void onKeyEvent(int key, int scancode, int action, int mods) = 0;
+    virtual void onMouseMove(double x, double y) = 0;
     virtual void onMouseClick(int button, int action, int mods) = 0;
 };
 
@@ -36,6 +37,7 @@ public:
     void render3DTick(float lag) override { cout << "Dummy render3DTick" << endl; };
     void render2DTick(float lag) override { cout << "Dummy render3DTick" << endl; };
     void onKeyEvent(int key, int scancode, int action, int mods) override { cout << "Dummy onKeyEvent" << endl; };
+    void onMouseMove(double x, double y) override { cout << "Dummy onMouseMove" << endl; };
     void onMouseClick(int button, int action, int mods) override { cout << "Dummy onMouseClick" << endl; };
 private:
     DummyClient() {};
@@ -61,6 +63,8 @@ public:
     static void setWorldViewMatrix(const float* data);
     static void setWorldModelMatrix(const float* data);
     static void setOverlayModelMatrix(const float* data);
+    
+    static void setMouseTrapped(bool mode);
 
 private:
     static const uint64_t NANOS_PER_FRAME = 1000000000 / 60;
@@ -73,9 +77,10 @@ private:
     static void onRenderTick(float lag);
     
     static void onKeyEvent(GLFWwindow* w, int key, int scancode, int action, int mods);
+    static void onMouseMove(GLFWwindow* w, double x, double y);
     static void onMouseClick(GLFWwindow* w, int button, int action, int mods);
     static void onWindowResize(GLFWwindow* w, int width, int height);
-    
+
     static void updateScale();
     
     static IClient* client;    
@@ -85,6 +90,7 @@ private:
     static int scale;
     static int width;
     static int height;
+    static int resizeTicks;
     
     // projection data
     static float fovY;

+ 1 - 1
engine/shader/SSAOShader.h

@@ -31,7 +31,7 @@ private:
     GLuint texture = 0;
     GLuint noiseTexture = 0;
     // uniform data
-    int numberOfSamples = 48;
+    int numberOfSamples = 32;
     float radius = 1.5f;
     // uniforms locations
     GLint unifProjMatrix = 0;

+ 16 - 1
math/Camera3D.cpp

@@ -41,6 +41,11 @@ const Vector3D& Camera3D::getFlatDown() const
     return flatDown;
 }
 
+void Camera3D::addToOldLengthAngle(float f)
+{
+    oldLengthAngle += f;
+}
+
 void Camera3D::storePosition()
 {
     oldCamera.set(camera);
@@ -55,6 +60,9 @@ void Camera3D::setPosition(float x, float y, float z, float length, float width)
     widthAngle = width;
 }
 
+float old = 0;
+float current = 0;
+
 void Camera3D::update(float lag)
 {
     // -------------------------------------------------------------------------
@@ -63,7 +71,7 @@ void Camera3D::update(float lag)
     
     // front
     front.setAngles(interpolate(lag, oldLengthAngle, lengthAngle), interpolate(lag, oldWidthAngle, widthAngle));
-
+    
     // back
     back.setInverse(front);
 
@@ -193,6 +201,13 @@ const float* Camera3D::getViewMatrix()
 
 bool Camera3D::isInFrustum(float x, float y, float z, float x2, float y2, float z2) const
 {
+    // some tolerance
+    x -= 1;
+    y -= 1;
+    z -= 1;
+    x2 += 1;
+    y2 += 1;
+    z2 += 1;
     //return true;
     // http://cgvr.informatik.uni-bremen.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html
     // for each plane do ...

+ 2 - 0
math/Camera3D.h

@@ -13,6 +13,8 @@ public:
     
     bool isInFrustum(float x, float y, float z, float x2, float y2, float z2) const;
     
+    void addToOldLengthAngle(float f);
+    
     void storePosition();
     void setPosition(float x, float y, float z, float length, float width);
     

BIN
resources/skin.png


+ 1 - 4
shader/ssaoBlurFragment.fs

@@ -24,8 +24,5 @@ void main()
         }
     }
     result /= (radius * radius * 4);
-    color = result;//texture(worldColorSamp, varTextureCoord) * vec4(result, result, result, 1);
-
-    //float occ = texture(ssaoSamp, varTextureCoord).r;
-    //color = texture(worldColorSamp, varTextureCoord) * vec4(occ, occ, occ, 1);
+    color = result;
 }