Browse Source

post effects by drawing into framebuffer (blending does not work yet),
general mesh

Kajetan Johannes Hammerle 6 years ago
parent
commit
1adc6a5773
18 changed files with 544 additions and 265 deletions
  1. 1 1
      MainClient.cpp
  2. 1 4
      Makefile
  3. 12 9
      client/Client.cpp
  4. 3 0
      client/Client.h
  5. 105 33
      engine/Mesh.cpp
  6. 23 2
      engine/Mesh.h
  7. 21 3
      engine/Shader.cpp
  8. 2 0
      engine/Shader.h
  9. 0 79
      engine/TextureMesh.cpp
  10. 0 30
      engine/TextureMesh.h
  11. 136 18
      engine/Wrapper.cpp
  12. 19 4
      engine/Wrapper.h
  13. 1 0
      shader/fragment.fs
  14. 11 0
      shader/postFragment.fs
  15. 12 0
      shader/postVertex.vs
  16. 15 0
      shader/vertex.vs
  17. 162 73
      world/Chunk.cpp
  18. 20 9
      world/Chunk.h

+ 1 - 1
MainClient.cpp

@@ -12,7 +12,7 @@ int main(int argc, char** argv)
        return 0; 
     }
     Client client;
-    Engine::start(client);
+    Engine::start(&client);
     return 0;
 }
 

+ 1 - 4
Makefile

@@ -8,7 +8,7 @@ run_client: game_client
 	vblank_mode=0 optirun ./game_client
 	
 game_client: MainClient.cpp\
-	Clock.o DirectRenderer.o KeyManager.o Mesh.o MouseManager.o Shader.o Texture.o TextureMesh.o Utils.o Wrapper.o\
+	Clock.o DirectRenderer.o KeyManager.o Mesh.o MouseManager.o Shader.o Texture.o Utils.o Wrapper.o\
 	Matrix3D.o Matrix3DStack.o StackOverflow.o StackUnderflow.o Vector3D.o\
 	Client.o\
 	Chunk.o
@@ -39,9 +39,6 @@ Shader.o: engine/Shader.cpp engine/Shader.h
 Texture.o: engine/Texture.cpp engine/Texture.h
 	g++ $(VERSION) -c engine/Texture.cpp -o $@
 
-TextureMesh.o: engine/TextureMesh.cpp engine/TextureMesh.h
-	g++ $(VERSION) -c engine/TextureMesh.cpp -o $@
-	
 Utils.o: engine/Utils.cpp engine/Utils.h
 	g++ $(VERSION) -c engine/Utils.cpp -o $@
 	

+ 12 - 9
client/Client.cpp

@@ -3,7 +3,7 @@
 
 using namespace std;
 
