Browse Source

Initial commit

testing
BuildTools 3 years ago
commit
3f19c6b196
65 changed files with 9278 additions and 0 deletions
  1. 12
    0
      CMakeLists.txt
  2. 26
    0
      res/config.conf
  3. BIN
      res/crosshair.png
  4. BIN
      res/dirt.png
  5. BIN
      res/grass.png
  6. 7
    0
      res/shaders/test.frag.glsl
  7. 8
    0
      res/shaders/test.vert.glsl
  8. 14
    0
      res/shaders/voxelfrag.frag.glsl
  9. 16
    0
      res/shaders/voxelvert.vert.glsl
  10. BIN
      res/stone.png
  11. 44
    0
      res/stone.vmd
  12. BIN
      res/test.png
  13. BIN
      res/test2.png
  14. BIN
      res/tileset.png
  15. BIN
      res/tileset.xcf
  16. 63
    0
      src/bitmap.cpp
  17. 42
    0
      src/bitmap.h
  18. 109
    0
      src/camera.cpp
  19. 60
    0
      src/camera.h
  20. 73
    0
      src/chunk.cpp
  21. 46
    0
      src/chunk.h
  22. 393
    0
      src/chunkrenderer.cpp
  23. 86
    0
      src/chunkrenderer.h
  24. 27
    0
      src/config.cpp
  25. 150
    0
      src/config.h
  26. 47
    0
      src/customnoise/gradientnoise.cpp
  27. 43
    0
      src/customnoise/gradientnoise.h
  28. 40
    0
      src/customnoise/yturbulence.cpp
  29. 43
    0
      src/customnoise/yturbulence.h
  30. 116
    0
      src/game.cpp
  31. 52
    0
      src/game.h
  32. 43
    0
      src/graphics/drawable.h
  33. 19
    0
      src/graphics/mesh.cpp
  34. 19
    0
      src/graphics/mesh.h
  35. 19
    0
      src/graphics/shader.cpp
  36. 38
    0
      src/graphics/shader.h
  37. 98
    0
      src/inputhandler.cpp
  38. 49
    0
      src/inputhandler.h
  39. 103
    0
      src/loadShader.cpp
  40. 22
    0
      src/loadShader.h
  41. 24
    0
      src/main.cpp
  42. 757
    0
      src/mathfuncs.cpp
  43. 164
    0
      src/mathfuncs.h
  44. 59
    0
      src/mathplus.h
  45. 242
    0
      src/nano_signal_slot.hpp
  46. 29
    0
      src/scene.cpp
  47. 39
    0
      src/scene.h
  48. 204
    0
      src/scenes/testscene.cpp
  49. 72
    0
      src/scenes/testscene.h
  50. 4673
    0
      src/stb_image.c
  51. 86
    0
      src/terraingen.cpp
  52. 51
    0
      src/terraingen.h
  53. 19
    0
      src/tilemap.h
  54. 81
    0
      src/tileset.cpp
  55. 46
    0
      src/tileset.h
  56. 127
    0
      src/voxelinfo.cpp
  57. 81
    0
      src/voxelinfo.h
  58. 129
    0
      src/voxelmath.cpp
  59. 45
    0
      src/voxelmath.h
  60. 57
    0
      src/voxelutils.h
  61. 65
    0
      src/window.cpp
  62. 49
    0
      src/window.h
  63. 164
    0
      src/world.cpp
  64. 67
    0
      src/world.h
  65. 21
    0
      todo.txt

+ 12
- 0
CMakeLists.txt View File

@@ -0,0 +1,12 @@
cmake_minimum_required (VERSION 3.6)
project ("voxeltronik")
file (GLOB_RECURSE SOURCES "src/*.cpp")
include_directories("include")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
add_executable(vtk ${SOURCES})

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
target_link_libraries(vtk SDL2 GL GLEW GLU noise ${CMAKE_THREAD_LIBS_INIT})


+ 26
- 0
res/config.conf View File

@@ -0,0 +1,26 @@
; Comments start with a semicolon

graphics {
res {
x = 1600 ; horizontal resolution
y = 900 ; vertical resolution
}
fov = 90.0
vsync = 1
}

controls {
mouse {
sensitivity = 8
}
bindings {
movement {
forward = W
backward = S
left = A
right = D
up = Space
down = Left Ctrl
}
}
}

BIN
res/crosshair.png View File


BIN
res/dirt.png View File


BIN
res/grass.png View File


+ 7
- 0
res/shaders/test.frag.glsl View File

@@ -0,0 +1,7 @@
#version 440

out vec4 outColor;

