First World Class Implementation

- Added PerlinNoise.(cpp/hpp) to repository.
- New BlockChunk class for storing block info
- New MeshChunk class, extends Entity and has a `build` method for building a mesh
- World Class that encapsulates some world logic
- ArrayTrans3D class for converting vectors to ints in chunks
- Rewrote some code in Main to use the World class
- MeshGenerator now uses a blockChunk and a blockAtlas
- MeshGenerator is not doing any culling in this commit
- Changed addFaces to use a glm::vec3
- BlockAtlas now has a `model` variable containing a BlockModel
- Changed the window title to be more descriptive
- Changed references of 'atlas' to 'textureAtlas'
master
aurailus 2018-12-15 23:55:36 -08:00
parent d0c006d660
commit 188f6ff20e
18 changed files with 423 additions and 81 deletions

View File

@ -16,6 +16,6 @@ find_package(Boost COMPONENTS system thread)
link_directories(Libraries/glew/lib)
add_executable(GlProject GlProject/Main.cpp GlProject/engine/graphics/Mesh.cpp GlProject/engine/graphics/Mesh.h GlProject/engine/PerlinNoise.cpp GlProject/engine/PerlinNoise.h GlProject/engine/Entity.cpp GlProject/engine/Entity.h GlProject/engine/graphics/Shader.cpp GlProject/engine/graphics/Shader.h GlProject/engine/Window.cpp GlProject/engine/Window.h GlProject/engine/Camera.cpp GlProject/engine/Camera.h GlProject/engine/graphics/Texture.cpp GlProject/engine/graphics/Texture.h GlProject/mesh/MeshGenerator.cpp GlProject/mesh/MeshGenerator.h GlProject/engine/Timer.cpp GlProject/engine/Timer.h GlProject/blocks/BlockAtlas.cpp GlProject/blocks/BlockAtlas.h GlProject/blocks/BlockDef.cpp GlProject/blocks/BlockDef.h GlProject/mesh/MeshPart.cpp GlProject/mesh/MeshPart.h GlProject/mesh/MeshMod.h GlProject/mesh/Vertex.cpp GlProject/mesh/Vertex.h GlProject/mesh/BlockModel.cpp GlProject/mesh/BlockModel.h GlProject/engine/TextureAtlas.cpp GlProject/engine/TextureAtlas.h GlProject/UDP.cpp GlProject/UDP.h)
add_executable(GlProject GlProject/Main.cpp GlProject/engine/graphics/Mesh.cpp GlProject/engine/graphics/Mesh.h GlProject/engine/PerlinNoise.cpp GlProject/engine/PerlinNoise.h GlProject/engine/Entity.cpp GlProject/engine/Entity.h GlProject/engine/graphics/Shader.cpp GlProject/engine/graphics/Shader.h GlProject/engine/Window.cpp GlProject/engine/Window.h GlProject/engine/Camera.cpp GlProject/engine/Camera.h GlProject/engine/graphics/Texture.cpp GlProject/engine/graphics/Texture.h GlProject/mesh/MeshGenerator.cpp GlProject/mesh/MeshGenerator.h GlProject/engine/Timer.cpp GlProject/engine/Timer.h GlProject/blocks/BlockAtlas.cpp GlProject/blocks/BlockAtlas.h GlProject/blocks/BlockDef.cpp GlProject/blocks/BlockDef.h GlProject/mesh/MeshPart.cpp GlProject/mesh/MeshPart.h GlProject/mesh/MeshMod.h GlProject/mesh/Vertex.cpp GlProject/mesh/Vertex.h GlProject/mesh/BlockModel.cpp GlProject/mesh/BlockModel.h GlProject/engine/TextureAtlas.cpp GlProject/engine/TextureAtlas.h GlProject/UDP.cpp GlProject/UDP.h GlProject/world/World.cpp GlProject/world/World.h GlProject/world/BlockChunk.cpp GlProject/world/BlockChunk.h GlProject/engine/helpers/ArrayTrans3D.h GlProject/world/MeshChunk.cpp GlProject/world/MeshChunk.h)
target_link_libraries(GlProject ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread)