-Client::Client()
+Client::Client() : chunk(0, 0)
 {    
     position.set(0, 0, -2);
     shader.setCamera(position.getX(), position.getY(), position.getZ(), 0, 0);
@@ -34,11 +34,6 @@ void Client::tick()
 {
     tps.update();
         
-    if(mouseManager.isDown(MOUSE_LEFT))
-    {
-        cout << mouseManager.getDownTime(MOUSE_LEFT) << endl;
-    }
-    
     oldTicker = ticker;
     ticker += 1;
     if(ticker >= 360)
@@ -49,7 +44,7 @@ void Client::tick()
     
     shader.storeCamera();
     
-    float factor = 0.125f;
+    float factor = 0.5f;
     if(keyManager.isDown(KEY_LEFT))
     {
         position.addMul(shader.getLeft(), factor);
@@ -102,16 +97,24 @@ void Client::renderTick(float lag)
 {
     fps.update();
     
+    shader.set3DMode(lag);
+    shader.setToIdentity();
+    shader.updateModelMatrix();
+    shader.setColorEnabled(true);
+    shader.setTextureEnabled(false);
+    shader.setUseBlending(false);
+    shader.setNormalsEnabled(true);
+    chunk.renderTick(shader, directRenderer, lag);
+    
     shader.set2DMode();
     shader.setToIdentity();
-    shader.translateTo(200, 200, 0);
-    shader.rotateZ(interpolate(lag, oldTicker, ticker));
     shader.updateModelMatrix();
     shader.setTextMode();
     
     string wusi;
     float y = 30;
     wusi = "FPS: " + to_string(fps.getUpdatesPerSecond());
+    y = directRenderer.drawString(30, y, false, wusi);
     y = directRenderer.drawString(30, y, true, wusi);
 }
 

+ 3 - 0
client/Client.h

@@ -7,6 +7,7 @@
 #include "../engine/Clock.h"
 #include "../engine/Shader.h"
 #include "../engine/DirectRenderer.h"
+#include "../world/Chunk.h"
 
 using namespace std;
 
@@ -41,6 +42,8 @@ private:
     KeyManager keyManager;
     MouseManager mouseManager;
     
+    Chunk chunk;
+    
     Shader shader;
     DirectRenderer directRenderer;
 

+ 105 - 33
engine/Mesh.cpp

@@ -6,70 +6,142 @@ using namespace std;
 
 Mesh::Mesh()
 {
-    data = new float[dataSize * 7];
 }
 
-Mesh::Mesh(const Mesh& orig)
-{
-}
-
-Mesh::~Mesh()
-{
-    delete[] data;
-    glDeleteVertexArrays(1, &vba);
-    glDeleteBuffers(1, &vbo);
-}
-
-void Mesh::init()
+Mesh::Mesh(int mode)
 {
+    // position
+    positionStartIndex = vertexSize;
+    vertexSize += 3;
+    
+    // color
+    if(mode & COLOR)
+    {
+        colorStartIndex = vertexSize;
+        vertexSize += 4;
+    }
+    
+    // texture
+    if(mode & TEXTURE)
+    {
+        textureStartIndex = vertexSize;
+        vertexSize += 2;
+    }
+    
+    // normal
+    if(mode & NORMAL)
+    {
+        normalStartIndex = vertexSize;
+        vertexSize += 3;
+    }
+    
+    data = new float[dataSize * vertexSize];
+    
     glGenVertexArrays(1, &vba);
     glBindVertexArray(vba);
     
     glGenBuffers(1, &vbo);
     glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
-    glVertexAttribPointer(0, 3, GL_FLOAT, 0, 28, (GLvoid*) 0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, 0, sizeof(float) * vertexSize, (GLvoid*) (sizeof(float) * positionStartIndex));
     glEnableVertexAttribArray(0);
 
-    glVertexAttribPointer(1, 4, GL_FLOAT, 0, 28, (GLvoid*) 12);
-    glEnableVertexAttribArray(1);       
+    glVertexAttribPointer(1, 4, GL_FLOAT, 0, sizeof(float) * vertexSize, (GLvoid*) (sizeof(float) * colorStartIndex));
+    glEnableVertexAttribArray(1);     
+    
+    glVertexAttribPointer(2, 2, GL_FLOAT, 0, sizeof(float) * vertexSize, (GLvoid*) (sizeof(float) * textureStartIndex));
+    glEnableVertexAttribArray(2);  
+    
+    glVertexAttribPointer(3, 3, GL_FLOAT, 0, sizeof(float) * vertexSize, (GLvoid*) (sizeof(float) * normalStartIndex));
+    glEnableVertexAttribArray(3);
+}
+
+Mesh::Mesh(const Mesh& orig)
+{
 }
 
-void Mesh::addPoint(float x, float y, float z, float r, float g, float b, float a)
+Mesh::~Mesh()
 {
-    if(vertices >= dataSize)
+    delete[] data;
+    glDeleteVertexArrays(1, &vba);
+    glDeleteBuffers(1, &vbo);
+}
+
+void Mesh::ensureCapacity(unsigned int index)
+{
+    if(index >= dataSize)
     {
-        float* newData = new float[dataSize * 2 * 7];
-        memcpy(newData, data, sizeof(float) * dataSize * 7);
+        float* newData = new float[dataSize * 2 * vertexSize];
+        memcpy(newData, data, sizeof(float) * dataSize * vertexSize);
         delete[] data;
         data = newData;
         dataSize *= 2;
     }
-    unsigned int index = vertices * 7;
+}
+
+void Mesh::addPosition(float x, float y, float z)
+{
+    ensureCapacity(positionIndex);
+    unsigned int index = positionStartIndex +  positionIndex * vertexSize;
     data[index] = x;
     data[index + 1] = y;
     data[index + 2] = z;
-    data[index + 3] = r;
-    data[index + 4] = g;
-    data[index + 5] = b;
-    data[index + 6] = a;
-    
-    vertices++;
+    positionIndex++;
+}
+
+void Mesh::addColor(float r, float g, float b, float a)
+{
+    ensureCapacity(colorIndex);
+    unsigned int index = colorStartIndex +  colorIndex * vertexSize;
+    data[index] = r;
+    data[index + 1] = g;
+    data[index + 2] = b;
+    data[index + 3] = a;
+    colorIndex++;
+}
+
+void Mesh::addTexture(float tx, float ty)
+{
+    ensureCapacity(textureIndex);
+    unsigned int index = textureStartIndex +  textureIndex * vertexSize;
+    data[index] = tx;
+    data[index + 1] = ty;
+    textureIndex++;
+}
+
+void Mesh::addNormal(float nx, float ny, float nz)
+{
+    ensureCapacity(normalIndex);
+    unsigned int index = normalStartIndex +  normalIndex * vertexSize;
+    data[index] = nx;
+    data[index + 1] = ny;
+    data[index + 2] = nz;
+    normalIndex++;
 }
 
 void Mesh::build()
 {
     glBindBuffer(GL_ARRAY_BUFFER, vbo);
    
-    /*for(int i = 0; i < vertices; i++)
+    vertices = positionIndex;
+    
+    /*cout << "______________" << vertices << " " << vertexSize << endl;
+    for(int i = 0; i < vertices; i++)
     {
-        int index = i * 7;
-        cout << data[index] << " " << data[index + 1] << " " << data[index + 2] 
-                << " " << data[index + 3] << " " << data[index + 4]  << " " 
-                << data[index + 5] << " " << data[index + 6] << 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) * 7 * vertices, data, GL_STATIC_DRAW);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, data, GL_STATIC_DRAW);
+    
+    positionIndex = 0;
+    colorIndex = 0;
+    textureIndex = 0;
+    normalIndex = 0;
 }
 
 void Mesh::draw()

+ 23 - 2
engine/Mesh.h

@@ -8,17 +8,38 @@ class Mesh
 {
 public:
     Mesh();
+    Mesh(int mode);
     Mesh(const Mesh& orig);
     virtual ~Mesh();
     
-    void init();
-    void addPoint(float x, float y, float z, float r, float g, float b, float a);
+    void addPosition(float x, float y, float z);
+    void addColor(float r, float g, float b, float a);
+    void addTexture(float tx, float ty);
+    void addNormal(float nx, float ny, float nz);
+    
     void build();
     void draw();
+    
+    static const int COLOR = 1;
+    static const int TEXTURE = 2;
+    static const int NORMAL = 4;
 private:
+    void ensureCapacity(unsigned int index);
+    
     GLuint vba = 0;
     GLuint vbo = 0;
     
+    unsigned int positionStartIndex = 0;
+    unsigned int colorStartIndex = 0;
+    unsigned int textureStartIndex = 0;
+    unsigned int normalStartIndex = 0;
+    
+    unsigned int positionIndex = 0;
+    unsigned int colorIndex = 0;
+    unsigned int textureIndex = 0;
+    unsigned int normalIndex = 0;
+    
+    unsigned int vertexSize = 0;
     unsigned int vertices = 0;
     unsigned int dataSize = 3;
     float* data = nullptr;

+ 21 - 3
engine/Shader.cpp

@@ -13,6 +13,7 @@ Shader::Shader()
     unifUseColor = Engine::getUniformLocation("useColor");
     unifUseMixColor = Engine::getUniformLocation("useMixColor");
     unifMixColorLoc = Engine::getUniformLocation("mixColor");
+    unifUseNormals = Engine::getUniformLocation("useNormals");
 }
 
 Shader::Shader(const Shader& orig)
@@ -118,12 +119,23 @@ void Shader::set2DMode()
     
     int scale = Engine::getScale();
     view.set(0, 0, (2.0f * scale) / Engine::getWidth());
-    view.set(1, 1, (-2.0f * scale) / Engine::getHeight());
-    view.set(2, 2, (-1.0f * scale) / Engine::getHeight());
-    
+    view.set(0, 1, 0.0f);
+    view.set(0, 2, 0.0f);
     view.set(0, 3, -1.0f);
+    
+    view.set(1, 0, 0.0f);
+    view.set(1, 1, (-2.0f * scale) / Engine::getHeight());
+    view.set(1, 2, 0.0f);
     view.set(1, 3, 1.0f);
+    
+    view.set(2, 0, 0.0f);
+    view.set(2, 1, 0.0f);
+    view.set(2, 2, (-1.0f * scale) / Engine::getHeight());
     view.set(2, 3, 0.5f);
+    
+    view.set(3, 0, 0.0f);
+    view.set(3, 1, 0.0f);
+    view.set(3, 0, 0.0f);
     view.set(3, 3, 1.0f);
     
     Engine::setMatrix(unifViewMatrix, view.getValues());
@@ -199,6 +211,12 @@ void Shader::setTextMode()
     setColorEnabled(true);
     setUseBlending(true);
     setMixColorEnabled(false);
+    setNormalsEnabled(false);
+}
+
+void Shader::setNormalsEnabled(bool use)
+{
+    Engine::setInt(unifUseNormals, use);
 }
 
 void Shader::setUseBlending(bool use)

+ 2 - 0
engine/Shader.h

@@ -30,6 +30,7 @@ public:
     void setMixColorEnabled(bool use);
     void setMixColor(float r, float g, float b, float a);
     void setTextMode();
+    void setNormalsEnabled(bool use);
     
     void setUseBlending(bool use);
     
@@ -80,6 +81,7 @@ private:
     int unifUseColor = 0;
     int unifUseMixColor = 0;
     int unifMixColorLoc = 0;
+    int unifUseNormals = 0;
 };
 
 #endif

+ 0 - 79
engine/TextureMesh.cpp

@@ -1,79 +0,0 @@
-#include "TextureMesh.h"
-#include <cstring>
-#include <iostream>
-
-using namespace std;
-
-TextureMesh::TextureMesh()
-{
-    data = new float[dataSize * 5];
-}
-
-TextureMesh::TextureMesh(const TextureMesh& orig)
-{
-}
-
-TextureMesh::~TextureMesh()
-{
-    delete[] data;
-    glDeleteVertexArrays(1, &vba);
-    glDeleteBuffers(1, &vbo);
-}
-
-void TextureMesh::init()
-{
-    glGenVertexArrays(1, &vba);
-    glBindVertexArray(vba);
-    
-    glGenBuffers(1, &vbo);
-    glBindBuffer(GL_ARRAY_BUFFER, vbo);
-
-    glVertexAttribPointer(0, 3, GL_FLOAT, 0, 20, (GLvoid*) 0);
-    glEnableVertexAttribArray(0);
-
-    glVertexAttribPointer(2, 2, GL_FLOAT, 0, 20, (GLvoid*) 12);
-    glEnableVertexAttribArray(2);       
-}
-
-void TextureMesh::addPoint(float x, float y, float z, float tx, float ty)
-{
-    if(vertices >= dataSize)
-    {
-        float* newData = new float[dataSize * 2 * 5];
-        memcpy(newData, data, sizeof(float) * dataSize * 5);
-        delete[] data;
-        data = newData;
-        dataSize *= 2;
-    }
-    unsigned int index = vertices * 5;
-    data[index] = x;
-    data[index + 1] = y;
-    data[index + 2] = z;
-    data[index + 3] = tx;
-    data[index + 4] = ty;
-    
-    vertices++;
-}
-
-void TextureMesh::build()
-{
-    glBindBuffer(GL_ARRAY_BUFFER, vbo);
-   
-    /*for(int i = 0; i < vertices; i++)
-    {
-        int index = i * 7;
-        cout << data[index] << " " << data[index + 1] << " " << data[index + 2] 
-                << " " << data[index + 3] << " " << data[index + 4]  << " " 
-                << data[index + 5] << " " << data[index + 6] << endl;
-    }*/
-    
-    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 5 * vertices, data, GL_STATIC_DRAW);
-}
-
-void TextureMesh::draw()
-{
-    glBindVertexArray(vba);
-    glBindBuffer(GL_ARRAY_BUFFER, vbo);
-    glDrawArrays(GL_TRIANGLES, 0, vertices);
-}
-

+ 0 - 30
engine/TextureMesh.h

@@ -1,30 +0,0 @@
-#ifndef TEXTUREMESH_H
-#define TEXTUREMESH_H
-
-#include <GL/glew.h>
-#include <GLFW/glfw3.h>
-
-class TextureMesh
-{
-public:
-    TextureMesh();
-    TextureMesh(const TextureMesh& orig);
-    virtual ~TextureMesh();
-    
-    void init();
-    void addPoint(float x, float y, float z, float tx, float ty);
-    void build();
-    void draw();
-private:
-    GLuint vba = 0;
-    GLuint vbo = 0;
-    
-    unsigned int vertices = 0;
-    unsigned int dataSize = 3;
-    float* data = nullptr;
-};
-
-#endif
-
-
-

+ 136 - 18
engine/Wrapper.cpp

@@ -9,9 +9,20 @@ DummyClient DummyClient::dummy;
 
 IClient* Engine::client = &DummyClient::dummy;
 GLFWwindow* Engine::window = nullptr;
+
 GLuint Engine::vShader = 0;
 GLuint Engine::fShader = 0;
 GLuint Engine::program = 0;
+
+GLuint Engine::postVba = 0;
+GLuint Engine::postVbo = 0;
+GLuint Engine::postVShader = 0;
+GLuint Engine::postFShader = 0;
+GLuint Engine::postProgram = 0;
+
+GLuint Engine::frameBuffer = 0;
+GLuint Engine::frameTexture = 0;
+GLuint Engine::renderBuffer = 0;
 int Engine::scale = 1;
 int Engine::width = 0;
 int Engine::height = 0;
@@ -54,7 +65,8 @@ bool Engine::init(int width, int height, const char* name)
 
     vShader = 0;
     fShader = 0;
-    program = createProgram(vShader, program);
+    program = createProgram("shader/vertex.vs", "shader/fragment.fs", vShader, program);
+    
     if(program == 0)
     {
         if(vShader != 0)
@@ -69,7 +81,26 @@ bool Engine::init(int width, int height, const char* name)
         glfwTerminate();
         return false;
     }
-
+    
+    postVShader = 0;
+    postFShader = 0;
+    postProgram = createProgram("shader/postVertex.vs", "shader/postFragment.fs", postVShader, postFShader);
+    
+    if(postProgram == 0)
+    {
+        if(postVShader != 0)
+        {
+            glDeleteShader(postVShader);
+        }
+        if(postFShader != 0)
+        {
+            glDeleteShader(postFShader);
+        }
+        glfwDestroyWindow(window);
+        glfwTerminate();
+        return false;
+    }
+    
     glfwSetKeyCallback(window, onKeyEvent);
     glfwSetMouseButtonCallback(window, onMouseClick);
     glfwSetFramebufferSizeCallback(window, onWindowResize); 
@@ -78,12 +109,17 @@ bool Engine::init(int width, int height, const char* name)
     return true;
 }
 
-void Engine::start(IClient& client)
+void Engine::start(IClient* client)
 {
-    Engine::client = &client;
+    if(client != nullptr)
+    {
+        Engine::client = client;
+    }
     
+    generateFramebuffer();
+    generatePostData();
+
     glEnable(GL_CULL_FACE);
-    glEnable(GL_DEPTH_TEST);
     glDepthFunc(GL_LEQUAL);
     
     uint64_t newTime = glfwGetTimerValue();
@@ -91,8 +127,6 @@ void Engine::start(IClient& client)
     uint64_t lag = 0;
     while(!glfwWindowShouldClose(window))
     {
-        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
         oldTime = newTime;
         newTime = glfwGetTimerValue();
         lag += newTime - oldTime;
@@ -117,15 +151,35 @@ void Engine::start(IClient& client)
             }
         }
 
+        // draw scene in framebuffer
+        glUseProgram(program);
+        glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        glEnable(GL_DEPTH_TEST);
         Engine::client->renderTick((float) lag / NANOS_PER_TICK);
+        
+        // draw textured framebuffer
+        glUseProgram(postProgram);
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        glDisable(GL_DEPTH_TEST);
+        glBindTexture(GL_TEXTURE_2D, frameTexture);
+        glBindVertexArray(postVba);
+        glBindBuffer(GL_ARRAY_BUFFER, postVbo);
+        glDrawArrays(GL_TRIANGLES, 0, 6);
 
         glfwSwapBuffers(window);
         glfwPollEvents();
     }
     
