Browse Source

Initial commit

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

12
CMakeLists.txt

@ -0,0 +1,12 @@ @@ -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
res/config.conf

@ -0,0 +1,26 @@ @@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

BIN
res/dirt.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

BIN
res/grass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

7
res/shaders/test.frag.glsl

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
#version 440
out vec4 outColor;
void main() {
outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

8
res/shaders/test.vert.glsl

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
#version 440
layout(location = 0) in vec3 position;
void main() {
gl_Position = vec4(position, 1.0);
}

14
res/shaders/voxelfrag.frag.glsl

@ -0,0 +1,14 @@ @@ -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
res/shaders/voxelvert.vert.glsl

@ -0,0 +1,16 @@ @@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 B

44
res/stone.vmd

@ -0,0 +1,44 @@ @@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
res/test2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
res/tileset.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
res/tileset.xcf

Binary file not shown.

63
src/bitmap.cpp

@ -0,0 +1,63 @@ @@ -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
src/bitmap.h

@ -0,0 +1,42 @@ @@ -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
src/camera.cpp

@ -0,0 +1,109 @@ @@ -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
src/camera.h

@ -0,0 +1,60 @@ @@ -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
src/chunk.cpp

@ -0,0 +1,73 @@ @@ -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
src/chunk.h

@ -0,0 +1,46 @@ @@ -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
src/chunkrenderer.cpp

@ -0,0 +1,393 @@ @@ -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
src/chunkrenderer.h

@ -0,0 +1,86 @@ @@ -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
src/config.cpp

@ -0,0 +1,27 @@ @@ -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
src/config.h

@ -0,0 +1,150 @@ @@ -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
src/customnoise/gradientnoise.cpp

@ -0,0 +1,47 @@ @@ -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
src/customnoise/gradientnoise.h

@ -0,0 +1,43 @@ @@ -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;
};