View File

@ -22,18 +22,22 @@
#include "engine/TextureAtlas.h"
#include "UDP.h"
#include "engine/PerlinNoise.h"
#include "world/World.h"
#include "engine/helpers/ArrayTrans3D.h"
Window* window;
Shader* shader;
std::vector<Entity*> entities;
Camera* camera;
TextureAtlas* atlas;
TextureAtlas* textureAtlas;
BlockAtlas* blockAtlas;
World* world;
GLfloat deltaTime = 0.0f;
GLfloat lastTime = 0.0f;
BlockModel* createBlockModel() {
BlockAtlas* createAtlas() {
Vertex* leftVerts = new Vertex[4] {
Vertex(new glm::vec3(0.0f, 0.0f, 0.0f), nullptr, new glm::vec2(0.0f, 1.0f)),
Vertex(new glm::vec3(0.0f, 0.0f, 1.0f), nullptr, new glm::vec2(1.0f, 1.0f)),
@ -44,7 +48,7 @@ BlockModel* createBlockModel() {
0, 1, 2, 2, 3, 0
};
auto* leftPart = new MeshPart(leftVerts, 4, leftInds, 6, "default_cobblestone", atlas);
auto* leftPart = new MeshPart(leftVerts, 4, leftInds, 6, "default_grass_side", textureAtlas);
Vertex* rightVerts = new Vertex[4] {
Vertex(new glm::vec3(1.0f, 0.0f, 0.0f), nullptr, new glm::vec2(0.0f, 1.0f)),
@ -56,7 +60,7 @@ BlockModel* createBlockModel() {
0, 1, 2, 2, 3, 0
};
auto* rightPart = new MeshPart(rightVerts, 4, rightInds, 6, "default_cobblestone", atlas);
auto* rightPart = new MeshPart(rightVerts, 4, rightInds, 6, "default_grass_side", textureAtlas);
Vertex* topVerts = new Vertex[4] {
Vertex(new glm::vec3(0.0f, 1.0f, 0.0f), nullptr, new glm::vec2(0.0f, 0.0f)),
@ -68,7 +72,7 @@ BlockModel* createBlockModel() {
0, 1, 2, 2, 3, 0
};
auto* topPart = new MeshPart(topVerts, 4, topInds, 6, "default_cobblestone", atlas);
auto* topPart = new MeshPart(topVerts, 4, topInds, 6, "default_grass_top", textureAtlas);
Vertex* bottomVerts = new Vertex[4] {
Vertex(new glm::vec3(0.0f, 0.0f, 0.0f), nullptr, new glm::vec2(0.0f, 0.0f)),
@ -80,7 +84,7 @@ BlockModel* createBlockModel() {
0, 1, 2, 2, 3, 0
};
auto* bottomPart = new MeshPart(bottomVerts, 4, bottomInds, 6, "default_cobblestone", atlas);
auto* bottomPart = new MeshPart(bottomVerts, 4, bottomInds, 6, "default_dirt", textureAtlas);
Vertex* frontVerts = new Vertex[4] {
Vertex(new glm::vec3(0.0f, 0.0f, 1.0f), nullptr, new glm::vec2(0.0f, 1.0f)),
@ -92,7 +96,7 @@ BlockModel* createBlockModel() {
0, 1, 2, 2, 3, 0
};
auto* frontPart = new MeshPart(frontVerts, 4, frontInds, 6, "default_cobblestone", atlas);
auto* frontPart = new MeshPart(frontVerts, 4, frontInds, 6, "default_grass_side", textureAtlas);
Vertex* backVerts = new Vertex[4] {
Vertex(new glm::vec3(0.0f, 0.0f, 0.0f), nullptr, new glm::vec2(0.0f, 1.0f)),
@ -104,49 +108,40 @@ BlockModel* createBlockModel() {
0, 1, 2, 2, 3, 0
};
auto* backPart = new MeshPart(backVerts, 4, backInds, 6, "default_cobblestone", atlas);
auto* backPart = new MeshPart(backVerts, 4, backInds, 6, "default_grass_side", textureAtlas);
return new BlockModel(leftPart, rightPart, topPart, bottomPart, frontPart, backPart, nullptr, true, true);
auto* bm = new BlockModel(leftPart, rightPart, topPart, bottomPart, frontPart, backPart, nullptr, true, true);
return new BlockAtlas(bm);
}
void makeEntities(BlockModel* model) {
void genChunks(World* world) {
PerlinNoise p(0);
int VIEW_RANGE = 12;
int VIEW_RANGE = 1;
for (int i = -VIEW_RANGE; i < VIEW_RANGE; i++) {
for (int j = -VIEW_RANGE; j < VIEW_RANGE; j++) {
for (int k = -8; k < 4; k++) {
for (int k = -2; k < 2; k++) {
int array[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];
auto* blocks = new std::vector<int>();
blocks->reserve(4096);
for (int x = 0; x < CHUNK_SIZE; x++) { // NOLINT(modernize-loop-convert)
for (int z = 0; z < CHUNK_SIZE; z++) {
for (int y = 0; y < CHUNK_SIZE; y++) {
int xx = x + i * 16;
int yy = y + k * 16;
int zz = z + j * 16;
double val = p.noise(xx / (double) 16, zz / (double) 16, yy / (double) 16);
glm::vec3 innerPos, pos;
array[z][y][x] = (int) (val > 0.5);
}
}
for (int ind = 0; ind < 4096; ind++) {
ArrayTrans3D::indAssignVec(ind, &innerPos);
pos.x = innerPos.x + i * CHUNK_SIZE;
pos.y = innerPos.y + k * CHUNK_SIZE;
pos.z = innerPos.z + j * CHUNK_SIZE;
double val = p.noise(pos.x / (double) 32, pos.z / (double) 32, pos.y / (double) 16) - pos.y * 0.08;
std::cout << (int)(val > 0.5) << std::endl;
blocks->push_back((int)(val > 0.5));
}
std::vector<float> vertices;
std::vector<unsigned int> indices;
MeshGenerator mg;
mg.build(array, model, vertices, indices);
auto *mesh = new Mesh();
mesh->create(&vertices, &indices);
auto *chunk = new Entity();
chunk->create(mesh);
chunk->setPosition(glm::vec3(i * CHUNK_SIZE, k * CHUNK_SIZE, j * CHUNK_SIZE));
chunk->setScale(1);
entities.push_back(chunk);
world->newChunk(new glm::vec3(i, k, j), new BlockChunk(blocks));
}
}
}
@ -166,13 +161,19 @@ int main(int argc, char* argv[]) {
camera = new Camera(glm::vec3(0.0f, 16.0f, 0.0f), glm::vec3(0, 1, 0), -90.0f, -45.0f, 10.0f, 0.1f);
//Load Textures
atlas = new TextureAtlas("../Textures");
textureAtlas = new TextureAtlas("../Textures");
//Create model
BlockModel* model = createBlockModel();
blockAtlas = createAtlas();
//Create entities
makeEntities(model);
//Create world
world = new World(blockAtlas);
// for (int i = 0; i < 17; i++) {
// world->newChunk(new glm::vec3(i, 0, 0), nullptr);
// }
//Generate Chunks
genChunks(world);
//Create shader
shader = new Shader();
@ -201,6 +202,8 @@ int main(int argc, char* argv[]) {
camera->keyControl(window->getKeysArray(), deltaTime);
camera->mouseControl(window->getDeltaX(), window->getDeltaY());
world->update();
//Clear Window
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -210,12 +213,14 @@ int main(int argc, char* argv[]) {
glUniformMatrix4fv(shader->getProjectionLocation(), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glUniformMatrix4fv(shader->getViewLocation(), 1, GL_FALSE, glm::value_ptr(camera->calculateViewMatrix()));
atlas->getTexture()->use();
textureAtlas->getTexture()->use();
for (auto &entity : entities) {
glUniformMatrix4fv(shader->getModelLocation(), 1, GL_FALSE, glm::value_ptr(entity->getModelMatrix()));
entity->draw();
}
// for (auto &entity : entities) {
// glUniformMatrix4fv(shader->getModelLocation(), 1, GL_FALSE, glm::value_ptr(entity->getModelMatrix()));
// entity->draw();
// }
world->draw(shader->getModelLocation());
Shader::clearShader();

View File

@ -3,3 +3,11 @@
//
#include "BlockAtlas.h"
BlockAtlas::BlockAtlas(BlockModel *model) {
blockModel = model;
}
BlockModel* BlockAtlas::getBlockModel() {
return blockModel;
}

View File

@ -6,8 +6,16 @@
#define GLPROJECT_BLOCKATLAS_H
class BlockAtlas {
#include "../mesh/BlockModel.h"
class BlockAtlas {
public:
BlockAtlas() = default;
explicit BlockAtlas(BlockModel* model);
BlockModel* getBlockModel();
private:
BlockModel* blockModel;
};

View File

@ -0,0 +1,94 @@
#include "PerlinNoise.h"
#include <cmath>
#include <random>
#include <algorithm>
#include <numeric>
// THIS IS A DIRECT TRANSLATION TO C++11 FROM THE REFERENCE
// JAVA IMPLEMENTATION OF THE IMPROVED PERLIN FUNCTION (see http://mrl.nyu.edu/~perlin/noise/)
// THE ORIGINAL JAVA IMPLEMENTATION IS COPYRIGHT 2002 KEN PERLIN
// I ADDED AN EXTRA METHOD THAT GENERATES A NEW PERMUTATION VECTOR (THIS IS NOT PRESENT IN THE ORIGINAL IMPLEMENTATION)
// Initialize with the reference values for the permutation vector
PerlinNoise::PerlinNoise() {
// Initialize the permutation vector with the reference values
p = {
151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,
8,99,37,240,21,10,23,190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,
35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,
134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,
55,46,245,40,244,102,143,54, 65,25,63,161,1,216,80,73,209,76,132,187,208, 89,
18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,
250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,
189,28,42,223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167,
43,172,9,129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,
97,228,251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,
107,49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 };
// Duplicate the permutation vector
p.insert(p.end(), p.begin(), p.end());
}
// Generate a new permutation vector based on the value of seed
PerlinNoise::PerlinNoise(unsigned int seed) {
p.resize(256);
// Fill p with values from 0 to 255
std::iota(p.begin(), p.end(), 0);
// Initialize a random engine with seed
std::default_random_engine engine(seed);
// Suffle using the above random engine
std::shuffle(p.begin(), p.end(), engine);
// Duplicate the permutation vector
p.insert(p.end(), p.begin(), p.end());
}
double PerlinNoise::noise(double x, double y, double z) {
// Find the unit cube that contains the point
int X = (int) floor(x) & 255;
int Y = (int) floor(y) & 255;
int Z = (int) floor(z) & 255;
// Find relative x, y,z of point in cube
x -= floor(x);
y -= floor(y);
z -= floor(z);
// Compute fade curves for each of x, y, z
double u = fade(x);
double v = fade(y);
double w = fade(z);
// Hash coordinates of the 8 cube corners
int A = p[X] + Y;
int AA = p[A] + Z;
int AB = p[A + 1] + Z;
int B = p[X + 1] + Y;
int BA = p[B] + Z;
int BB = p[B + 1] + Z;
// Add blended results from 8 corners of cube
double res = lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), grad(p[BA], x-1, y, z)), lerp(u, grad(p[AB], x, y-1, z), grad(p[BB], x-1, y-1, z))), lerp(v, lerp(u, grad(p[AA+1], x, y, z-1), grad(p[BA+1], x-1, y, z-1)), lerp(u, grad(p[AB+1], x, y-1, z-1), grad(p[BB+1], x-1, y-1, z-1))));
return (res + 1.0)/2.0;
}
double PerlinNoise::fade(double t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
double PerlinNoise::lerp(double t, double a, double b) {
return a + t * (b - a);
}
double PerlinNoise::grad(int hash, double x, double y, double z) {
int h = hash & 15;
// Convert lower 4 bits of hash into 12 gradient directions
double u = h < 8 ? x : y,
v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}

View File

@ -0,0 +1,28 @@
// THIS CLASS IS A TRANSLATION TO C++11 FROM THE REFERENCE
// JAVA IMPLEMENTATION OF THE IMPROVED PERLIN FUNCTION (see http://mrl.nyu.edu/~perlin/noise/)
// THE ORIGINAL JAVA IMPLEMENTATION IS COPYRIGHT 2002 KEN PERLIN
// I ADDED AN EXTRA METHOD THAT GENERATES A NEW PERMUTATION VECTOR (THIS IS NOT PRESENT IN THE ORIGINAL IMPLEMENTATION)
#ifndef PERLINNOISE_H
#define PERLINNOISE_H
#include <vector>
class PerlinNoise {
// The permutation vector
std::vector<int> p;
public:
// Initialize with the reference values for the permutation vector
PerlinNoise();
// Generate a new permutation vector based on the value of seed
PerlinNoise(unsigned int seed);
// Get a noise value, for 2D images z can have any value
double noise(double x, double y, double z);
private:
double fade(double t);
double lerp(double t, double a, double b);
double grad(int hash, double x, double y, double z);
};
#endif

View File

@ -94,7 +94,7 @@ TextureAtlas::TextureAtlas(const char* directory) {
pageData[i * 4 + 3] = 0;
}
//Add all of the textures to the atlas and store the UVs in the associative array
//Add all of the textures to the textureAtlas and store the UVs in the associative array
int widthOffset = 0;
int heightOffset = 0;
int tallestInRow = 0;
@ -130,7 +130,7 @@ TextureAtlas::TextureAtlas(const char* directory) {
widthOffset += i.width;
}
stbi_write_png("../atlas.png", pageWidth, pageHeight, 4, pageData, pageWidth*4);
stbi_write_png("../textureAtlas.png", pageWidth, pageHeight, 4, pageData, pageWidth*4);
texture = new Texture();
texture->load(pageData, pageWidth, pageHeight);
}
@ -141,7 +141,7 @@ Texture* TextureAtlas::getTexture() {
glm::vec4* TextureAtlas::getUVs(std::string* texture) {
if (textures.count(*texture) == 0) {
std::cout << "Texture '" << *texture << "' Not found in atlas! Terminating." << std::endl;
std::cout << "Texture '" << *texture << "' Not found in textureAtlas! Terminating." << std::endl;
throw std::exception();
}
return &textures.at(*texture);

View File

@ -43,7 +43,7 @@ int Window::initialize() {
// glEnable(GL_MULTISAMPLE);
//Create the window
mainWindow = glfwCreateWindow(width, height, "OpenGL Learning", nullptr, nullptr);
mainWindow = glfwCreateWindow(width, height, "Zeus_cpp OPENGL Linux x64", nullptr, nullptr);
if (!mainWindow) {
printf("GLFW window failed");

View File

@ -0,0 +1,39 @@
//
// Created by aurailus on 14/12/18.
//
#ifndef GLPROJECT_ARRAYTRANS3D_H
#define GLPROJECT_ARRAYTRANS3D_H
#include <vec3.hpp>
class ArrayTrans3D {
static const int SIZE = 16;
public:
static void indAssignVec(int ind, glm::vec3* vec) {
vec->z = ind / (SIZE * SIZE);
ind -= ((int)vec->z * SIZE * SIZE);
vec->y = ind / SIZE;
vec->x = ind % SIZE;
}
static glm::vec3* indToVec(int ind) {
int z = ind / (SIZE * SIZE);
ind -= (z * SIZE * SIZE);
int y = ind / SIZE;
int x = ind % SIZE;
return new glm::vec3(x, y, z);
}
static unsigned int vecToInd(glm::vec3* vec) {
return vecToInd((int)vec->x, (int)vec->y, (int)vec->z);
}
static unsigned int vecToInd(int x, int y, int z) {
return (unsigned int)(x + SIZE * (y + SIZE * z));
}
};
#endif //GLPROJECT_ARRAYTRANS3D_H

View File

@ -2,9 +2,8 @@
// Created by aurailus on 01/12/18.
//
#include <cstdio>
#include "MeshGenerator.h"
#include "../engine/Timer.h"
#include "../engine/helpers/ArrayTrans3D.h"
MeshGenerator::MeshGenerator() {
indOffset = 0;
@ -14,8 +13,8 @@ bool outOfRange(glm::vec3 pos) {
return (pos.x < 0 || pos.x > 15 || pos.y < 0 || pos.y > 15 || pos.z < 0 || pos.z > 15);
}
void MeshGenerator::build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE], BlockModel* model,
std::vector<float> &vertices, std::vector<unsigned int> &indices) {
void MeshGenerator::build(BlockChunk* chunk, BlockAtlas* atlas,
std::vector<float> &vertices, std::vector<unsigned int> &indices) {
Timer t("Mesh Generation");
@ -24,32 +23,31 @@ void MeshGenerator::build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE], BlockM
glm::vec3 off;
BlockModel* model = atlas->getBlockModel();
for (int i = 0; i < 4096; i++) {
int idx = i;
int z = idx / (CHUNK_SIZE * CHUNK_SIZE);
idx -= (z * CHUNK_SIZE * CHUNK_SIZE);
int y = idx / CHUNK_SIZE;
int x = idx % CHUNK_SIZE;
if (blocks[z][y][x] == 1) {
if (chunk->getBlock(i) == 1) {
if (outOfRange(glm::vec3(x - 1, y, z)) || blocks[z][y][x - 1] == 0)
addFaces(x, y, z, &vertices, &indices, &model->leftFaces);
ArrayTrans3D::indAssignVec(i, &off);
if (outOfRange(glm::vec3(x + 1, y, z)) || blocks[z][y][x + 1] == 0)
addFaces(x, y, z, &vertices, &indices, &model->rightFaces);
// if (outOfRange(glm::vec3(x - 1, y, z)) || blocks[z][y][x - 1] == 0)
addFaces(off, &vertices, &indices, &model->leftFaces);
if (outOfRange(glm::vec3(x, y - 1, z)) || blocks[z][y - 1][x] == 0)
addFaces(x, y, z, &vertices, &indices, &model->bottomFaces);
// if (outOfRange(glm::vec3(x + 1, y, z)) || blocks[z][y][x + 1] == 0)
addFaces(off, &vertices, &indices, &model->rightFaces);
if (outOfRange(glm::vec3(x, y + 1, z)) || blocks[z][y + 1][x] == 0)
addFaces(x, y, z, &vertices, &indices, &model->topFaces);
// if (outOfRange(glm::vec3(x, y - 1, z)) || blocks[z][y - 1][x] == 0)
addFaces(off, &vertices, &indices, &model->bottomFaces);
if (outOfRange(glm::vec3(x, y, z - 1)) || blocks[z - 1][y][x] == 0)
addFaces(x, y, z, &vertices, &indices, &model->backFaces);
// if (outOfRange(glm::vec3(x, y + 1, z)) || blocks[z][y + 1][x] == 0)
addFaces(off, &vertices, &indices, &model->topFaces);
if (outOfRange(glm::vec3(x, y, z + 1)) || blocks[z + 1][y][x] == 0)
addFaces(x, y, z, &vertices, &indices, &model->frontFaces);
// if (outOfRange(glm::vec3(x, y, z - 1)) || blocks[z - 1][y][x] == 0)
addFaces(off, &vertices, &indices, &model->backFaces);
// if (outOfRange(glm::vec3(x, y, z + 1)) || blocks[z + 1][y][x] == 0)
addFaces(off, &vertices, &indices, &model->frontFaces);
}
}
@ -59,16 +57,16 @@ void MeshGenerator::build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE], BlockM
t.elapsedMs();
}
void MeshGenerator::addFaces(int x, int y, int z, vector<float>* vertices, vector<unsigned int>* indices, vector<MeshPart*>* meshParts) {
void MeshGenerator::addFaces(glm::vec3 &offset, vector<float>* vertices, vector<unsigned int>* indices, vector<MeshPart*>* meshParts) {
for (MeshPart *mp : *meshParts) {
MeshVertexIter *mvIterator = mp->getVertexIterator();
while (mvIterator->hasNext()) {
Vertex *vertex = mvIterator->next();
vertices->push_back(vertex->pos->x + x);
vertices->push_back(vertex->pos->y + y);
vertices->push_back(vertex->pos->z + z);
vertices->push_back(vertex->pos->x + offset.x);
vertices->push_back(vertex->pos->y + offset.y);
vertices->push_back(vertex->pos->z + offset.z);
vertices->push_back(vertex->tex->x);
vertices->push_back(vertex->tex->y);

View File

@ -10,20 +10,24 @@
#include "BlockModel.h"
#include <vector>
#include <gtx/normal.hpp>
#include <cstdio>
#include "../engine/Timer.h"
#include "../blocks/BlockAtlas.h"
#include "../world/BlockChunk.h"
const int CHUNK_SIZE = 16;
class MeshGenerator {
public:
MeshGenerator();
void build(int blocks[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE], BlockModel* model,
void build(BlockChunk* chunk, BlockAtlas* atlas,
std::vector<float> &vertices, std::vector<unsigned int> &indices);
~MeshGenerator();
private:
unsigned int indOffset;
void addFaces(int x, int y, int z, vector<float>* vertices, vector<unsigned int>* indices, vector<MeshPart*>* meshParts);
void addFaces(glm::vec3 &offset, vector<float>* vertices, vector<unsigned int>* indices, vector<MeshPart*>* meshParts);
void cleanup();
};

View File

@ -49,7 +49,7 @@ void MeshPart::construct(Vertex* vertices, int vSize, unsigned int *indices, int
auto uv = atlas->getUVs(&texString);
// std::cout << uv->x << ", " << uv->y << ", " << uv->z << ", " << uv->w << ", " << std::endl;
//Iterate through the vertices to adjust the texture coordinates to fit the atlas.
//Iterate through the vertices to adjust the texture coordinates to fit the textureAtlas.
for (int i = 0; i < vSize; i++) {
Vertex* vertex = &vertices[i];

View File

@ -0,0 +1,28 @@
//
// Created by aurailus on 14/12/18.
//
#include <iostream>
#include "BlockChunk.h"
#include "../engine/helpers/ArrayTrans3D.h"
BlockChunk::BlockChunk(std::vector<int>* blocks) {
this->blocks = blocks;
}
int BlockChunk::getBlock(glm::vec3* pos) {
unsigned int ind = ArrayTrans3D::vecToInd(pos);
if (ind < 0 || ind >= 4096) return -1;
return blocks->at(ind);
}
int BlockChunk::getBlock(int ind) {
if (ind < 0 || ind >= 4096) return -1;
return blocks->at((unsigned long)ind);
}
int BlockChunk::getBlock(int x, int y, int z) {
unsigned int ind = ArrayTrans3D::vecToInd(x, y, z);
if (ind < 0 || ind >= 4096) return -1;
return blocks->at(ind);
}

View File

@ -0,0 +1,25 @@
//
// Created by aurailus on 14/12/18.
//
#ifndef GLPROJECT_BLOCKCHUNK_H
#define GLPROJECT_BLOCKCHUNK_H
#include <vec3.hpp>
#include <vector>
class BlockChunk {
public:
BlockChunk() = default;
explicit BlockChunk(std::vector<int>* blocks);
int getBlock(int ind);
int getBlock(glm::vec3* pos);
int getBlock(int x, int y, int z);
//TODO: Add block setting methods as well
private:
std::vector<int>* blocks;
};
#endif //GLPROJECT_BLOCKCHUNK_H

View File

@ -0,0 +1,27 @@
//
// Created by aurailus on 15/12/18.
//
#ifndef GLPROJECT_MESHCHUNK_H
#define GLPROJECT_MESHCHUNK_H
#include "BlockChunk.h"
#include "../engine/Entity.h"
#include "../mesh/MeshGenerator.h"
class MeshChunk : public Entity {
public:
MeshChunk();
explicit MeshChunk(BlockChunk* blockChunk);
void build(BlockAtlas* atlas);
bool isReady();
private:
bool ready;
BlockChunk* blockChunk;
};
#endif //GLPROJECT_MESHCHUNK_H

36
GlProject/world/World.cpp Normal file
View File

@ -0,0 +1,36 @@
//
// Created by aurailus on 14/12/18.
//
#include "World.h"
World::World(BlockAtlas *atlas) {
blockAtlas = atlas;
}
void World::newChunk(glm::vec3* pos, BlockChunk *c) {
blockChunks.insert(std::pair<glm::vec3*, BlockChunk*>(pos, c));
meshGenQueue.insert(pos);
}
void World::update() {
int done = 0;
while (!meshGenQueue.empty() && done < 8) {
auto it = meshGenQueue.begin();
meshGenQueue.erase(meshGenQueue.begin());
glm::vec3* pos = (*it);
auto meshChunk = new MeshChunk(blockChunks.at(pos));
meshChunk->build(blockAtlas);
meshChunk->setPosition(glm::vec3(pos->x * CHUNK_SIZE, pos->y * CHUNK_SIZE, pos->z * CHUNK_SIZE));
meshChunks.insert(std::pair<glm::vec3*, MeshChunk*>(pos, meshChunk));
}
}
void World::draw(GLint modelUni) {
for (auto &meshChunk : meshChunks) {
glUniformMatrix4fv(modelUni, 1, GL_FALSE, glm::value_ptr(meshChunk.second->getModelMatrix()));
meshChunk.second->draw();
}
}

42
GlProject/world/World.h Normal file
View File

@ -0,0 +1,42 @@
//
// Created by aurailus on 14/12/18.
//
#ifndef GLPROJECT_WORLD_H
#define GLPROJECT_WORLD_H
#include <map>
#include <vec3.hpp>
#include <unordered_set>
#include <iostream>
#include <gtc/type_ptr.hpp>
#include "BlockChunk.h"
#include "MeshChunk.h"
#include "../blocks/BlockAtlas.h"
class World {
public:
World() = default;
explicit World(BlockAtlas* atlas);
void newChunk(glm::vec3* pos, BlockChunk* c);
void update();
void draw(GLint modelUni);
~World() = default;
private:
//Note to self:
//The same glm::vec3 pointer is used for the blockChunk and meshChunk maps. If discarding a block/meshChunk, keep
//this in mind. If this needs to be changed later change the 'update' method.
std::map<glm::vec3*, BlockChunk*> blockChunks;
std::map<glm::vec3*, MeshChunk*> meshChunks;
std::unordered_set<glm::vec3*> meshGenQueue;
BlockAtlas* blockAtlas;
};
#endif //GLPROJECT_WORLD_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B