+    destroyPostData();
+    glDeleteFramebuffers(1, &frameBuffer);
     glDeleteShader(vShader);
     glDeleteShader(fShader);
     glDeleteProgram(program);
+    glDeleteShader(postVShader);
+    glDeleteShader(postFShader);
+    glDeleteProgram(postProgram);
     glfwDestroyWindow(window);
     glfwTerminate();
 }
@@ -210,10 +264,10 @@ bool Engine::checkShaderErrors(const char* name, GLuint shader)
     return returnValue;
 }
 
-GLuint Engine::compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* vertex, const GLchar* fragment)
+GLuint Engine::compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* v, const GLchar* f)
 {
     vShader = glCreateShader(GL_VERTEX_SHADER);
-    glShaderSource(vShader, 1, &vertex, nullptr);
+    glShaderSource(vShader, 1, &v, nullptr);
     glCompileShader(vShader);
 
     if(checkShaderErrors("vertex", vShader))
@@ -222,7 +276,7 @@ GLuint Engine::compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* ve
     }    
     
     fShader = glCreateShader(GL_FRAGMENT_SHADER);
-    glShaderSource(fShader, 1, &fragment, nullptr);
+    glShaderSource(fShader, 1, &f, nullptr);
     glCompileShader(fShader);
 
     if(checkShaderErrors("fragment", fShader))