void main() {
outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

+ 8
- 0
res/shaders/test.vert.glsl View File

@@ -0,0 +1,8 @@
#version 440

layout(location = 0) in vec3 position;

void main() {
gl_Position = vec4(position, 1.0);

}

+ 14
- 0
res/shaders/voxelfrag.frag.glsl View File

@@ -0,0 +1,14 @@
#version 440
#extension GL_EXT_texture_array : enable

in vec3 texCoordInterp;
in vec3 lightDataInterp;

out vec4 outColor;

uniform sampler2DArray texture;

void main() {
vec4 texel = texture2DArray(texture, texCoordInterp);
outColor = texel * vec4(lightDataInterp, 1.0f);
}

+ 16
- 0
res/shaders/voxelvert.vert.glsl View File

@@ -0,0 +1,16 @@
#version 400

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 texCoord;
layout(location = 2) in vec3 lightData;

uniform mat4 proj, view, model; //transform matrix

out vec3 texCoordInterp;
out vec3 lightDataInterp;

void main() {
gl_Position = proj * view * model * vec4(position, 1.0);
texCoordInterp = texCoord;
lightDataInterp = lightData;
}

BIN
res/stone.png View File


+ 44
- 0
res/stone.vmd View File

@@ -0,0 +1,44 @@
# Example of the VTK model format

faceGroup NORTH { # faceGroups are used to group faces. Cardinal directions are used for draw optimizations
face { # define a face
type: triangles
verts [ # defined x, y, z, x, y, z ...
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,

1.0, 1.0, 0.0,
0.0, 1.0, 0.0,
1.0, 0.0, 0.0

]
uv [
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,

...
]
}
}

faceGroup SOUTH {

}

faceGroup EAST {

}

faceGroup WEST {

}

faceGroup TOP {

}

faceGroup BOTTOM {

}

BIN
res/test.png View File


BIN
res/test2.png View File


BIN
res/tileset.png View File


BIN
res/tileset.xcf View File


+ 63
- 0
src/bitmap.cpp View File

@@ -0,0 +1,63 @@
/*
* =====================================================================================
*
* Filename: bitmap.cpp
*
* Description: Bitmap
*
* Version: 1.0
* Created: 04/02/2014 07:21:51 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#include "bitmap.h"
#include "stb_image.c"

namespace vtk {

Bitmap::Bitmap() {
forceChannels = 4;
}

bool Bitmap::loadFromFile(const std::string& fileName) {
imageData = stbi_load(fileName.c_str(), &x, &y, &n, forceChannels);
if (!imageData) return false;
flipVertical();
return true;
}

unsigned char* Bitmap::getPixelDataPtr() {
return imageData;
}

void Bitmap::flipVertical() {
int widthBytes = x * 4;
unsigned char* top = NULL;
unsigned char* bottom = NULL;
unsigned char temp = 0;
int halfHeight = y/2;

for (int row = 0; row < halfHeight; row++) {
top = imageData + row * widthBytes;
bottom = imageData + (y - row - 1) * widthBytes;
for (int col = 0; col < widthBytes; col++) {
temp = *top;
*top = *bottom;
*bottom = temp;
top++;
bottom++;
}
}
}

int Bitmap::getHeight() { return y; }
int Bitmap::getWidth() { return x; }
int Bitmap::getNumChannels() { return n; }

}

+ 42
- 0
src/bitmap.h View File

@@ -0,0 +1,42 @@
/*
* =====================================================================================
*
* Filename: bitmap.h
*
* Description: Stores a bitmap
*
* Version: 1.0
* Created: 04/02/2014 07:19:09 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include <string>

namespace vtk {

class Bitmap {
public:
Bitmap();

bool loadFromFile(const std::string& fileName);
unsigned char* getPixelDataPtr();
int getHeight();
int getWidth();
int getNumChannels();
void flipVertical();

protected:
unsigned char* imageData;
int x, y, n;
int forceChannels;
};

}

+ 109
- 0
src/camera.cpp View File

@@ -0,0 +1,109 @@
/*
* =====================================================================================
*
* Filename: camera.cpp
*
* Description:
*
* Version: 1.0
* Created: 03/24/2014 04:58:22 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include "camera.h"
#include "window.h"

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/rotate_vector.hpp>
#include <glm/gtx/transform.hpp>

namespace vtk {

Camera::Camera() {
up = glm::vec3(0.0f, 1.0f, 0.0f);
pitch = 0.0f;
yaw = 0.0f;
pitchDelta = 0.0f;
yawDelta = 0.0f;
moveDampening = 0.0f;
tiltDampening = 0.0f;
}

glm::mat4 Camera::getViewMatrix() {
glm::mat4 translationMat = glm::translate(glm::mat4(), -position);
glm::mat4 pitchMat = glm::rotate(glm::mat4(), pitch, glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 yawMat = glm::rotate(glm::mat4(), yaw, glm::vec3(0.0f, 1.0f, 0.0f));

return pitchMat * yawMat * translationMat;
//return translationMat;
}

glm::mat4 Camera::getProjectionMatrix() {
return glm::infinitePerspective(1.5708f, linkedWindow->getAspect(), 1.0f);
}


void Camera::update(const float& dTime) {
pitch += pitchDelta;
yaw += yawDelta;
position += positionDelta;

pitchDelta *= dTime * tiltDampening;
yawDelta *= dTime * tiltDampening;
positionDelta *= dTime * moveDampening;

{
//reverse project for direction vector
glm::vec4 rayClip(0.0f, 0.0f, -1.0f, 1.0f);
glm::vec4 rayEye = glm::inverse(getProjectionMatrix()) * rayClip;
rayEye = glm::vec4(rayEye.x, rayEye.y, -1.0f, 0.0f);
glm::vec4 rayWor = glm::inverse(getViewMatrix()) * rayEye;
direction = glm::vec3(rayWor.x, rayWor.y, rayWor.z);
}
}

void Camera::setPosition(const glm::vec3& position) {
this->position = position;
}

glm::vec3 Camera::getPosition() {
return position;
}

glm::vec3 Camera::getAngleVector() {
return direction;
}

void Camera::setWindow(Window* window) {
linkedWindow = window;
}

void Camera::move(const glm::vec3& offset) {
positionDelta += offset;

}

void Camera::moveRelative(const glm::vec3& offset) {
if (offset.x != 0) {
positionDelta += offset.x * glm::normalize(glm::cross(direction, glm::vec3(0.0f, 1.0f, 0.0f)));
}
if (offset.y != 0) {
positionDelta += offset.y * glm::normalize(glm::cross(direction, glm::vec3(1.0f, 0.0f, 0.0f)));
}
if (offset.z != 0) {
positionDelta += offset.z * direction;
}
}

void Camera::rotate(const float& x, const float& y) {
pitchDelta += y;
yawDelta += x;
}


}

+ 60
- 0
src/camera.h View File

@@ -0,0 +1,60 @@
/*
* =====================================================================================
*
* Filename: camera.h
*
* Description: FPS style camera
*
* Version: 1.0
* Created: 03/24/2014 04:58:12 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>

namespace vtk {

class Window;

class Camera {
public:
Camera();
glm::mat4 getViewMatrix();
glm::mat4 getProjectionMatrix();
void update(const float& dTime);
void setPosition(const glm::vec3& position);
glm::vec3 getPosition();

//id setAngleVector(const glm::vec3& angleVector);
glm::vec3 getAngleVector();

void setWindow(Window* window);

void move(const glm::vec3& offset);
void moveRelative(const glm::vec3& offset);
void rotate(const float& x, const float& y);

private:
glm::vec3 up;
glm::vec3 position;
glm::vec3 positionDelta;
glm::vec3 direction;
float pitch;
float yaw;
float pitchDelta;
float yawDelta;
float moveDampening;
float tiltDampening;
Window* linkedWindow;
};

}

+ 73
- 0
src/chunk.cpp View File

@@ -0,0 +1,73 @@
/*
* =====================================================================================
*
* Filename: chunk.cpp
*
* Description: Chunk
*
* Version: 1.0
* Created: 04/04/2014 09:44:36 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include "chunk.h"
#include "world.h"

#include <iostream>

namespace vtk {

Chunk::Chunk() {
linkedWorld = nullptr;
chunkSize = 16;
chunkPos = glm::ivec3(0,0,0);
renderer.linkedChunk = this;
//fill voxels with 0
for (unsigned i = 0; i < 4096; i++) {
voxels[i] = 0;
}
}

bool Chunk::isVoxelSolid(const int& x, const int& y, const int& z) {
if (x < 0 || x > (int)chunkSize - 1 ||
y < 0 || y > (int)chunkSize - 1 ||
z < 0 || z > (int)chunkSize - 1 ) { //position is outside of the chunk
return linkedWorld->isVoxelSolid(chunkPos.x * 16 + x,
chunkPos.y * 16 + y,
chunkPos.z * 16 + z);
}

return (getVoxelType((unsigned)x,(unsigned)y,(unsigned)z) != 0);
}

void Chunk::setVoxelType(const int& x, const int& y, const int& z, const unsigned& type) {
auto index = x + 16 * (y + 16 * z);
if (index > 4095) {
std::cout << "CHUNK ACCESS ERROR (set voxel): Out of range, doing nothing\n";
return;
}
voxels[index] = type;

}

unsigned Chunk::getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z) {
auto index = x + 16 * (y + 16 * z);
if (index > 4095) {
std::cout << "CHUNK ACCESS ERROR (get voxel): Out of range, returning type 0\n";
return 0;
}
return voxels[index];
}

glm::ivec3 Chunk::getWorldCoords(const int& x, const int& y, const int& z) {
return glm::ivec3(chunkPos.x * 16 + x,
chunkPos.y * 16 + y,
chunkPos.z * 16 + z);
}

}

+ 46
- 0
src/chunk.h View File

@@ -0,0 +1,46 @@
/*
* =====================================================================================
*
* Filename: chunk.h
*
* Description: Stores chunk information
*
* Version: 1.0
* Created: 04/03/2014 07:23:43 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include "voxelutils.h"
#include "chunkrenderer.h"

#include <unordered_map>
#include <glm/glm.hpp>

namespace vtk {

class World;

class Chunk {
public:
Chunk();
bool isVoxelSolid(const int& x, const int& y, const int& z); //Is the voxel not a transparent type?
void setVoxelType(const int& x, const int& y, const int& z, const unsigned& type);
unsigned getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z);
glm::ivec3 getWorldCoords(const int& x, const int& y, const int& z);

std::array<unsigned, 4096> voxels;
World* linkedWorld;
unsigned chunkSize;
glm::ivec3 chunkPos;
ChunkRenderer renderer;
};

}

+ 393
- 0
src/chunkrenderer.cpp View File

@@ -0,0 +1,393 @@
/*
* =====================================================================================
*
* Filename: chunkrenderer.cpp
*
* Description:
*
* Version: 1.0
* Created: 04/04/2014 11:34:53 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#include "chunkrenderer.h"

#include "chunk.h"
#include "world.h"

#include <GL/glew.h>
#include <GL/gl.h>
#include <iostream>

namespace vtk {

void ChunkRenderer::init() {
hasGeometryChanged = false;
hasTexturesChanged = false;
hasLightingChanged = false;
updatingGeometry = false;

chunkSize = 16;
lightingMethod = 0;
voxelSize = 1.0f;

//generate VBOs
for (auto& i : vertexBuffers) {
for(auto& j : i) {
glGenBuffers(1, &j);
}
}

//generate VAOs
for (auto& i : vertexArrays) {
glGenVertexArrays(1, &i);
}

//bind VAOs
for (int i = 0; i < 6; i++) {
glBindVertexArray(vertexArrays[i]);

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][1]);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][2]);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(2);
}
}

void ChunkRenderer::drawChunk() {
for (int i = 0; i < 6; i++) {
glBindVertexArray(vertexArrays[i]);
glDrawArrays(GL_TRIANGLES, 0, vertexCounts[i]);
}
}

void ChunkRenderer::setChunkPosition(const int&x, const int& y, const int&z) {
chunkPos = std::make_tuple(x, y, z);
}

void ChunkRenderer::updateGeometry() {
updatingGeometry = true;

for (auto& i : geometryVertices)
i.clear();

for (auto& i : faceCounts)
i = 0;

for (unsigned i = 0; i < chunkSize; i++) {
for (unsigned j = 0; j < chunkSize; j++) {
for (unsigned k = 0; k < chunkSize; k++) {
if (linkedChunk->isVoxelSolid(i,j,k)) {
if (!linkedChunk->isVoxelSolid(i+1,j,k)) {
//right face
//top left
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//bottom left
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom right
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
//bottom left
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize);
faceCounts[0]++;
}
if (!linkedChunk->isVoxelSolid(i-1,j,k)) {
//left face
//top left
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//top right
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize, k * voxelSize);
//bottom right
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize, k * voxelSize);
//top right
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
faceCounts[1]++;
}

if (!linkedChunk->isVoxelSolid(i,j+1,k)) {
//top face
//bottom left
addVertex(geometryVertices[2], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top left
addVertex(geometryVertices[2], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//bottom right
addVertex(geometryVertices[2], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[2], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//bottom right
addVertex(geometryVertices[2], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top left
addVertex(geometryVertices[2], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
faceCounts[2]++;
}
if (!linkedChunk->isVoxelSolid(i,j-1,k)) {
//bottom face
//top right
addVertex(geometryVertices[3], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom right
addVertex(geometryVertices[3], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
//top left
addVertex(geometryVertices[3], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[3], i * voxelSize, j * voxelSize, k * voxelSize);
//top left
addVertex(geometryVertices[3], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom right
addVertex(geometryVertices[3], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
faceCounts[3]++;
}

if (!linkedChunk->isVoxelSolid(i,j,k-1)) {
//back face
//top left
addVertex(geometryVertices[4], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//top right
addVertex(geometryVertices[4], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//bottom left
addVertex(geometryVertices[4], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
//bottom right
addVertex(geometryVertices[4], i * voxelSize, j * voxelSize, k * voxelSize);
//bottom left
addVertex(geometryVertices[4], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
//top right
addVertex(geometryVertices[4], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
faceCounts[4]++;
}

if (!linkedChunk->isVoxelSolid(i,j,k+1)) {
//front face
//bottom right
addVertex(geometryVertices[5], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[5], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[5], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top left
addVertex(geometryVertices[5], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[5], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[5], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
faceCounts[5]++;
}
}
}
}
}

hasGeometryChanged = true;

updateTexCoords();
updateLighting();

updatingGeometry = false;
}

void ChunkRenderer::updateTexCoords() {
for (auto& i : textureCoords)
i.clear();

for (unsigned i = 0; i < chunkSize; i++) {
for (unsigned j = 0; j < chunkSize; j++) {
for (unsigned k = 0; k < chunkSize; k++) {
if (linkedChunk->isVoxelSolid(i,j,k)) {
if (!linkedChunk->isVoxelSolid(i+1,j,k)) {
//right face
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::TOPLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::TOPRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::BOTTOMRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::TOPRIGHT);
}
if (!linkedChunk->isVoxelSolid(i-1,j,k)) {
//left face
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::TOPLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::TOPRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::BOTTOMRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::TOPRIGHT);
}
if (!linkedChunk->isVoxelSolid(i,j+1,k)) {
//top face
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::TOPLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::BOTTOMRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::TOPRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::BOTTOMRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::TOPLEFT);
}
if (!linkedChunk->isVoxelSolid(i,j-1,k)) {
//bottom face
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::TOPRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::BOTTOMRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::TOPLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::TOPLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::BOTTOMRIGHT);
}
if (!linkedChunk->isVoxelSolid(i,j,k-1)) {
//back face
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::TOPLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::TOPRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::BOTTOMRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::TOPRIGHT);

}
if (!linkedChunk->isVoxelSolid(i,j,k+1)) {
//front face
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::BOTTOMRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::BOTTOMLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::TOPRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::TOPLEFT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::TOPRIGHT);
linkedChunk->linkedWorld->voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::BOTTOMLEFT);
}
}
}
}
}
hasTexturesChanged = true;
}

void ChunkRenderer::updateLighting() {
for (auto& i : lightingData)
i.clear();

for (unsigned i = 0; i < chunkSize; i++) {
for (unsigned j = 0; j < chunkSize; j++) {
for (unsigned k = 0; k < chunkSize; k++) {
if (linkedChunk->isVoxelSolid(i,j,k)) {
if (lightingMethod == 0) { //fullbright lighting
//face U , V , I
//right face
if (!linkedChunk->isVoxelSolid(i+1,j,k)) {
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //TL
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //TR
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //BL
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //BR
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //BL
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //TR
}
if (!linkedChunk->isVoxelSolid(i-1,j,k)) {
//left face
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //TL
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //TR
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //BL
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //BR
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //BL
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //TR
}
if (!linkedChunk->isVoxelSolid(i,j+1,k)) {
//top face
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //TL
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //TR
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //BL
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //BR
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //BL
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //TR
}
if (!linkedChunk->isVoxelSolid(i,j-1,k)) {
//bottom face
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //TL
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //TR
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //BL
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //BR
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //BL
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //TR
}
if (!linkedChunk->isVoxelSolid(i,j,k-1)) {
//back face
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //TL
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //TR
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //BL
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //BR
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //BL
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //TR
}
if (!linkedChunk->isVoxelSolid(i,j,k+1)) {
//front face
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //TL
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //TR
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //BL
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //BR
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //BL
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //TR
}
} else if (lightingMethod == 1) { //blocky lighting (Need to implement!)

} else if (lightingMethod == 2) { //smooth lighting (Need to implement!)

}
}
}
}
}
hasLightingChanged = true;
}

void ChunkRenderer::updateVertexData() {
if (!updatingGeometry) {
//std::cout << "testing";
for (unsigned i = 0; i < 6; i++) {
if (hasGeometryChanged) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * geometryVertices[i].size(), geometryVertices[i].data(), GL_STATIC_DRAW);
//hasGeometryChanged = false;
}
if (hasTexturesChanged) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * textureCoords[i].size(), textureCoords[i].data(), GL_STATIC_DRAW);
//hasTexturesChanged = false;
}
if (hasLightingChanged) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * lightingData[i].size(), lightingData[i].data(), GL_STATIC_DRAW);
//hasLightingChanged = false;
}
}

if (hasGeometryChanged) hasGeometryChanged = false;
if (hasTexturesChanged) hasTexturesChanged = false;
if (hasLightingChanged) hasLightingChanged = false;

for (int i = 0; i < 6; i++) {
vertexCounts[i] = faceCounts[i] * 6;
}
}
}

void ChunkRenderer::addVertex(std::vector<float>& data, const float& x, const float& y, const float& z) {
data.push_back(x);
data.push_back(y);
data.push_back(z);
}

}

+ 86
- 0
src/chunkrenderer.h View File

@@ -0,0 +1,86 @@
/*
* =====================================================================================
*
* Filename: chunkrenderer.h
*
* Description:
*
* Version: 1.0
* Created: 04/04/2014 11:11:43 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include "voxelutils.h"

#include <array>
#include <vector>
#include <atomic>

namespace vtk {

class Chunk;

class ChunkRenderer {
public:

void init();

void drawChunk();
void setChunkPosition(const int&x, const int& y, const int&z);

void updateGeometry();
void updateTexCoords();
void updateLighting();

void updateVertexData();

Chunk* linkedChunk;
protected:

/*
Info I need to reference:
0 = X+
1 = X-
2 = y+
3 = Y-
4 = Z+
5 = Z-
*/

bool initialized;
iPos chunkPos;
float voxelSize;
unsigned chunkSize;
unsigned lightingMethod; // 0 = fullbright, 1 = blocky, 2 = smooth

bool updatingGeometry; //Is geometry actively updating (for threading)

//set to true after their respective update function is called
bool hasGeometryChanged;
bool hasTexturesChanged;
bool hasLightingChanged;


std::array<unsigned, 6> faceCounts;
std::array<unsigned, 6> vertexCounts;

std::array<std::vector<float>, 6> geometryVertices; //Holds geometry vertices as x,y,z,x,y,z...
std::array<std::vector<float>, 6> textureCoords; //Holds texture coords as u,v,i,u,v,i...
std::array<std::vector<float>, 6> lightingData; //Holds lighting data as r,g,b,r,g,b...

std::array<std::array <unsigned, 3>, 6> vertexBuffers;//VBOs
std::array<unsigned, 6> vertexArrays; //VAOs

//add vertex to a vector of floats. Used for code cleanliness and flexibility
void addVertex(std::vector<float>& data, const float& x, const float& y, const float& z);
};

}

