experimental multithreaded generation and meshing
parent
2ec728897e
commit
716056b8c5
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "block.hpp"
|
||||
#include "spacefilling.hpp"
|
||||
|
@ -22,8 +24,9 @@ namespace Chunk
|
|||
|
||||
constexpr uint8_t CHUNK_STATE_GENERATED = 1;
|
||||
constexpr uint8_t CHUNK_STATE_MESHED = 2;
|
||||
constexpr uint8_t CHUNK_STATE_LOADED = 3;
|
||||
constexpr uint8_t CHUNK_STATE_EMPTY = 4;
|
||||
constexpr uint8_t CHUNK_STATE_MESH_LOADED = 3;
|
||||
constexpr uint8_t CHUNK_STATE_LOADED = 4;
|
||||
constexpr uint8_t CHUNK_STATE_EMPTY = 7;
|
||||
|
||||
int coord3DTo1D(int x, int y, int z);
|
||||
|
||||
|
@ -48,11 +51,17 @@ namespace Chunk
|
|||
|
||||
public:
|
||||
GLuint VAO{0}, VBO{0}, EBO{0}, colorBuffer{0}, vIndex{0};
|
||||
|
||||
std::mutex mutex_state;
|
||||
|
||||
std::vector<GLfloat> vertices;
|
||||
std::vector<GLfloat> colors;
|
||||
std::vector<GLuint> indices;
|
||||
|
||||
private:
|
||||
glm::vec3 position{};
|
||||
IntervalMap<Block> blocks{};
|
||||
|
||||
|
||||
std::bitset<8> state{0};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
#ifndef CHUNKMANAGER_H
|
||||
#define CHUNKMANAGER_H
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace chunkmanager
|
||||
{
|
||||
void init();
|
||||
std::thread initGenThread();
|
||||
std::thread initMeshThread();
|
||||
void update(float deltaTime);
|
||||
void updateChunk(uint32_t, uint16_t, uint16_t, uint16_t);
|
||||
void destroy();
|
||||
|
||||
void mesh();
|
||||
void generate();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -10,11 +10,14 @@
|
|||
#include "globals.hpp"
|
||||
#include "shader.hpp"
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace chunkmesher{
|
||||
void mesh(Chunk::Chunk* chunk);
|
||||
void draw(Chunk::Chunk* chunk, glm::mat4 model);
|
||||
|
||||
void quad(glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, glm::vec3 bottomRight, Block block, bool backFace);
|
||||
void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, glm::vec3 bottomRight, Block block, bool backFace);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -9,31 +9,129 @@
|
|||
#include "globals.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <thread>
|
||||
|
||||
std::unordered_map<std::uint32_t, Chunk::Chunk*> chunks;
|
||||
std::unordered_map<std::uint32_t, Chunk::Chunk *> chunks;
|
||||
|
||||
namespace chunkmanager
|
||||
{
|
||||
void init()
|
||||
std::mutex mutex_queue_generate;
|
||||
std::set<Chunk::Chunk *> to_generate;
|
||||
std::set<Chunk::Chunk *> to_generate_shared;
|
||||
|
||||
std::mutex mutex_queue_mesh;
|
||||
std::set<Chunk::Chunk *> to_mesh;
|
||||
std::set<Chunk::Chunk *> to_mesh_shared;
|
||||
|
||||
void mesh()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (mutex_queue_mesh.try_lock())
|
||||
{
|
||||
for (const auto &c : to_mesh)
|
||||
{
|
||||
if (c->mutex_state.try_lock())
|
||||
{
|
||||
chunkmesher::mesh(c);
|
||||
c->setState(Chunk::CHUNK_STATE_MESHED, true);
|
||||
c->mutex_state.unlock();
|
||||
}
|
||||
}
|
||||
to_mesh.clear();
|
||||
mutex_queue_mesh.unlock();
|
||||
}
|
||||
|
||||
// while (!to_mesh.empty())
|
||||
// {
|
||||
|
||||
// Chunk::Chunk *c = to_mesh.front();
|
||||
|
||||
// if (c->mutex_state.try_lock())
|
||||
// {
|
||||
// chunkmesher::mesh(c);
|
||||
// // std::cout << "Meshing chunk at " << c->getPosition().x << ", " << c->getPosition().y << ", " << c->getPosition().z << "\n";
|
||||
// c->setState(Chunk::CHUNK_STATE_MESHED, true);
|
||||
// c->mutex_state.unlock();
|
||||
// to_mesh.pop();
|
||||
// }
|
||||
// }
|
||||
// if(mutex_queue_mesh.try_lock()){
|
||||
// to_mesh = to_mesh_shared;
|
||||
// mutex_queue_mesh.unlock();
|
||||
// }
|
||||
// std::cout << "To mesh empty\n";
|
||||
}
|
||||
}
|
||||
|
||||
void generate()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (mutex_queue_generate.try_lock())
|
||||
{
|
||||
for (const auto &c : to_generate)
|
||||
{
|
||||
if (c->mutex_state.try_lock())
|
||||
{
|
||||
generateChunk(c);
|
||||
c->setState(Chunk::CHUNK_STATE_GENERATED, true);
|
||||
c->mutex_state.unlock();
|
||||
}
|
||||
}
|
||||
to_generate.clear();
|
||||
mutex_queue_generate.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::thread initMeshThread()
|
||||
{
|
||||
std::thread mesh_thread(mesh);
|
||||
return mesh_thread;
|
||||
}
|
||||
std::thread initGenThread()
|
||||
{
|
||||
std::thread gen_thread(generate);
|
||||
return gen_thread;
|
||||
}
|
||||
|
||||
int total{0}, toGpu{0};
|
||||
int rr{RENDER_DISTANCE * RENDER_DISTANCE};
|
||||
uint8_t f = 0;
|
||||
|
||||
void update(float deltaTime)
|
||||
{
|
||||
f = 0;
|
||||
f |= mutex_queue_generate.try_lock();
|
||||
f |= mutex_queue_mesh.try_lock() << 1;
|
||||
|
||||
// Iterate over all chunks, in concentric spheres starting fron the player and going outwards
|
||||
// Eq. of the sphere (x - a)² + (y - b)² + (z - c)² = r²
|
||||
glm::vec3 cameraPos = theCamera.getPos();
|
||||
|
||||
int chunkX{(static_cast<int>(cameraPos.x)) / CHUNK_SIZE}, chunkY{(static_cast<int>(cameraPos.y)) / CHUNK_SIZE}, chunkZ{(static_cast<int>(cameraPos.z)) / CHUNK_SIZE};
|
||||
|
||||
|
||||
// Possible change: coordinates everything at the origin, then translate later?
|
||||
// Step 1. Eq. of a circle. Fix the x coordinate, get the 2 possible y's
|
||||
for (int x = chunkX - RENDER_DISTANCE; x <= chunkX + RENDER_DISTANCE; x++)
|
||||
int xp{0}, x{0};
|
||||
bool b = true;
|
||||
while (xp <= RENDER_DISTANCE)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
x = chunkX + xp;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = chunkX - xp;
|
||||
}
|
||||
// for (int x = chunkX - RENDER_DISTANCE; x < chunkX + RENDER_DISTANCE; x++)
|
||||
// {
|
||||
|
||||
// Possible optimization: use sqrt lookup
|
||||
int y1 = sqrt((rr) - (x - chunkX) * (x - chunkX)) + chunkY;
|
||||
|
@ -49,7 +147,6 @@ namespace chunkmanager
|
|||
|
||||
for (int z = z2; z <= z1; z++)
|
||||
{
|
||||
|
||||
uint16_t i{}, j{}, k{};
|
||||
|
||||
if (x < 0)
|
||||
|
@ -77,42 +174,138 @@ namespace chunkmanager
|
|||
chunkmanager::updateChunk(in, i, j, k);
|
||||
}
|
||||
}
|
||||
|
||||
if (!b)
|
||||
{
|
||||
xp++;
|
||||
b = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
std::cout << "Total chunks to draw: " << total << ". Sent to GPU: " << toGpu << "\n";
|
||||
total = 0;
|
||||
toGpu = 0;
|
||||
// std::cout << "Total chunks to draw: " << total << ". Sent to GPU: " << toGpu << "\n";
|
||||
// total = 0;
|
||||
// toGpu = 0;
|
||||
|
||||
if ((f & 1))
|
||||
mutex_queue_generate.unlock();
|
||||
if ((f & 2))
|
||||
mutex_queue_mesh.unlock();
|
||||
}
|
||||
|
||||
// Generation and meshing happen in two separate threads from the main one
|
||||
// Chunk states are used to decide which actions need to be done on the chunk and queues+mutexes to pass the chunks between the threads
|
||||
// Uploading data to GPU still needs to be done in the main thread, or another OpenGL context needs to be opened, which further complicates stuff
|
||||
// For now using frustum culling decreases performance (somehow)
|
||||
void updateChunk(uint32_t index, uint16_t i, uint16_t j, uint16_t k)
|
||||
{
|
||||
// std::cout << "Checking" << i << ", " << j << ", " << k <<std::endl;
|
||||
if (chunks.find(index) == chunks.end())
|
||||
{
|
||||
chunks.insert(std::make_pair(index, new Chunk::Chunk(glm::vec3(i, j, k))));
|
||||
generateChunk(chunks.at(index));
|
||||
mesh(chunks.at(index));
|
||||
// std::cout << "Creating new chunk" << i << ", " << j << ", " << k <<std::endl;
|
||||
Chunk::Chunk *c = new Chunk::Chunk(glm::vec3(i, j, k));
|
||||
chunks.insert(std::make_pair(index, c));
|
||||
}
|
||||
else
|
||||
{
|
||||
glm::vec3 chunk = chunks.at(index)->getPosition() /*+ glm::vec3(static_cast<float>(CHUNK_SIZE))*/;
|
||||
glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE)*chunk);
|
||||
Chunk::Chunk *c = chunks.at(index);
|
||||
|
||||
total++;
|
||||
if (!(c->mutex_state.try_lock()))
|
||||
return;
|
||||
|
||||
int a{0};
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (!c->getState(Chunk::CHUNK_STATE_GENERATED))
|
||||
{
|
||||
glm::vec4 vertex = glm::vec4(chunk.x + (float)(i & 1), chunk.y + (float)((i & 2) >> 1), chunk.z + (float)((i & 4) >> 2), 500.0f) * (theCamera.getProjection() * theCamera.getView() * model);
|
||||
vertex = glm::normalize(vertex);
|
||||
|
||||
a += (-vertex.w <= vertex.x && vertex.x <= vertex.w && -vertex.w <= vertex.y && vertex.y <= vertex.w /*&& -vertex.w < vertex.z && vertex.z < vertex.w*/);
|
||||
if (f & 1)
|
||||
to_generate.insert(c);
|
||||
}
|
||||
if (a)
|
||||
else
|
||||
{
|
||||
toGpu++;
|
||||
draw(chunks.at(index), model);
|
||||
if (!c->getState(Chunk::CHUNK_STATE_MESHED))
|
||||
{
|
||||
if (f & 2)
|
||||
to_mesh.insert(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!c->getState(Chunk::CHUNK_STATE_MESH_LOADED))
|
||||
{
|
||||
if (c->vIndex > 0)
|
||||
{
|
||||
|
||||
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||
glBindVertexArray(c->VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, c->VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, c->vertices.size() * sizeof(GLfloat), &(c->vertices[0]), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, c->EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, c->indices.size() * sizeof(GLuint), &(c->indices[0]), GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, c->colorBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, c->colors.size() * sizeof(GLfloat), &(c->colors[0]), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
|
||||
|
||||
// glDisableVertexAttribArray(0);
|
||||
// glDisableVertexAttribArray(1);
|
||||
glBindVertexArray(0);
|
||||
|
||||
c->vIndex = (GLuint)(c->indices.size());
|
||||
|
||||
c->vertices.clear();
|
||||
c->indices.clear();
|
||||
c->colors.clear();
|
||||
}
|
||||
c->setState(Chunk::CHUNK_STATE_MESH_LOADED, true);
|
||||
}
|
||||
|
||||
glm::vec3 chunk = c->getPosition();
|
||||
glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE) * chunk);
|
||||
// chunkmesher::draw(c, model);
|
||||
total++;
|
||||
|
||||
int a{0};
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
glm::vec4 vertex = glm::vec4(chunk.x + (float)(i & 1), chunk.y + (float)((i & 2) >> 1), chunk.z + (float)((i & 4) >> 2), 500.0f) * (theCamera.getProjection() * theCamera.getView() * model);
|
||||
vertex = glm::normalize(vertex);
|
||||
|
||||
a += (-vertex.w <= vertex.x && vertex.x <= vertex.w && -vertex.w <= vertex.y && vertex.y <= vertex.w /*&& -vertex.w < vertex.z && vertex.z < vertex.w*/);
|
||||
}
|
||||
if (a)
|
||||
{
|
||||
toGpu++;
|
||||
chunkmesher::draw(c, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if ((f & 4) == 4)
|
||||
// {
|
||||
// glm::vec3 chunk = c->getPosition();
|
||||
// glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE) * chunk);
|
||||
// // chunkmesher::draw(c, model);
|
||||
// // total++;
|
||||
|
||||
// // int a{0};
|
||||
// // for (int i = 0; i < 8; i++)
|
||||
// // {
|
||||
// // glm::vec4 vertex = glm::vec4(chunk.x + (float)(i & 1), chunk.y + (float)((i & 2) >> 1), chunk.z + (float)((i & 4) >> 2), 500.0f) * (theCamera.getProjection() * theCamera.getView() * model);
|
||||
// // vertex = glm::normalize(vertex);
|
||||
|
||||
// // a += (-vertex.w <= vertex.x && vertex.x <= vertex.w && -vertex.w <= vertex.y && vertex.y <= vertex.w /*&& -vertex.w < vertex.z && vertex.z < vertex.w*/);
|
||||
// // }
|
||||
// // if (a)
|
||||
// // {
|
||||
// // toGpu++;
|
||||
// chunkmesher::draw(c, model);
|
||||
// // }
|
||||
// }
|
||||
c->mutex_state.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,4 +314,4 @@ namespace chunkmanager
|
|||
for (auto &n : chunks)
|
||||
delete n.second;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,11 +8,8 @@
|
|||
#include "spacefilling.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
std::vector<GLfloat> vertices;
|
||||
std::vector<GLfloat> colors;
|
||||
std::vector<GLuint> indices;
|
||||
GLuint vIndex{0};
|
||||
|
||||
namespace chunkmesher{
|
||||
|
||||
void mesh(Chunk::Chunk* chunk)
|
||||
{
|
||||
|
||||
|
@ -37,11 +34,11 @@ void mesh(Chunk::Chunk* chunk)
|
|||
* containing all the quads. In the future, maybe translucent blocks and liquids
|
||||
* will need a separate mesh, but still on a per-chunk basis
|
||||
*/
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
vIndex = 0;
|
||||
chunk->vertices.clear();
|
||||
chunk->indices.clear();
|
||||
chunk->vIndex = 0;
|
||||
|
||||
// if(chunk->getState(Chunk::CHUNK_STATE_EMPTY)) return;
|
||||
if(chunk->getState(Chunk::CHUNK_STATE_EMPTY)) return;
|
||||
|
||||
// convert tree to array since it is easier to work with it
|
||||
int length{0};
|
||||
|
@ -149,7 +146,7 @@ void mesh(Chunk::Chunk* chunk)
|
|||
dv[2] = 0;
|
||||
dv[v] = h;
|
||||
|
||||
quad(glm::vec3(x[0], x[1], x[2]),
|
||||
quad(chunk, glm::vec3(x[0], x[1], x[2]),
|
||||
glm::vec3(x[0] + du[0], x[1] + du[1], x[2] + du[2]),
|
||||
glm::vec3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1],
|
||||
x[2] + du[2] + dv[2]),
|
||||
|
@ -183,46 +180,15 @@ void mesh(Chunk::Chunk* chunk)
|
|||
}
|
||||
}
|
||||
|
||||
if (vIndex > 0)
|
||||
{
|
||||
|
||||
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||
glBindVertexArray(chunk->VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, chunk->VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &(vertices[0]), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, chunk->EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &(indices[0]), GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, chunk->colorBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(GLfloat), &(colors[0]), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
|
||||
|
||||
// glDisableVertexAttribArray(0);
|
||||
// glDisableVertexAttribArray(1);
|
||||
glBindVertexArray(0);
|
||||
|
||||
chunk->vIndex = (GLuint)(indices.size());
|
||||
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
colors.clear();
|
||||
}
|
||||
delete[] blocks;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void draw(Chunk::Chunk* chunk, glm::mat4 model)
|
||||
{
|
||||
|
||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // wireframe mode
|
||||
if(!chunk->getState(Chunk::CHUNK_STATE_EMPTY))
|
||||
if(chunk->getState(Chunk::CHUNK_STATE_MESH_LOADED))
|
||||
{
|
||||
theShader->use();
|
||||
theShader->setMat4("model", model);
|
||||
|
@ -235,44 +201,44 @@ void draw(Chunk::Chunk* chunk, glm::mat4 model)
|
|||
}
|
||||
}
|
||||
|
||||
void quad(glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, glm::vec3 bottomRight, Block block, bool backFace)
|
||||
void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, glm::vec3 bottomRight, Block block, bool backFace)
|
||||
{
|
||||
|
||||
vertices.push_back(bottomLeft.x);
|
||||
vertices.push_back(bottomLeft.y);
|
||||
vertices.push_back(bottomLeft.z);
|
||||
chunk->vertices.push_back(bottomLeft.x);
|
||||
chunk->vertices.push_back(bottomLeft.y);
|
||||
chunk->vertices.push_back(bottomLeft.z);
|
||||
|
||||
vertices.push_back(bottomRight.x);
|
||||
vertices.push_back(bottomRight.y);
|
||||
vertices.push_back(bottomRight.z);
|
||||
chunk->vertices.push_back(bottomRight.x);
|
||||
chunk->vertices.push_back(bottomRight.y);
|
||||
chunk->vertices.push_back(bottomRight.z);
|
||||
|
||||
vertices.push_back(topLeft.x);
|
||||
vertices.push_back(topLeft.y);
|
||||
vertices.push_back(topLeft.z);
|
||||
chunk->vertices.push_back(topLeft.x);
|
||||
chunk->vertices.push_back(topLeft.y);
|
||||
chunk->vertices.push_back(topLeft.z);
|
||||
|
||||
vertices.push_back(topRight.x);
|
||||
vertices.push_back(topRight.y);
|
||||
vertices.push_back(topRight.z);
|
||||
chunk->vertices.push_back(topRight.x);
|
||||
chunk->vertices.push_back(topRight.y);
|
||||
chunk->vertices.push_back(topRight.z);
|
||||
|
||||
if (backFace)
|
||||
{
|
||||
indices.push_back(vIndex + 2);
|
||||
indices.push_back(vIndex);
|
||||
indices.push_back(vIndex + 1);
|
||||
indices.push_back(vIndex + 1);
|
||||
indices.push_back(vIndex + 3);
|
||||
indices.push_back(vIndex + 2);
|
||||
chunk->indices.push_back(chunk->vIndex + 2);
|
||||
chunk->indices.push_back(chunk->vIndex);
|
||||
chunk->indices.push_back(chunk->vIndex + 1);
|
||||
chunk->indices.push_back(chunk->vIndex + 1);
|
||||
chunk->indices.push_back(chunk->vIndex + 3);
|
||||
chunk->indices.push_back(chunk->vIndex + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
indices.push_back(vIndex + 2);
|
||||
indices.push_back(vIndex + 3);
|
||||
indices.push_back(vIndex + 1);
|
||||
indices.push_back(vIndex + 1);
|
||||
indices.push_back(vIndex);
|
||||
indices.push_back(vIndex + 2);
|
||||
chunk->indices.push_back(chunk->vIndex + 2);
|
||||
chunk->indices.push_back(chunk->vIndex + 3);
|
||||
chunk->indices.push_back(chunk->vIndex + 1);
|
||||
chunk->indices.push_back(chunk->vIndex + 1);
|
||||
chunk->indices.push_back(chunk->vIndex);
|
||||
chunk->indices.push_back(chunk->vIndex + 2);
|
||||
}
|
||||
vIndex += 4;
|
||||
chunk->vIndex += 4;
|
||||
|
||||
// ugly switch case
|
||||
GLfloat r, g, b;
|
||||
|
@ -317,8 +283,9 @@ void quad(glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, glm::vec3
|
|||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
colors.push_back(r);
|
||||
colors.push_back(g);
|
||||
colors.push_back(b);
|
||||
chunk->colors.push_back(r);
|
||||
chunk->colors.push_back(g);
|
||||
chunk->colors.push_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "chunkmanager.hpp"
|
||||
#include "main.hpp"
|
||||
|
@ -52,11 +53,12 @@ int main()
|
|||
glfwSetCursorPosCallback(window, mouse_callback);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE); //GL_BACK GL_CCW by default
|
||||
|
||||
|
||||
std::cout << "Using GPU: " << glGetString(GL_VENDOR) << " " << glGetString(GL_RENDERER) << "\n";
|
||||
|
||||
SpaceFilling::initLUT();
|
||||
chunkmanager::init();
|
||||
std::thread genThread = chunkmanager::initGenThread();
|
||||
std::thread meshThread = chunkmanager::initMeshThread();
|
||||
|
||||
theShader = new Shader{"shaders/shader.vs", "shaders/shader.fs"};
|
||||
|
||||
|
@ -93,6 +95,9 @@ int main()
|
|||
}
|
||||
|
||||
delete theShader;
|
||||
|
||||
genThread.join();
|
||||
meshThread.join();
|
||||
chunkmanager::destroy();
|
||||
|
||||
glfwTerminate();
|
||||
|
|
Loading…
Reference in New Issue