@@ -266,23 +320,21 @@ GLuint Engine::compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* ve
         cout << buffer << endl;
         return 0;
     }
-    
-    glUseProgram(program);
     return program;
 }
 
-GLuint Engine::createProgram(GLuint& vShader, GLuint& fShader)
+GLuint Engine::createProgram(const char* v, const char* f, GLuint& vShader, GLuint& fShader)
 {
-    GLchar* vertex = readFile("shader/vertex.vs");
+    GLchar* vertex = readFile(v);
     if(vertex == nullptr)
     {
-        cout << "cannot read vertex.vs" << endl;
+        cout << "cannot read " << v << endl;
         return 0;
     }
-    GLchar* fragment = readFile("shader/fragment.fs");
+    GLchar* fragment = readFile(f);
     if(fragment == nullptr)
     {
-        cout << "cannot read fragment.fs" << endl;
+        cout << "cannot read " << f << endl;
         delete[] vertex;
         return 0;
     }
@@ -361,7 +413,7 @@ void Engine::printError()
     switch(error)
     {
         case GL_NO_ERROR: 
-            cout << "> No error has been recorded." << endl;
+            //cout << "> No error has been recorded." << endl;
             break;
         case GL_INVALID_ENUM: 
             cout << "> An unacceptable value is specified for an enumerated argument." << endl;
@@ -387,4 +439,70 @@ void Engine::printError()
         default:
             cout << "> Unknown OpenGL error: " << error << endl;
     }
+}
+
+void Engine::generateFramebuffer()
+{
+    glGenFramebuffers(1, &frameBuffer);
+    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); 
+    
+    glGenTextures(1, &frameTexture);
+    glBindTexture(GL_TEXTURE_2D, frameTexture);
+    
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameTexture, 0);  
+    
+    glGenRenderbuffers(1, &renderBuffer);
+    glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); 
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);  
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);
+    
+    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+    {
+	cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
+    }
+    else
+    {
+        cout << "WORKS" << endl;
+    }
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void Engine::generatePostData()
+{
+    glGenVertexArrays(1, &postVba);
+    glBindVertexArray(postVba);
+    
+    glGenBuffers(1, &postVbo);
+    glBindBuffer(GL_ARRAY_BUFFER, postVbo);
+
+    glVertexAttribPointer(0, 2, GL_FLOAT, 0, sizeof(float) * 4, (GLvoid*) 0);
+    glEnableVertexAttribArray(0);
+
+    glVertexAttribPointer(1, 2, GL_FLOAT, 0, sizeof(float) * 4, (GLvoid*) (sizeof(float) * 2));
+    glEnableVertexAttribArray(1);
+    
+    float data[] = 
+    {
+        -1.0f, 1.0f, 0.0f, 1.0f, 
+        -1.0f, -1.0f, 0.0f, 0.0f,
+        1.0f, -1.0f, 1.0f, 0.0f,
+        -1.0f, 1.0f, 0.0f, 1.0f,
+        1.0f, -1.0f, 1.0f, 0.0f,
+        1.0f, 1.0f, 1.0f, 1.0f
+    };
+    
+    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 24, data, GL_STATIC_DRAW);
+}
+
+void Engine::destroyPostData()
+{
+    glDeleteVertexArrays(1, &postVba);
+    glDeleteBuffers(1, &postVbo);
 }