+ 27
- 0
src/config.cpp View File

@@ -0,0 +1,27 @@
/*
* =====================================================================================
*
* Filename: config.cpp
*
* Description: Specializations and shit
*
* Version: 1.0
* Created: 03/27/2014 10:56:51 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include "config.h"

template <>
std::string Config::getValue<std::string>(const std::string& key, const std::string& fallback) {
if (values.find(key) != values.end()) {
return values[key];
}
return fallback;
}


+ 150
- 0
src/config.h View File

@@ -0,0 +1,150 @@
/*
* =====================================================================================
*
* Filename: config.h
*
* Description: Processes command line arguments and config files in header only library
*
* Version: 1.0
* Created: 03/26/2014 09:30:55 PM
* Revision: none
* Compiler: gcc
*
* Author: Michael Porter
*
* =====================================================================================
*/

/*

EXAMPLE CONFIG:

;this is a comment

key = value
integer = 69
float = 3.1415926
bool = 1
anotherbool = false

hierarchything {

subkey = "value as a string"

}

*/

#pragma once

#include <string>
#include <map>
#include <sstream>
#include <fstream>
#include <iostream>
#include <vector>

//Config stores values
class Config {
public:
bool loadConfigFromFile(const std::string& fileName) {
std::ifstream file(fileName);
if (!file) return false;
std::string line;
std::vector<std::string> hierarchyPosition;

while (std::getline(file, line)) {
auto temp = line; //copy line for safety
trimString(temp);
if (temp.find_first_of(";") != std::string::npos) { //contains comment
temp.erase(temp.find_first_of(";"), temp.size() - 1);
}
if (!temp.empty()) { //it's not empty
if (temp[0] != '{' && temp.find_first_of("{") != std::string::npos) {
std::string key = temp.substr(0, temp.find_first_of("{"));
trimString(key);
hierarchyPosition.push_back(key);
} else if (temp[0] == '}') {
hierarchyPosition.pop_back();
} else if (temp[0] != '=' && temp.find_first_of("=") != std::string::npos) { //it's assigning something!

std::string key = temp.substr(0, temp.find_first_of("="));
trimString(key);

std::string value = temp.substr(temp.find_first_of("=") + 1, temp.size() - 1);
trimString(value);

if (!hierarchyPosition.empty()) {
std::string tempKey = key;
key.clear();
for (auto& i : hierarchyPosition) {
key.append(i);
key.append(".");
}
key.append(tempKey);
}
values[key] = value;
}
}
}
return true;
}

template <typename T>
T getValue(const std::string& key, const T& fallback) {
if (values.find(key) != values.end()) {
stream.clear();
stream << values[key];
T value;
stream >> value;
return value;
}
return fallback;
}
template <typename T>
void setValue(const std::string& key, const T& value) {
stream.clear();
stream << value;
stream >> values[key];
}

void addArgumentRule(const std::string& flag, const std::string& key) { //sets a value to be overriden by command line flag
commandRules[flag] = key;
}

bool loadConfigFromArguments(const int& argc, char* argv[]) {
for (int i = 1; i < argc; i += 2) {
auto flag = std::string(argv[i]);
auto value = std::string(argv[i+1]);
if (commandRules.find(flag) != commandRules.end()) {
values[commandRules[flag]] = value;
} else return false;
}
return true;
}

void printConfig() {
for (auto& i : values) {
std::cout << i.first << " = " << i.second << std::endl;
}
}

protected:
std::map<std::string, std::string> values;
std::map<std::string, std::string> commandRules;
std::stringstream stream;

void trimString(std::string& string) {
size_t end = string.find_last_not_of(" \t\n\v\f\r");
if ( end != std::string::npos )
string.resize( end + 1 );

size_t start = string.find_first_not_of(" \t\n\v\f\r");
if ( start != std::string::npos )
string = string.substr( start );
}
};



