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
parent
d0c006d660
commit
188f6ff20e
|
@ -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)
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -3,3 +3,11 @@
|
|||
//
|
||||
|
||||
#include "BlockAtlas.h"
|
||||
|
||||
BlockAtlas::BlockAtlas(BlockModel *model) {
|
||||
blockModel = model;
|
||||
}
|
||||
|
||||
BlockModel* BlockAtlas::getBlockModel() {
|
||||
return blockModel;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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 |
Loading…
Reference in New Issue