+ 19 - 4
engine/Wrapper.h

@@ -34,10 +34,10 @@ class Engine
 {
 public:
     static bool init(int width, int height, const char* name);
-    static void start(IClient& client);
+    static void start(IClient* client);
     static void stop();
     
-    void printError();
+    static void printError();
     
     static int getScale();
     static int getWidth();
@@ -51,10 +51,14 @@ private:
     static const uint64_t NANOS_PER_TICK = 50000000;
     static const int MAX_TICKS_PER_FRAME = 5;
     
+    static void generateFramebuffer();
+    static void generatePostData();
+    static void destroyPostData();
+    
     static GLchar* readFile(const char* name);
     static bool checkShaderErrors(const char* name, GLuint shader);
-    static GLuint compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* vertex, const GLchar* fragment);
-    static GLuint createProgram(GLuint& vShader, GLuint& fShader);
+    static GLuint compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* v, const GLchar* f);
+    static GLuint createProgram(const char* v, const char* f, GLuint& vShader, GLuint& fShader);
     
     static void onKeyEvent(GLFWwindow* w, int key, int scancode, int action, int mods);
     static void onMouseClick(GLFWwindow* w, int button, int action, int mods);
@@ -64,9 +68,20 @@ private:
     
     static IClient* client;    
     static GLFWwindow* window;   