+ 47
- 0
src/customnoise/gradientnoise.cpp View File

@@ -0,0 +1,47 @@
/*
* =====================================================================================
*
* Filename: gradientnoise.cpp
*
* Description:
*
* Version: 1.0
* Created: 05/10/2014 03:47:54 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include "gradientnoise.h"

namespace vtk {

GradientNoise::GradientNoise() : Module(GetSourceModuleCount()){

}

int GradientNoise::GetSourceModuleCount() const {
return 0;
}

double GradientNoise::GetValue(double x, double y, double z) const {
//We don't need x and z, so we suppress the warnings about it
(void)x;
(void)z;

if (y <= stop0) return -1.0;
if (y >= stop1) return 1.0;

return ((y - stop0) / (stop1 - stop0)) * 2 - 1;
}

void GradientNoise::setStop(const int& index, const double& value) {
if (index == 0) stop0 = value;
else if (index == 1) stop1 = value;
}

}


+ 43
- 0
src/customnoise/gradientnoise.h View File

@@ -0,0 +1,43 @@
/*
* =====================================================================================
*
* Filename: gradientnoise.h
*
* Description: Produces a vertical gradient
*
* Version: 1.0
* Created: 05/10/2014 03:42:45 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include <noise/noise.h>


//TODO: Add support for more than 2 stops

namespace vtk {

class GradientNoise : public noise::module::Module {
public:
GradientNoise();

virtual int GetSourceModuleCount() const;
virtual double GetValue(double x, double y, double z) const;

void setStop(const int& index, const double& value);

protected:
double stop0;
double stop1;
};


}

+ 40
- 0
src/customnoise/yturbulence.cpp View File

@@ -0,0 +1,40 @@
/*
* =====================================================================================
*
* Filename: yturbulence.cpp
*
* Description:
*
* Version: 1.0
* Created: 05/10/2014 06:17:38 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include "yturbulence.h"

namespace vtk {
YTurbulence::YTurbulence() : Module(GetSourceModuleCount()){

}

int YTurbulence::GetSourceModuleCount() const {
return 1;
}

double YTurbulence::GetValue(double x, double y, double z) const {
double xOff, yOff, zOff;
xOff = x + (12414.0 / 65536.0);
yOff = y + (65124.0 / 65536.0);
zOff = z + (31337.0 / 65536.0);

double distortion = y + (yNoise.GetValue(xOff, yOff, zOff) * power);

return m_pSourceModule[0]->GetValue(x, distortion, z);
}

}

+ 43
- 0
src/customnoise/yturbulence.h View File

@@ -0,0 +1,43 @@
/*
* =====================================================================================
*
* Filename: yturbulence.h
*
* Description: Y axis turbulence using perlin,
* Basically just normal turbulence, but only on Y.
*
* Version: 1.0
* Created: 05/10/2014 06:11:09 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include <noise/noise.h>


//TODO: Add support for more than 2 stops

namespace vtk {

class YTurbulence : public noise::module::Module {
public:
YTurbulence();

virtual int GetSourceModuleCount() const;
virtual double GetValue(double x, double y, double z) const;

noise::module::Perlin yNoise;
double power;
protected:

};


}

+ 116
- 0
src/game.cpp View File

@@ -0,0 +1,116 @@
/*
* =====================================================================================
*
* Filename: game.cpp
*
* Description: Game class source
*
* Version: 1.0
* Created: 03/23/2014 11:33:25 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#include "game.h"
#include "loadShader.h"
#include "camera.h"
#include "scene.h"

//SPAGHETTI INCLUDES
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

namespace vtk {

Game::Game() {
activeScene = nullptr;
}

void Game::init() {
SDL_Init(SDL_INIT_VIDEO);

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

SDL_GL_SetSwapInterval(conf->getValue<int>("graphics.vsync", 0));

window.setTitle("OpenGL");
window.setResolution(conf->getValue<int>("graphics.res.x", 800),
conf->getValue<int>("graphics.res.y", 600));
window.setFOV(conf->getValue<float>("graphics.fov", 45.0f));

window.create();

glewExperimental = GL_TRUE;
glewInit();

//OpenGL settings
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);

running = false;

}

void Game::start() {
if (activeScene == nullptr) return;
running = true;
loop();
}

void Game::loop() {


int lastFrameTime = SDL_GetTicks();

while (running) {
//time
int dTimeMS = SDL_GetTicks() - lastFrameTime;
lastFrameTime = SDL_GetTicks();
float dTime = (float)dTimeMS / 1000.0f;

activeScene->update(dTime);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
activeScene->draw();

SDL_GL_SwapWindow(window.getWindow());
}
cleanup();
}

void Game::stop() {
running = false;
}

void Game::cleanup() {
SDL_Quit();
}

void Game::setScene(Scene* scene) {
activeScene = scene;
scene->link(this);
scene->init();
}

void Game::setConfig(Config* conf) {
this->conf = conf;
}

Config* Game::getConfig() {
return conf;
}

};

+ 52
- 0
src/game.h View File

@@ -0,0 +1,52 @@
/*
* =====================================================================================
*
* Filename: game.h
*
* Description: Main game class
*
* Version: 1.0
* Created: 03/23/2014 06:29:19 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

#include "window.h"
#include "config.h"

namespace vtk {

class Scene;

class Game {
public:

Game();
void init();
void start();
void loop();
void stop();
void setScene(Scene* scene);
void setConfig(Config* conf);
Config* getConfig();
Window window;
protected:
Config* conf;
Scene* activeScene;
void cleanup();
bool running;
};

}

+ 43
- 0
src/graphics/drawable.h View File

@@ -0,0 +1,43 @@
/*
* =====================================================================================
*
* Filename: drawable.h
*
* Description: Drawable object
*
* Version: 1.0
* Created: 05/20/2014 11:02:19 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#include "../camera.h"

#include <memory>

namespace vtk {

//Forward declarations
class Shader;

///\brief Abstract base class that can
/// be drawn to a camera

class Drawable {
public:
///\brief Destructor
virtual ~Drawable();

///\brief Draw something from the viewpoint of a camera
///\param camera Camera to draw with
virtual void draw(Camera& camera);
protected:
std::shared_ptr<Shader> linkedShader;
};

}

+ 19
- 0
src/graphics/mesh.cpp View File

@@ -0,0 +1,19 @@
/*
* =====================================================================================
*
* Filename: mesh.cpp
*
* Description: Random stuff
*
* Version: 1.0
* Created: 05/12/2014 10:52:06 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include <stdlib.h>


+ 19
- 0
src/graphics/mesh.h View File

@@ -0,0 +1,19 @@
/*
* =====================================================================================
*
* Filename: mesh.h
*
* Description: Mesh that can be drawn
*
* Version: 1.0
* Created: 05/12/2014 10:51:27 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

+ 19
- 0
src/graphics/shader.cpp View File

@@ -0,0 +1,19 @@
/*
* =====================================================================================
*
* Filename: shader.cpp
*
* Description: Source for shader class
*
* Version: 1.0
* Created: 05/12/2014 10:55:10 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include <stdlib.h>


+ 38
- 0
src/graphics/shader.h View File

@@ -0,0 +1,38 @@
/*
* =====================================================================================
*
* Filename: shader.h
*
* Description: Shader that shades
*
* Version: 1.0
* Created: 05/12/2014 10:54:44 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include <string>

namespace vtk {

class Shader {
public:
bool activate(); //Must be called to use shader

//Load shader, type 0 = Vert, 1 = Frag, 2 = Geometry
bool loadShaderFromFile(const std::string& fileName, const unsigned& type);


protected:

};

}

+ 98
- 0
src/inputhandler.cpp View File

@@ -0,0 +1,98 @@
/*
* =====================================================================================
*
* Filename: inputhandler.cpp
*
* Description: Source for inputhandler
*
* Version: 1.0
* Created: 03/28/2014 06:19:17 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#include "inputhandler.h"

namespace vtk {

void InputHandler::update() {
while (SDL_PollEvent(&event) ) {
if (events.find(event.type) != events.end()) {
events[event.type]();
}
}
mouseButtons = SDL_GetMouseState(NULL, NULL);
keys = SDL_GetKeyboardState(NULL);
}

bool InputHandler::isActionDown(const std::string& action) {
ActionIdentifier& curAction = actions[action];
if (curAction.mouse) {
switch (curAction.mouseCode) {
case 1:
return mouseButtons&SDL_BUTTON(1);
break;
case 2:
return mouseButtons&SDL_BUTTON(2);
break;
case 3:
return mouseButtons&SDL_BUTTON(3);
break;
case 4:
return mouseButtons&SDL_BUTTON(4);
break;
case 5:
return mouseButtons&SDL_BUTTON(5);
break;
case 6:
return mouseButtons&SDL_BUTTON(6);
break;
case 7:
return mouseButtons&SDL_BUTTON(7);
break;
default:
break;
}
} else {
return keys[SDL_GetScancodeFromKey(curAction.keyCode)];
}
return false;
}

bool InputHandler::setAction(const std::string& actionName, const std::string& actionButton) {
ActionIdentifier newIdentifier;
if (actionButton.find("Mouse ") != std::string::npos) {
newIdentifier.mouse = true;
if (actionButton == "Mouse Left") {
newIdentifier.mouseCode = 1;
} else if (actionButton == "Mouse Middle") {
newIdentifier.mouseCode = 2;
} else if (actionButton == "Mouse Right") {
newIdentifier.mouseCode = 3;
} else if (actionButton == "Mouse Wheel Up") {
newIdentifier.mouseCode = 4;
} else if (actionButton == "Mouse Wheel Down") {
newIdentifier.mouseCode = 5;
} else if (actionButton == "Mouse Shoulder 1") {
newIdentifier.mouseCode = 6;
} else if (actionButton == "Mouse Shoulder 2") {
newIdentifier.mouseCode = 7;
}
} else {
newIdentifier.mouse = false;
newIdentifier.keyCode = SDL_GetKeyFromName(actionButton.c_str());
}
actions[actionName] = newIdentifier;
return true;
}

Nano::signal<void()>& InputHandler::getEventSignal(const Uint32& type) {
return events[type];
}

}

+ 49
- 0
src/inputhandler.h View File

@@ -0,0 +1,49 @@
/*
* =====================================================================================
*
* Filename: inputhandler.h
*
* Description: Passes input to an inputbridge
*
* Version: 1.0
* Created: 03/28/2014 06:19:01 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include <SDL2/SDL.h>
#include <map>
#include "nano_signal_slot.hpp"

namespace vtk {

struct ActionIdentifier {
SDL_Keycode keyCode; //Key code
unsigned mouseCode; //Mouse button code
bool mouse; //Is mouse button?

};

class InputHandler {
public:
void update();
bool isActionDown(const std::string& action);
bool setAction(const std::string& actionName, const std::string& actionButton);
Nano::signal<void()>& getEventSignal(const Uint32& type);

protected:
std::map<std::string, ActionIdentifier> actions;
std::map<Uint32, Nano::signal<void()> > events; //SDL Event type handling
Uint32 mouseButtons;
const Uint8* keys;
SDL_Event event;
};

}

+ 103
- 0
src/loadShader.cpp View File

@@ -0,0 +1,103 @@
/*
* =====================================================================================
*
* Filename: loadShader.cpp
*
* Description:
*
* Version: 1.0
* Created: 03/13/2014 03:28:10 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#include "loadShader.h"

#include <GL/glew.h>
#include <GL/gl.h>

#include <string>
#include <fstream>
#include <vector>
#include <algorithm>

GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open())
{
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> VertexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
// Link the program
fprintf(stdout, "Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage( std::max(InfoLogLength, int(1)) );
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}

+ 22
- 0
src/loadShader.h View File

@@ -0,0 +1,22 @@
/*
* =====================================================================================
*
* Filename: loadShader.h
*
* Description:
*
* Version: 1.0
* Created: 03/13/2014 04:13:08 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once
#include <GL/glew.h>

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path);

+ 24
- 0
src/main.cpp View File

@@ -0,0 +1,24 @@
#include "game.h"
#include "scenes/testscene.h"
#include "config.h"
#include "mathplus.h"

#include <iostream>


int main (int argc, char *argv[])
{
auto conf = new Config;
conf->loadConfigFromFile("res/config.conf");
conf->addArgumentRule("-w", "graphics.res.x");
conf->addArgumentRule("-h", "graphics.res.y");
conf->loadConfigFromArguments(argc, argv);

vtk::Game game;
game.setConfig(conf);
game.init();
game.setScene(new vtk::TestScene);
game.start();

return 0;
}

+ 757
- 0
src/mathfuncs.cpp View File

@@ -0,0 +1,757 @@

/******************************************************************************\
| OpenGL 4 Example Code. |
| Accompanies written series "Anton's OpenGL 4 Tutorials" |
| Email: anton at antongerdelan dot net |
| First version 27 Jan 2014 |
| Copyright Dr Anton Gerdelan, Trinity College Dublin, Ireland. |
| See individual libraries' separate legal notices |
|******************************************************************************|
| Commonly-used maths structures and functions |
| Simple-as-possible. No disgusting templates. |
| Structs vec3, mat4, versor. just hold arrays of floats called "v","m","q", |
| respectively. So, for example, to get values from a mat4 do: my_mat.m |
| A versor is the proper name for a unit quaternion. |
\******************************************************************************/
#include "mathfuncs.h"
#include <stdio.h>
#define _USE_MATH_DEFINES
#include <math.h>