+    
     static GLuint vShader;
     static GLuint fShader;
     static GLuint program;
+    
+    static GLuint postVba;
+    static GLuint postVbo;
+    static GLuint postVShader;
+    static GLuint postFShader;
+    static GLuint postProgram;
+    
+    static GLuint frameBuffer;
+    static GLuint frameTexture;
+    static GLuint renderBuffer;
     static int scale;
     static int width;
     static int height;

+ 1 - 0
shader/fragment.fs

@@ -10,6 +10,7 @@ uniform bool useTexture;
 uniform bool useColor;
 uniform bool useMixColor;
 uniform vec4 mixColor;
+uniform bool useNormals;
 
 in vec2 tc;
 in vec4 outColor;

+ 11 - 0
shader/postFragment.fs

@@ -0,0 +1,11 @@
+#version 430
+
+uniform sampler2D samp;
+
+in vec2 tc;
+out vec4 color;
+
+void main(void)
+{
+    color = texture(samp, tc);
+}

+ 12 - 0
shader/postVertex.vs

@@ -0,0 +1,12 @@
+#version 430
+
+layout (location = 0) in vec2 pos;
+layout (location = 1) in vec2 tex;
+
+out vec2 tc;
+
+void main(void)
+{ 
+    gl_Position = vec4(pos, 0.0, 1.0);
+    tc = tex;
+}

+ 15 - 0
shader/vertex.vs

@@ -3,6 +3,7 @@
 layout (location = 0) in vec3 pos;
 layout (location = 1) in vec4 color;
 layout (location = 2) in vec2 tex;
+layout (location = 3) in vec3 normal;
 
 uniform sampler2D samp;
 
@@ -14,6 +15,7 @@ uniform bool useTexture;
 uniform bool useColor;
 uniform bool useMixColor;
 uniform vec4 mixColor;
+uniform bool useNormals;
 
 out vec2 tc;
 out vec4 outColor;
@@ -22,5 +24,18 @@ void main(void)
 { 
     tc = tex; 
     outColor = color;
+
+    if(useNormals)
+    {
+        if(abs(normal.x) == 1)
+        {
+            outColor = outColor * 0.5;
+        }
+        if(abs(normal.z) == 1)
+        {
+            outColor = outColor * 0.75;
+        }
+    }
+    
     gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(pos, 1.0);
 }

+ 162 - 73
world/Chunk.cpp

@@ -1,18 +1,21 @@
 #include "Chunk.h"