/*--------------------------------CONSTRUCTORS--------------------------------*/
vec2::vec2 () {}

vec2::vec2 (float x, float y) {
v[0] = x;
v[1] = y;
}

vec3::vec3 () {}

vec3::vec3 (float x, float y, float z) {
v[0] = x;
v[1] = y;
v[2] = z;
}

vec3::vec3 (const vec2& vv, float z) {
v[0] = vv.v[0];
v[1] = vv.v[1];
v[2] = z;
}

vec3::vec3 (const vec4& vv) {
v[0] = vv.v[0];
v[1] = vv.v[1];
v[2] = vv.v[2];
}

vec4::vec4 () {}

vec4::vec4 (float x, float y, float z, float w) {
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
}

vec4::vec4 (const vec2& vv, float z, float w) {
v[0] = vv.v[0];
v[1] = vv.v[1];
v[2] = z;
v[3] = w;
}

vec4::vec4 (const vec3& vv, float w) {
v[0] = vv.v[0];
v[1] = vv.v[1];
v[2] = vv.v[2];
v[3] = w;
}

mat3::mat3 () {}

/* note: entered in COLUMNS */
mat3::mat3 (float a, float b, float c,
float d, float e, float f,
float g, float h, float i) {
m[0] = a;
m[1] = b;
m[2] = c;
m[3] = d;
m[4] = e;
m[5] = f;
m[6] = g;
m[7] = h;
m[8] = i;
}

mat4::mat4 () {}

/* note: entered in COLUMNS */
mat4::mat4 (float a, float b, float c, float d,
float e, float f, float g, float h,
float i, float j, float k, float l,