+#include <cstdlib>
 
 Chunk::Chunk(int chunkX, int chunkZ) : chunkX(chunkX), chunkZ(chunkZ)
 {
-    for(int i = 0; i < WORLD_HIGH; i++)
+    mesh = new Mesh*[HEIGHT_PARTIONS];
+    for(int i = 0; i < HEIGHT_PARTIONS; i++)
     {
+        mesh[i] = new Mesh(Mesh::COLOR | Mesh::NORMAL);
         dirty[i] = true;
     }
-    for(int y = 0; y < MAX_Y; y++)
+    for(int y = 0; y < HEIGHT; y++)
     {
-        for(int x = 0; x < CHUNK_SIZE; x++)
+        for(int x = 0; x < WIDTH; x++)
         {
-            for(int z = 0; z < CHUNK_SIZE; z++)
+            for(int z = 0; z < DEPTH; z++)
             {
-                blocks[y][x][z] = 0;
+                blocks[y][x][z] = (rand() < RAND_MAX / 2);
             }
         }
     }
@@ -24,92 +27,178 @@ Chunk::Chunk(const Chunk& orig)
 
 Chunk::~Chunk()
 {
+    for(int i = 0; i < HEIGHT_PARTIONS; i++)
+    {
+        delete mesh[i];
+    }
+    delete[] mesh;
 }
 
 void Chunk::setBlock(int x, int y, int z, unsigned short block)
 {
-    if(x >= 0 && x < CHUNK_SIZE && y >= 0 && y < MAX_Y && z >= 0 && z < CHUNK_SIZE)
-    {
-        blocks[y][x][z] = block;
-    }
+    blocks[y & BITMASK_HEIGHT][x & BITMASK_WIDTH][z & BITMASK_DEPTH] = block;
 }
 
 unsigned short Chunk::getBlock(int x, int y, int z)
 {
-    if(x >= 0 && x < CHUNK_SIZE && y >= 0 && y < MAX_Y && z >= 0 && z < CHUNK_SIZE)
-    {
-        return blocks[y][x][z];
-    }
-    return 0;
+    return blocks[y & BITMASK_HEIGHT][x & BITMASK_WIDTH][z & BITMASK_DEPTH];
 }
 
-void Chunk::init()
+void Chunk::renderTick(Shader& shader, DirectRenderer& dr, float lag)
 {
-    for(int i = 0; i < WORLD_HIGH; i++)
+    for(int i = 0; i < HEIGHT_PARTIONS; i++)
     {
-        mesh[i].init();
+        if(dirty[i])
+        {
+            buildChunk(i);
+            dirty[i] = false;
+        }
+        mesh[i]->draw();
     }
 }
 
-void Chunk::renderTick(float lag)
-{
-    for(int i = 0; i < WORLD_HIGH; i++)
+void Chunk::buildChunk(int partionY)
+{    
+    cout << "BUILD " << partionY << endl;
+    Mesh& m = *mesh[partionY];
+    
+    for(int y = 0; y < HEIGHT; y++)
     {
-        if(dirty[i])
+        for(int x = 0; x < WIDTH; x++)
         {
-            mesh[i].build();
-            /*
-             // bottom
-    tmesh.addPoint(0.0f, 0.0f, 0.0f, 0.125f, 0.0f);
-    tmesh.addPoint(1.0f, 0.0f, 0.0f, 0.1875f, 0.0f);
-    tmesh.addPoint(0.0f, 0.0f, 1.0f, 0.125f, 0.0625f);
-    tmesh.addPoint(1.0f, 0.0f, 0.0f, 0.1875f, 0.0f);
-    tmesh.addPoint(1.0f, 0.0f, 1.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(0.0f, 0.0f, 1.0f, 0.125f, 0.0625f);
-    
-    // top
-    tmesh.addPoint(0.0f, 1.0f, 0.0f, 0.25f, 0.0f);
-    tmesh.addPoint(0.0f, 1.0f, 1.0f, 0.25f, 0.0625f);
-    tmesh.addPoint(1.0f, 1.0f, 0.0f, 0.3125f, 0.0f);
-    tmesh.addPoint(1.0f, 1.0f, 0.0f, 0.3125f, 0.0f);
-    tmesh.addPoint(0.0f, 1.0f, 1.0f, 0.25f, 0.0625f);
-    tmesh.addPoint(1.0f, 1.0f, 1.0f, 0.3125f, 0.0625f);
-    
-    // right
-    tmesh.addPoint(1.0f, 0.0f, 0.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(1.0f, 1.0f, 1.0f, 0.25f, 0.0f);
-    tmesh.addPoint(1.0f, 0.0f, 1.0f, 0.25f, 0.0625f);
-    tmesh.addPoint(1.0f, 0.0f, 0.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(1.0f, 1.0f, 0.0f, 0.1875f, 0.0f);
-    tmesh.addPoint(1.0f, 1.0f, 1.0f, 0.25f, 0.0f);
-    
-    // left
-    tmesh.addPoint(0.0f, 0.0f, 0.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(0.0f, 0.0f, 1.0f, 0.25f, 0.0625f);
-    tmesh.addPoint(0.0f, 1.0f, 1.0f, 0.25f, 0.0f);
-    tmesh.addPoint(0.0f, 0.0f, 0.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(0.0f, 1.0f, 1.0f, 0.25f, 0.0f);
-    tmesh.addPoint(0.0f, 1.0f, 0.0f, 0.1875f, 0.0f);
-    
-    // back
-    tmesh.addPoint(0.0f, 0.0f, 1.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(1.0f, 0.0f, 1.0f, 0.25f, 0.0625f);
-    tmesh.addPoint(1.0f, 1.0f, 1.0f, 0.25f, 0.0f);
-    tmesh.addPoint(0.0f, 0.0f, 1.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(1.0f, 1.0f, 1.0f, 0.25f, 0.0f);
-    tmesh.addPoint(0.0f, 1.0f, 1.0f, 0.1875f, 0.0f);
-    
-    // front
-    tmesh.addPoint(0.0f, 0.0f, 0.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(1.0f, 1.0f, 0.0f, 0.25f, 0.0f);
-    tmesh.addPoint(1.0f, 0.0f, 0.0f, 0.25f, 0.0625f);
-    tmesh.addPoint(0.0f, 0.0f, 0.0f, 0.1875f, 0.0625f);
-    tmesh.addPoint(0.0f, 1.0f, 0.0f, 0.1875f, 0.0f);
-    tmesh.addPoint(1.0f, 1.0f, 0.0f, 0.25f, 0.0f);
-             
-             */
+            for(int z = 0; z < DEPTH; z++)
+            {
+                if(blocks[y][x][z] == 1)
+                {
+                    for(int i = 0; i < 36; i++)
+                    {
+                        m.addColor(1, 0, 0, 1);
+                    }
+                    
+                    // bottom
+                    //m.addTexture(0.125f, 0.0f);
+                    //m.addTexture(0.1875f, 0.0f);
+                    //m.addTexture(0.125f, 0.0625f);
+                    //m.addTexture(0.1875f, 0.0f);
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.125f, 0.0625f);
+                    
+                    for(int i = 0; i < 6; i++)
+                    {
+                        m.addNormal(0.0f, -1.0f, 0.0f);
+                    }
+
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 1.0f);
+                    m.addPosition(x + 1.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 0.0f, z + 1.0f);
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 1.0f);
+
+                    // top
+                    //m.addTexture(0.25f, 0.0f);
+                    //m.addTexture(0.25f, 0.0625f);
+                    //m.addTexture(0.3125f, 0.0f);
+                    //m.addTexture(0.3125f, 0.0f);
+                    //m.addTexture(0.25f, 0.0625f);
+                    //m.addTexture(0.3125f, 0.0625f);
+                    
+                    for(int i = 0; i < 6; i++)
+                    {
+                        m.addNormal(0.0f, 1.0f, 0.0f);
+                    }
+
+                    m.addPosition(x + 0.0f, y + 1.0f, z + 0.0f);
+                    m.addPosition(x + 0.0f, y + 1.0f, z + 1.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 0.0f);
+                    m.addPosition(x + 0.0f, y + 1.0f, z + 1.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 1.0f);
+
+                    // right
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.25f, 0.0f);
+                    //m.addTexture(0.25f, 0.0625f);
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.1875f, 0.0f);
+                    //m.addTexture(0.25f, 0.0f);
+                    
+                    for(int i = 0; i < 6; i++)
+                    {
+                        m.addNormal(1.0f, 0.0f, 0.0f);
+                    }
+
+                    m.addPosition(x + 1.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 1.0f);
+                    m.addPosition(x + 1.0f, y + 0.0f, z + 1.0f);
+                    m.addPosition(x + 1.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 1.0f);
+
+                    // left
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.25f, 0.0625f);
+                    //m.addTexture(0.25f, 0.0f);
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.25f, 0.0f);
+                    //m.addTexture(0.1875f, 0.0f);
+                    
+                    for(int i = 0; i < 6; i++)
+                    {
+                        m.addNormal(-1.0f, 0.0f, 0.0f);
+                    }
+
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 1.0f);
+                    m.addPosition(x + 0.0f, y + 1.0f, z + 1.0f);
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 0.0f, y + 1.0f, z + 1.0f);
+                    m.addPosition(x + 0.0f, y + 1.0f, z + 0.0f);
+
+                    // back
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.25f, 0.0625f);
+                    //m.addTexture(0.25f, 0.0f);
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.25f, 0.0f);
+                    //m.addTexture(0.1875f, 0.0f);
+                    
+                    for(int i = 0; i < 6; i++)
+                    {
+                        m.addNormal(0.0f, 0.0f, -1.0f);
+                    }
+
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 1.0f);
+                    m.addPosition(x + 1.0f, y + 0.0f, z + 1.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 1.0f);
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 1.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 1.0f);
+                    m.addPosition(x + 0.0f, y + 1.0f, z + 1.0f);
+
+                    // front
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.25f, 0.0f);
+                    //m.addTexture(0.25f, 0.0625f);
+                    //m.addTexture(0.1875f, 0.0625f);
+                    //m.addTexture(0.1875f, 0.0f);
+                    //m.addTexture(0.25f, 0.0f);
+                    
+                    for(int i = 0; i < 6; i++)
+                    {
+                        m.addNormal(0.0f, 0.0f, 1.0f);
+                    }
+
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 0.0f, y + 0.0f, z + 0.0f);
+                    m.addPosition(x + 0.0f, y + 1.0f, z + 0.0f);
+                    m.addPosition(x + 1.0f, y + 1.0f, z + 0.0f);
+                }
+            }
         }
-        mesh[i].draw();
     }
+    
+    m.build();  
 }
 

+ 20 - 9
world/Chunk.h

@@ -1,7 +1,9 @@
 #ifndef CHUNK_H
 #define CHUNK_H
 
-#include "../engine/TextureMesh.h"
+#include "../engine/Mesh.h"
+#include "../engine/Shader.h"
+#include "../engine/DirectRenderer.h"
 
 class Chunk
 {
@@ -13,19 +15,28 @@ public:
     void setBlock(int x, int y, int z, unsigned short block);
     unsigned short getBlock(int x, int y, int z);
     
-    static const int WORLD_HIGH = 16;
-    static const int CHUNK_SIZE = 16;
-    static const int MAX_Y = WORLD_HIGH * CHUNK_SIZE;
+    void renderTick(Shader& shader, DirectRenderer& dr, float lag);
     
-    void init();
-    void renderTick(float lag);
+    // chunk constants
+    static const int PARTION_HEIGHT = 16;
+    static const int HEIGHT_PARTIONS = 1;
+    
+    static const int WIDTH = 16;
+    static const int HEIGHT = PARTION_HEIGHT * HEIGHT_PARTIONS;
+    static const int DEPTH = 16;
+    
+    static const int BITMASK_WIDTH = WIDTH - 1;
+    static const int BITMASK_HEIGHT = HEIGHT - 1;
+    static const int BITMASK_DEPTH = DEPTH - 1;
 private:
+    void buildChunk(int partionY);
+    
     int chunkX;
     int chunkZ;
     
-    unsigned short blocks[MAX_Y][CHUNK_SIZE][CHUNK_SIZE];
-    bool dirty[WORLD_HIGH];
-    TextureMesh mesh[WORLD_HIGH];
+    unsigned short blocks[HEIGHT][WIDTH][DEPTH];
+    bool dirty[HEIGHT_PARTIONS];
+    Mesh** mesh;
 };
 
 #endif