Browse Source

some reformatting, started superchunkmesh

testing
Michael Porter 2 years ago
parent
commit
0f61038ef1
13 changed files with 619 additions and 2590 deletions
  1. 1
    0
      .dir-local.el
  2. BIN
      1504168289.png
  3. BIN
      1504168338.png
  4. 0
    1907
      comp.txt
  5. 33
    0
      include/graphics/superchunkmesh.h
  6. 0
    0
      include/stb_image.c
  7. 0
    1
      include/world.h
  8. 0
    119
      src/'
  9. 221
    219
      src/graphics/chunkmesh.cpp
  10. 16
    0
      src/graphics/superchunkmesh.cpp
  11. 12
    11
      src/main.cpp
  12. 164
    164
      src/scenes/testscene.cpp
  13. 172
    169
      src/world.cpp

+ 1
- 0
.dir-local.el View File

@@ -0,0 +1 @@
((c-mode . ((mode . c++))))

BIN
1504168289.png View File


BIN
1504168338.png View File


+ 0
- 1907
comp.txt
File diff suppressed because it is too large
View File


+ 33
- 0
include/graphics/superchunkmesh.h View File

@@ -0,0 +1,33 @@
// A chunk mesh for batching together other chunk meshes to reduce drawcalls
// chunks OR the supermesh but not both.
// To be used to group together chunks (i.e. 8^3 blocks of chunks)
// If rebuild is started when it's already rebuilding in another thread,it will
// restart rebuilding in the original thread.

#pragma once

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

namespace vtk {

class ChunkMesh;

class SuperChunkMesh {
public:
SuperChunkMesh();
bool addMesh(ChunkMesh* mesh);
void rebuild();
protected:
typedef struct {
unsigned count;
unsigned instanceCount;
unsigned first;
unsigned baseInstance;
} DrawArraysIndirectCommand;
std::vector<ChunkMesh*> mChunkMeshes;
std::vector<glm::mat4> mModelMats;
};

}

src/stb_image.c → include/stb_image.c View File


+ 0
- 1
include/world.h View File

@@ -59,7 +59,6 @@ public:
std::unordered_map<glm::ivec3, ChunkMesh, ivec3Hash> mChunkMeshes;
std::vector<iPos> chunkUpdateQueue;
std::deque<glm::ivec3> mChunkUpdateQueue;
std::vector<glm::ivec3> mChunkGeometryUpdateQueue;

unsigned chunkSize;
float voxelSize;

+ 0
- 119
src/' View File

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

#include "game.h"
#include "loadShader.h"
#include "graphics/camera.h"
#include "graphics/glstate.h"
#include "scene.h"

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

#include <chrono>

namespace vtk {

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

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

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

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

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

window.create();

glewExperimental = GL_TRUE;
glewInit();

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

running = false;
gls::setTracking(true);
}

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

void Game::loop() {


auto lastFrameTime = std::chrono::steady_clock::now();

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

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

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

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

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

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

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

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

};

+ 221
- 219
src/graphics/chunkmesh.cpp View File

@@ -11,224 +11,226 @@


namespace vtk {
ChunkMesh::ChunkMesh(World& world, glm::ivec3 chunkPos) :
mLinkedWorld(world),
mLinkedChunkPos(chunkPos),
mLocked(false)
{
glGenBuffers(1, &mGeometryTexVBO);
glGenBuffers(1, &mLightVBO);

glGenVertexArrays(1, &mVAO);

glBindVertexArray(mVAO);

glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);


//vertices
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), NULL);
glEnableVertexAttribArray(0);

//tex uv coords
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float)));
glEnableVertexAttribArray(1);
}

void ChunkMesh::rebuildChunkGeometry() {
if (mLocked) return;
mLocked = true;
//get the chunk from position
auto chunk = mLinkedWorld.getChunk(mLinkedChunkPos);

//temporary until I finish mesh providers
float texUV [] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
1.0f, 1.0f
};
float topModel [] = {
//x y z
0.0f, 1.0f, 0.0f, //tl
1.0f, 1.0f, 0.0f, //tr
0.0f, 1.0f, 1.0f, //bl
1.0f, 1.0f, 1.0f, //br
0.0f, 1.0f, 1.0f, //bl
1.0f, 1.0f, 0.0f //tr
};
float bottomModel [] = {
//x y z u v
0.0f, 0.0f, 1.0f, //tl
1.0f, 0.0f, 1.0f, //tr
0.0f, 0.0f, 0.0f, //bl
1.0f, 0.0f, 0.0f, //br
0.0f, 0.0f, 0.0f, //bl
1.0f, 0.0f, 1.0f //tr
};
float northModel [] = {
//x y z u v
0.0f, 1.0f, 1.0f, //tl
1.0f, 1.0f, 1.0f, //tr
0.0f, 0.0f, 1.0f, //bl
1.0f, 0.0f, 1.0f, //br
0.0f, 0.0f, 1.0f, //bl
1.0f, 1.0f, 1.0f //tr
};
float southModel [] = {
//x y z u v
1.0f, 1.0f, 0.0f, //tl
0.0f, 1.0f, 0.0f, //tr
1.0f, 0.0f, 0.0f, //bl
0.0f, 0.0f, 0.0f, //br
1.0f, 0.0f, 0.0f, //bl
0.0f, 1.0f, 0.0f //tr
};
float eastModel [] = {
//x y z u v
1.0f, 1.0f, 1.0f, //tl
1.0f, 1.0f, 0.0f, //tr
1.0f, 0.0f, 1.0f, //bl
1.0f, 0.0f, 0.0f, //br
1.0f, 0.0f, 1.0f, //bl
1.0f, 1.0f, 0.0f //tr
};
float westModel [] = {
//x y z u v
0.0f, 1.0f, 0.0f, //tl
0.0f, 1.0f, 1.0f, //tr
0.0f, 0.0f, 0.0f, //bl
0.0f, 0.0f, 1.0f, //br
0.0f, 0.0f, 0.0f, //bl
0.0f, 1.0f, 1.0f //tr
};

// geometry format: x,y,z,u,v,i
geometry.clear();
mFaceCount = 0;
int chunkSize = 16; // TODO: make this not hardcoded

for (int i = 0; i < chunkSize; ++i) {
for (int j = 0; j < chunkSize; ++j) {
for (int k = 0; k < chunkSize; ++k) {
//for each voxel in the chunk...
// TODO: move this code into a mesh provider system

//top
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j + 1, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(topModel[(l * 3)] + (float)i);
geometry.push_back(topModel[(l * 3) + 1] + (float)j);
geometry.push_back(topModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//bottom
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j - 1, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(bottomModel[(l * 3)] + (float)i);
geometry.push_back(bottomModel[(l * 3) + 1] + (float)j);
geometry.push_back(bottomModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//north
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j, k + 1)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(northModel[(l * 3)] + (float)i);
geometry.push_back(northModel[(l * 3) + 1] + (float)j);
geometry.push_back(northModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}
//south
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j, k - 1)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(southModel[(l * 3)] + (float)i);
geometry.push_back(southModel[(l * 3) + 1] + (float)j);
geometry.push_back(southModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}
//east
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i + 1, j, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(eastModel[(l * 3)] + (float)i);
geometry.push_back(eastModel[(l * 3) + 1] + (float)j);
geometry.push_back(eastModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//west
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i - 1, j, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(westModel[(l * 3)] + (float)i);
geometry.push_back(westModel[(l * 3) + 1] + (float)j);
geometry.push_back(westModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

ChunkMesh::ChunkMesh(World& world, glm::ivec3 chunkPos) :
mLinkedWorld(world),
mLinkedChunkPos(chunkPos),
mLocked(false)
{
glGenBuffers(1, &mGeometryTexVBO);
glGenBuffers(1, &mLightVBO);

glGenVertexArrays(1, &mVAO);

glBindVertexArray(mVAO);

glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);


//vertices
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), NULL);
glEnableVertexAttribArray(0);

//tex uv coords
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float)));
glEnableVertexAttribArray(1);
}

void ChunkMesh::rebuildChunkGeometry() {
if (mLocked) return;
mLocked = true;
//get the chunk from position
auto chunk = mLinkedWorld.getChunk(mLinkedChunkPos);

//temporary until I finish mesh providers
float texUV [] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
1.0f, 1.0f
};
float topModel [] = {
//x y z
0.0f, 1.0f, 0.0f, //tl
1.0f, 1.0f, 0.0f, //tr
0.0f, 1.0f, 1.0f, //bl
1.0f, 1.0f, 1.0f, //br
0.0f, 1.0f, 1.0f, //bl
1.0f, 1.0f, 0.0f //tr
};
float bottomModel [] = {
//x y z u v
0.0f, 0.0f, 1.0f, //tl
1.0f, 0.0f, 1.0f, //tr
0.0f, 0.0f, 0.0f, //bl
1.0f, 0.0f, 0.0f, //br
0.0f, 0.0f, 0.0f, //bl
1.0f, 0.0f, 1.0f //tr
};
float northModel [] = {
//x y z u v
0.0f, 1.0f, 1.0f, //tl
1.0f, 1.0f, 1.0f, //tr
0.0f, 0.0f, 1.0f, //bl
1.0f, 0.0f, 1.0f, //br
0.0f, 0.0f, 1.0f, //bl
1.0f, 1.0f, 1.0f //tr
};
float southModel [] = {
//x y z u v
1.0f, 1.0f, 0.0f, //tl
0.0f, 1.0f, 0.0f, //tr
1.0f, 0.0f, 0.0f, //bl
0.0f, 0.0f, 0.0f, //br
1.0f, 0.0f, 0.0f, //bl
0.0f, 1.0f, 0.0f //tr
};
float eastModel [] = {
//x y z u v
1.0f, 1.0f, 1.0f, //tl
1.0f, 1.0f, 0.0f, //tr
1.0f, 0.0f, 1.0f, //bl
1.0f, 0.0f, 0.0f, //br
1.0f, 0.0f, 1.0f, //bl
1.0f, 1.0f, 0.0f //tr
};
float westModel [] = {
//x y z u v
0.0f, 1.0f, 0.0f, //tl
0.0f, 1.0f, 1.0f, //tr
0.0f, 0.0f, 0.0f, //bl
0.0f, 0.0f, 1.0f, //br
0.0f, 0.0f, 0.0f, //bl
0.0f, 1.0f, 1.0f //tr
};

// geometry format: x,y,z,u,v,i
geometry.clear();
mFaceCount = 0;
int chunkSize = 16; // TODO: make this not hardcoded

for (int i = 0; i < chunkSize; ++i) {
for (int j = 0; j < chunkSize; ++j) {
for (int k = 0; k < chunkSize; ++k) {
//for each voxel in the chunk...
// TODO: move this code into a mesh provider system

//top
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j + 1, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(topModel[(l * 3)] + (float)i);
geometry.push_back(topModel[(l * 3) + 1] + (float)j);
geometry.push_back(topModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//bottom
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j - 1, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(bottomModel[(l * 3)] + (float)i);
geometry.push_back(bottomModel[(l * 3) + 1] + (float)j);
geometry.push_back(bottomModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//north
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j, k + 1)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(northModel[(l * 3)] + (float)i);
geometry.push_back(northModel[(l * 3) + 1] + (float)j);
geometry.push_back(northModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}
//south
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i, j, k - 1)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(southModel[(l * 3)] + (float)i);
geometry.push_back(southModel[(l * 3) + 1] + (float)j);
geometry.push_back(southModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}
//east
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i + 1, j, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(eastModel[(l * 3)] + (float)i);
geometry.push_back(eastModel[(l * 3) + 1] + (float)j);
geometry.push_back(eastModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}

//west
if (chunk->isVoxelSolid(i,j,k)) { //check that it's solid
if (!chunk->isVoxelSolid(i - 1, j, k)) {
++mFaceCount;
for (int l = 0; l < 6; ++l) {
geometry.push_back(westModel[(l * 3)] + (float)i);
geometry.push_back(westModel[(l * 3) + 1] + (float)j);
geometry.push_back(westModel[(l * 3) + 2] + (float)k);
geometry.push_back(texUV[l*2]);
geometry.push_back(texUV[(l*2)+1]);
geometry.push_back(mLinkedWorld.voxelInfo.getTexIndexFromID(2, Face3D::TOP));
}
}
}
}
}
}
}
}

mUpdated = true;
mLocked = false;
}

void ChunkMesh::rebuildChunkLighting() {
//this doesn't do anything yet
}

void ChunkMesh::draw() {
updateGeometry();
glBindVertexArray(mVAO);
glDrawArrays(GL_TRIANGLES, 0, mGeometryFaceCount * 6);
}

bool ChunkMesh::updateGeometry() {
if (mUpdated) {
mUpdated = false;
glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * geometry.size(), geometry.data(), GL_STATIC_DRAW);
mGeometryFaceCount = mFaceCount;
return true;
}
return false;
}

mUpdated = true;
mLocked = false;
}

void ChunkMesh::rebuildChunkLighting() {
//this doesn't do anything yet
}

void ChunkMesh::draw() {
updateGeometry();
glBindVertexArray(mVAO);
glDrawArrays(GL_TRIANGLES, 0, mGeometryFaceCount * 6);
}

bool ChunkMesh::updateGeometry() {
if (mUpdated) {
mUpdated = false;
glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * geometry.size(), geometry.data(), GL_STATIC_DRAW);
mGeometryFaceCount = mFaceCount;
return true;
}
return false;
}

} //namespace vtk

+ 16
- 0
src/graphics/superchunkmesh.cpp View File

@@ -0,0 +1,16 @@
#include "graphics/superchunkmesh.h"

namespace vtk {

SuperChunkMesh::SuperChunkMesh() {

}
bool SuperChunkMesh::addMesh(ChunkMesh* mesh) {

return true;
}

}
longFunctionThatDoesStuff(objectWithLongName.x,
objectWithLongName.y,
objectWithLongName.z);

+ 12
- 11
src/main.cpp View File

@@ -15,18 +15,19 @@ int main (int argc, char *argv[])
vtk::LoggerSetup lSetup;
lSetup.setup();
spdlog::get("general")->info("Starting Voxeltronik Engine...");
spdlog::get("general");

auto conf = new Config;
conf->loadConfigFromFile("res/config.conf");
conf->addArgumentRule("-w", "graphics.res.x");
conf->addArgumentRule("-h", "graphics.res.y");
conf->loadConfigFromArguments(argc, argv);
auto conf = new Config;
conf->loadConfigFromFile("res/config.conf");
conf->addArgumentRule("-w", "graphics.res.x");
conf->addArgumentRule("-h", "graphics.res.y");
conf->loadConfigFromArguments(argc, argv);

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

return 0;
return 0;
}

+ 164
- 164
src/scenes/testscene.cpp View File

@@ -3,15 +3,15 @@
*
* Filename: testscene.cpp
*
* Description:
* Description:
*
* Version: 1.0
* Created: 03/24/2014 11:06:32 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
@@ -40,112 +40,112 @@ namespace vtk {

void TestScene::init() {

Tileset tiles;
tiles.buildTexture();
tiles.updateTextureAt(0, "res/stone.png");
tiles.updateTextureAt(1, "res/dirt.png");
tiles.updateTextureAt(2, "res/test.png");
Tileset tiles;
tiles.buildTexture();
tiles.updateTextureAt(0, "res/stone.png");
tiles.updateTextureAt(1, "res/dirt.png");
tiles.updateTextureAt(2, "res/test.png");

//define vertices
float vertices[] {
-0.01f, 0.01f, 0.0f,
0.01f, -0.01f, 0.0f,
-0.01f, -0.01f, 0.0f,
-0.01f, 0.01f, 0.0f,
0.01f, 0.01f, 0.0f,
0.01f, -0.01f, 0.0f
};
//define vertices
float vertices[] {
-0.01f, 0.01f, 0.0f,
0.01f, -0.01f, 0.0f,
-0.01f, -0.01f, 0.0f,
-0.01f, 0.01f, 0.0f,
0.01f, 0.01f, 0.0f,
0.01f, -0.01f, 0.0f
};


glGenBuffers(1, &vertVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &vertVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vertVBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vertVBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(0);

//shaders
//shaders
mCursorShader.loadShaderFiles("res/shaders/test.vert.glsl", "res/shaders/test.frag.glsl");
cursorShaders = LoadShaders("res/shaders/test.vert.glsl", "res/shaders/test.frag.glsl");
shaders = LoadShaders("res/shaders/voxelvert.vert.glsl", "res/shaders/voxelfrag.frag.glsl");
cursorShaders = LoadShaders("res/shaders/test.vert.glsl", "res/shaders/test.frag.glsl");
shaders = LoadShaders("res/shaders/voxelvert.vert.glsl", "res/shaders/voxelfrag.frag.glsl");

glUseProgram(shaders);
glUseProgram(shaders);

camera.setPosition(glm::vec3(0.0f, 5.0f, 5.0f));
camera.setAspectRatio(linkedGame->window.getAspect());
camera.setPosition(glm::vec3(0.0f, 5.0f, 5.0f));
camera.setAspectRatio(linkedGame->window.getAspect());

viewMatUni = glGetUniformLocation(shaders, "view");
projMatUni = glGetUniformLocation(shaders, "proj");
modelMatUni = glGetUniformLocation(shaders, "model");
world.modelMatUni = modelMatUni;
viewMatUni = glGetUniformLocation(shaders, "view");
projMatUni = glGetUniformLocation(shaders, "proj");
modelMatUni = glGetUniformLocation(shaders, "model");
world.modelMatUni = modelMatUni;
mSkyboxTask = new RenderTask(mSkybox, camera, linkedGame->window);
glUniformMatrix4fv(viewMatUni, 1, GL_FALSE, glm::value_ptr(camera.getViewMatrix()));
glUniformMatrix4fv(projMatUni, 1, GL_FALSE, glm::value_ptr(linkedGame->window.getProjectionMatrix()));
//nanovg
vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
nvgCreateFont(vg, "mono", "res/fonts/DejaVuSansMono.ttf");
SDL_SetRelativeMouseMode(SDL_TRUE);
sensitivity = linkedGame->getConfig()->getValue<float>("controls.mouse.sensitivity", 5.0f);
//get config
Config* conf = linkedGame->getConfig();
//add actions to handler
handler.setAction("Move Forward", conf->getValue<std::string>("controls.bindings.movement.forward", "W" ));
handler.setAction("Move Backward", conf->getValue<std::string>("controls.bindings.movement.backward", "S" ));
handler.setAction("Move Left", conf->getValue<std::string>("controls.bindings.movement.left", "A" ));
handler.setAction("Move Right", conf->getValue<std::string>("controls.bindings.movement.right", "D" ));
handler.setAction("Move Up", conf->getValue<std::string>("controls.bindings.movement.up", "Space" ));
handler.setAction("Move Down", conf->getValue<std::string>("controls.bindings.movement.down", "Left Ctrl"));
handler.setAction("Place Voxel", conf->getValue<std::string>("controls.bindings.action.placevoxel", "Mouse Left"));
handler.setAction("Delete Voxel", conf->getValue<std::string>("controls.bindings.action.delvoxel", "Mouse Right"));
handler.setAction("Select Type 1", conf->getValue<std::string>("controls.bindings.typesel.type1", "1" ));
handler.setAction("Select Type 2", conf->getValue<std::string>("controls.bindings.typesel.type2", "2" ));
//set signals for handler
handler.getEventSignal(SDL_QUIT ).connect<Game , &Game::stop >(linkedGame);
handler.getEventSignal(SDL_MOUSEMOTION).connect<TestScene, &TestScene::look>(this);
world.voxelInfo.setTextureData(1, Face3D::RIGHT, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::LEFT, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::TOP, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::BOTTOM, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::FRONT, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::BACK, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(2, Face3D::RIGHT, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::LEFT, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::TOP, Orientation2D::UP, 2.0f);
world.voxelInfo.setTextureData(2, Face3D::BOTTOM, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::FRONT, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::BACK, Orientation2D::UP, 1.0f);
//world.voxelInfo.setTransparent(1, false);
//world.voxelInfo.setTransparent(2, false);
std::cout << std::endl;
int chunkCount = 1;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
for (int k = 0; k < 8; k++) {
std::cout << "\rGenerating chunks (" << chunkCount << "/" << 8*8*8 << ")" << std::flush;
world.generateChunk(i,j,k);
chunkCount++;
}
}
}
//world.forceGlobalGeometryUpdate();
voxelType = 1;
glUniformMatrix4fv(viewMatUni, 1, GL_FALSE, glm::value_ptr(camera.getViewMatrix()));
glUniformMatrix4fv(projMatUni, 1, GL_FALSE, glm::value_ptr(linkedGame->window.getProjectionMatrix()));
//nanovg
vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
nvgCreateFont(vg, "mono", "res/fonts/DejaVuSansMono.ttf");
SDL_SetRelativeMouseMode(SDL_TRUE);
sensitivity = linkedGame->getConfig()->getValue<float>("controls.mouse.sensitivity", 5.0f);
//get config
Config* conf = linkedGame->getConfig();
//add actions to handler
handler.setAction("Move Forward", conf->getValue<std::string>("controls.bindings.movement.forward", "W" ));
handler.setAction("Move Backward", conf->getValue<std::string>("controls.bindings.movement.backward", "S" ));
handler.setAction("Move Left", conf->getValue<std::string>("controls.bindings.movement.left", "A" ));
handler.setAction("Move Right", conf->getValue<std::string>("controls.bindings.movement.right", "D" ));
handler.setAction("Move Up", conf->getValue<std::string>("controls.bindings.movement.up", "Space" ));
handler.setAction("Move Down", conf->getValue<std::string>("controls.bindings.movement.down", "Left Ctrl"));
handler.setAction("Place Voxel", conf->getValue<std::string>("controls.bindings.action.placevoxel", "Mouse Left"));
handler.setAction("Delete Voxel", conf->getValue<std::string>("controls.bindings.action.delvoxel", "Mouse Right"));
handler.setAction("Select Type 1", conf->getValue<std::string>("controls.bindings.typesel.type1", "1" ));
handler.setAction("Select Type 2", conf->getValue<std::string>("controls.bindings.typesel.type2", "2" ));
//set signals for handler
handler.getEventSignal(SDL_QUIT ).connect<Game , &Game::stop >(linkedGame);
handler.getEventSignal(SDL_MOUSEMOTION).connect<TestScene, &TestScene::look>(this);
world.voxelInfo.setTextureData(1, Face3D::RIGHT, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::LEFT, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::TOP, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::BOTTOM, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::FRONT, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(1, Face3D::BACK, Orientation2D::UP, 0.0f);
world.voxelInfo.setTextureData(2, Face3D::RIGHT, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::LEFT, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::TOP, Orientation2D::UP, 2.0f);
world.voxelInfo.setTextureData(2, Face3D::BOTTOM, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::FRONT, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::BACK, Orientation2D::UP, 1.0f);
//world.voxelInfo.setTransparent(1, false);
//world.voxelInfo.setTransparent(2, false);
std::cout << std::endl;
int chunkCount = 1;
for (int i = 0; i < 64; i++) {
for (int j = 0; j < 8; j++) {
for (int k = 0; k < 64; k++) {
std::cout << "\rGenerating chunks (" << chunkCount << "/" << 8*8*8 << ")" << std::flush;
world.generateChunk(i,j,k);
chunkCount++;
}
}
}
//world.forceGlobalGeometryUpdate();
voxelType = 1;
}

void TestScene::reInit() {
@@ -153,78 +153,78 @@ void TestScene::reInit() {
}

void TestScene::update(const float& dTime) {
this->dTime = dTime;
camera.update(dTime);
handler.update();
world.update();
mFPS = 1.0f/dTime;
if (handler.isActionDown("Move Forward" )) camera.moveRelative(glm::vec3 (0.0f, 0.0f, 1.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Backward")) camera.moveRelative(glm::vec3( 0.0f, 0.0f, -1.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Left" )) camera.moveRelative(glm::vec3(-1.0f, 0.0f, 0.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Right" )) camera.moveRelative(glm::vec3( 1.0f, 0.0f, 0.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Up" )) camera.move(glm::vec3( 0.0f, 1.0f, 0.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Down" )) camera.move(glm::vec3( 0.0f, -1.0f, 0.0f) * dTime * 4.0f);
if (handler.isActionDown("Select Type 1")) voxelType = 1;
if (handler.isActionDown("Select Type 2")) voxelType = 2;
//place voxel testing
if ((handler.isActionDown("Place Voxel") || handler.isActionDown("Delete Voxel")) && !placeVoxel) {
placeVoxel = true;
//perform a raycast
glm::vec3 hitPos;
glm::vec3 hitNormal;
bool success;
world.voxelMath.rayCast(hitPos, hitNormal, success, camera.getPosition(), camera.getAngleVector(), 10);
if (success) {
std::cout << "Hit voxel at: " << hitPos.x << ", " << hitPos.y << ", " << hitPos.z << std::endl;
if (handler.isActionDown("Place Voxel")) {
world.setVoxelType((int)(hitPos.x + hitNormal.x), (int)(hitPos.y + hitNormal.y), (int)(hitPos.z + hitNormal.z), voxelType, true);
} else {
world.setVoxelType((int)(hitPos.x), (int)(hitPos.y), (int)(hitPos.z), 0, true);
}
}
} else if (!(handler.isActionDown("Place Voxel") || handler.isActionDown("Delete Voxel")) && placeVoxel) {
placeVoxel = false;
}
//camera.moveRelative(camMovement * dTime);
this->dTime = dTime;
camera.update(dTime);
handler.update();
world.update();
mFPS = 1.0f/dTime;
if (handler.isActionDown("Move Forward" )) camera.moveRelative(glm::vec3 (0.0f, 0.0f, 1.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Backward")) camera.moveRelative(glm::vec3( 0.0f, 0.0f, -1.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Left" )) camera.moveRelative(glm::vec3(-1.0f, 0.0f, 0.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Right" )) camera.moveRelative(glm::vec3( 1.0f, 0.0f, 0.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Up" )) camera.move(glm::vec3( 0.0f, 1.0f, 0.0f) * dTime * 4.0f);
if (handler.isActionDown("Move Down" )) camera.move(glm::vec3( 0.0f, -1.0f, 0.0f) * dTime * 4.0f);
if (handler.isActionDown("Select Type 1")) voxelType = 1;
if (handler.isActionDown("Select Type 2")) voxelType = 2;
//place voxel testing
if ((handler.isActionDown("Place Voxel") || handler.isActionDown("Delete Voxel")) && !placeVoxel) {
placeVoxel = true;
//perform a raycast
glm::vec3 hitPos;
glm::vec3 hitNormal;
bool success;
world.voxelMath.rayCast(hitPos, hitNormal, success, camera.getPosition(), camera.getAngleVector(), 10);
if (success) {
std::cout << "Hit voxel at: " << hitPos.x << ", " << hitPos.y << ", " << hitPos.z << std::endl;
if (handler.isActionDown("Place Voxel")) {
world.setVoxelType((int)(hitPos.x + hitNormal.x), (int)(hitPos.y + hitNormal.y), (int)(hitPos.z + hitNormal.z), voxelType, true);
} else {
world.setVoxelType((int)(hitPos.x), (int)(hitPos.y), (int)(hitPos.z), 0, true);
}
}
} else if (!(handler.isActionDown("Place Voxel") || handler.isActionDown("Delete Voxel")) && placeVoxel) {
placeVoxel = false;
}
//camera.moveRelative(camMovement * dTime);
}

void TestScene::draw() {
mSkyboxTask->draw();
gls::setShader(shaders);
glUniformMatrix4fv(viewMatUni, 1, GL_FALSE, glm::value_ptr(camera.getViewMatrix()));
world.draw();
glDisable(GL_DEPTH_TEST);
mCursorShader.activate();
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
nvgBeginFrame(vg, 1920, 1080, 1);
nvgFontSize(vg, 14.0f);
nvgFontFace(vg, "mono");
nvgFillColor(vg, nvgRGBA(0, 0, 0, 190));
std::string fpsString = std::to_string(mFPS);
nvgText(vg, 5, 19, fpsString.data(), NULL);
nvgEndFrame(vg);
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
mSkyboxTask->draw();
gls::setShader(shaders);
glUniformMatrix4fv(viewMatUni, 1, GL_FALSE, glm::value_ptr(camera.getViewMatrix()));
world.draw();
glDisable(GL_DEPTH_TEST);
mCursorShader.activate();
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
nvgBeginFrame(vg, 1920, 1080, 1);
nvgFontSize(vg, 14.0f);
nvgFontFace(vg, "mono");
nvgFillColor(vg, nvgRGBA(0, 0, 0, 190));
std::string fpsString = std::to_string(mFPS);
nvgText(vg, 5, 19, fpsString.data(), NULL);
nvgEndFrame(vg);
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
}

void TestScene::look() {
int x, y; //mouse change
SDL_GetRelativeMouseState(&x, &y);
camera.rotate((float)x * sensitivity * 0.001f, (float)y * sensitivity * 0.001f);
//camera.rotate((float)x, (float)y);
int x, y; //mouse change
SDL_GetRelativeMouseState(&x, &y);
camera.rotate((float)x * sensitivity * 0.001f, (float)y * sensitivity * 0.001f);
//camera.rotate((float)x, (float)y);
}

}

+ 172
- 169
src/world.cpp View File

@@ -3,15 +3,15 @@
*
* Filename: world.cpp
*
* Description:
* Description:
*
* Version: 1.0
* Created: 04/03/2014 09:53:00 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
@@ -32,208 +32,211 @@

namespace vtk {

{
asd;
}

World::World() {
chunkSize = 16;
voxelSize = 1.0f;
voxelInfo.linkedWorld = this;
voxelMath.linkedWorld = this;
rebuildThreadActive = false;
chunkSize = 16;
voxelSize = 1.0f;
voxelInfo.linkedWorld = this;
voxelMath.linkedWorld = this;
rebuildThreadActive = false;
}

bool World::isVoxelSolid(const int& x, const int& y, const int& z) {
auto chunkPos = glm::ivec3(floor((float)x / (float)chunkSize),
floor((float)y / (float)chunkSize),
floor((float)z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) { //block is in nonexistant chunk
return true;
}
int relPosX = x - chunkPos.x * chunkSize;
int relPosY = y - chunkPos.y * chunkSize;
int relPosZ = z - chunkPos.z * chunkSize;
return mChunks[chunkPos]->isVoxelSolid(relPosX, relPosY, relPosZ);
auto chunkPos = glm::ivec3(floor((float)x / (float)chunkSize),
floor((float)y / (float)chunkSize),
floor((float)z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) { //block is in nonexistant chunk
return true;
}
int relPosX = x - chunkPos.x * chunkSize;
int relPosY = y - chunkPos.y * chunkSize;
int relPosZ = z - chunkPos.z * chunkSize;
return mChunks[chunkPos]->isVoxelSolid(relPosX, relPosY, relPosZ);
}

bool World::setVoxelType(const int& x, const int& y, const int& z, const unsigned& type, const bool& updateChunk) {
auto chunkPos = glm::ivec3(floor((float)x / (float)chunkSize), floor((float)y / (float)chunkSize), floor((float)z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) { //block is in nonexistant chunk
return false;
}
int relPosX = x - chunkPos.x * chunkSize;
int relPosY = y - chunkPos.y * chunkSize;
int relPosZ = z - chunkPos.z * chunkSize;
mChunks[chunkPos]->setVoxelType(relPosX, relPosY, relPosZ, type);
if (updateChunk) queueChunkUpdate(chunkPos, true);
return true;
auto chunkPos = glm::ivec3(floor((float)x / (float)chunkSize), floor((float)y / (float)chunkSize), floor((float)z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) { //block is in nonexistant chunk
return false;
}
int relPosX = x - chunkPos.x * chunkSize;
int relPosY = y - chunkPos.y * chunkSize;
int relPosZ = z - chunkPos.z * chunkSize;
mChunks[chunkPos]->setVoxelType(relPosX, relPosY, relPosZ, type);
if (updateChunk) queueChunkUpdate(chunkPos, true);
return true;
}

unsigned World::getVoxelType(const glm::ivec3& pos) {
auto chunkPos = glm::ivec3(floor((float)pos.x / (float)chunkSize),
floor((float)pos.y / (float)chunkSize),
floor((float)pos.z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) {
return 0;
}
int relPosX = pos.x - chunkPos.x * chunkSize;
int relPosY = pos.y - chunkPos.y * chunkSize;
int relPosZ = pos.z - chunkPos.z * chunkSize;
return mChunks[chunkPos]->getVoxelType((unsigned)relPosX, (unsigned)relPosY, (unsigned)relPosZ);
auto chunkPos = glm::ivec3(floor((float)pos.x / (float)chunkSize),
floor((float)pos.y / (float)chunkSize),
floor((float)pos.z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) {
return 0;
}
int relPosX = pos.x - chunkPos.x * chunkSize;
int relPosY = pos.y - chunkPos.y * chunkSize;
int relPosZ = pos.z - chunkPos.z * chunkSize;
return mChunks[chunkPos]->getVoxelType((unsigned)relPosX, (unsigned)relPosY, (unsigned)relPosZ);
}


bool World::makeChunk(const int& x, const int& y, const int& z) {
auto pos = glm::ivec3(x, y, z);
auto pos = glm::ivec3(x, y, z);

if (mChunks.find(pos) != mChunks.end()) { //chunk already exists
return false;
}

if (mChunks.find(pos) != mChunks.end()) { //chunk already exists
return false;
}
auto newChunk = new Chunk(*this);
mChunks[pos] = newChunk;

auto newChunk = new Chunk(*this);
mChunks[pos] = newChunk;
newChunk->setPos(pos);

newChunk->setPos(pos);
mChunkMeshes.emplace(pos, ChunkMesh(*this, pos));

mChunkMeshes.emplace(pos, ChunkMesh(*this, pos));
return true;
return true;
}

bool World::generateChunk(const int& x, const int& y, const int& z) {
bool chunkMade = makeChunk(x,y,z);
if (chunkMade) {
terrain.generateChunk(getChunk(glm::ivec3(x,y,z)));
//queue this chunk for geometry update
queueChunkUpdate(x,y,z);
//queue the neighboring 6 chunks. the queue functions throws them out
// if they don't exist
queueChunkUpdate(x+1,y,z);
queueChunkUpdate(x-1,y,z);
queueChunkUpdate(x,y+1,z);
queueChunkUpdate(x,y-1,z);
queueChunkUpdate(x,y,z+1);
queueChunkUpdate(x,y,z-1);
}
return chunkMade;
bool chunkMade = makeChunk(x,y,z);
if (chunkMade) {
terrain.generateChunk(getChunk(glm::ivec3(x,y,z)));
//queue this chunk for geometry update
queueChunkUpdate(x,y,z);
//queue the neighboring 6 chunks. the queue functions throws them out
// if they don't exist
queueChunkUpdate(x+1,y,z);
queueChunkUpdate(x-1,y,z);
queueChunkUpdate(x,y+1,z);
queueChunkUpdate(x,y-1,z);
queueChunkUpdate(x,y,z+1);
queueChunkUpdate(x,y,z-1);
}
return chunkMade;
}


Chunk* World::getChunk(const glm::ivec3& pos) {
auto chunk = mChunks.find(pos)->second;
if (chunk) return chunk;
else return nullptr;
}
void World::queueChunkUpdate(const int& x, const int& y, const int& z, const bool& back) {
queueChunkUpdate(glm::ivec3(x,y,z));
Chunk* World::getChunk(const glm::ivec3& pos) {
auto chunk = mChunks.find(pos)->second;
if (chunk) return chunk;
else return nullptr;
}
void World::queueChunkUpdate(const int& x, const int& y, const int& z, const bool& back) {
queueChunkUpdate(glm::ivec3(x,y,z));
}

void World::queueChunkUpdate(const glm::ivec3& pos, const bool& back) {
if (mChunks.find(pos) == mChunks.end()) return; //chunk doesn't exist
for (auto& i : mChunkUpdateQueue) {
if (i == pos) return; //chunk is already in queue, we don't need to update multiple times
}
if (back) {
mChunkUpdateQueue.push_back(pos);
} else {
mChunkUpdateQueue.push_front(pos);
}
void World::queueChunkUpdate(const glm::ivec3& pos, const bool& back) {
if (mChunks.find(pos) == mChunks.end()) return; //chunk doesn't exist
for (auto& i : mChunkUpdateQueue) {
if (i == pos) return; //chunk is already in queue, we don't need to update multiple times
}
if (back) {
mChunkUpdateQueue.push_back(pos);
} else {
mChunkUpdateQueue.push_front(pos);
}
}

void World::draw() {
/*
for (auto& i : chunks) {
glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3(
(float)i.second->getPos().x * 16,
(float)i.second->getPos().y * 16,
(float)i.second->getPos().z * 16
));
glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
i.second->renderer.drawChunk();
}
*/
for (auto& i : mChunkMeshes) {
glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3(
(float)i.first.x * 16,
(float)i.first.y * 16,
(float)i.first.z * 16
));
glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
i.second.draw();
}
/*
for (auto& i : chunks) {
glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3(
(float)i.second->getPos().x * 16,
(float)i.second->getPos().y * 16,
(float)i.second->getPos().z * 16
));

glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
i.second->renderer.drawChunk();
}
*/
for (auto& i : mChunkMeshes) {
glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3((float)i.first.x * 16,
(float)i.first.y * 16,
(float)i.first.z * 16
));

glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
i.second.draw();
}
}

void World::update() {
if (!rebuildThreadActive && !mChunkUpdateQueue.empty( )) {
auto updatefunc = [&]() {
while (!mChunkUpdateQueue.empty()) {
auto& pos = mChunkUpdateQueue.back();
auto& mesh = mChunkMeshes.find(pos)->second;
mChunkUpdateQueue.pop_back();
mesh.rebuildChunkGeometry();
}
rebuildThreadActive = false;
};
rebuildThreadActive = true;
std::thread(updatefunc).detach();
}
/*
while (!chunkUpdateQueue.empty()) {
auto chunk = chunks[chunkUpdateQueue.back()];
chunkUpdateQueue.pop_back();
std::thread(&ChunkRenderer::updateGeometry, &chunk->renderer).detach();
auto& pos = chunkUpdateQueue.back();
auto posVec = glm::ivec3(std::get<0>(pos), std::get<1>(pos), std::get<2>(pos));
auto& mesh = mChunkMeshes.find(posVec)->second;
chunkUpdateQueue.pop_back();
//mesh.rebuildChunkGeometry();
std::thread(&ChunkMesh::rebuildChunkGeometry, &mesh).detach();
mChunkGeometryUpdateQueue.push_back(posVec);
}
for (auto& i : chunks) {
i.second->renderer.updateVertexData();
}
auto it = mChunkGeometryUpdateQueue.begin();
while (it != mChunkGeometryUpdateQueue.end()) {
if (mChunkMeshes.find(*it)->second.updateGeometry()) {
std::cout << "updated chunk " << it->x << "," << it->y << "," << it->z;
mChunkGeometryUpdateQueue.erase(it);
}
else ++it;
}
*/
if (!rebuildThreadActive && !mChunkUpdateQueue.empty( )) {
auto updatefunc = [&]() {
while (!mChunkUpdateQueue.empty()) {
auto& pos = mChunkUpdateQueue.back();
auto& mesh = mChunkMeshes.find(pos)->second;
mChunkUpdateQueue.pop_back();
mesh.rebuildChunkGeometry();
}
rebuildThreadActive = false;
};
rebuildThreadActive = true;
std::thread(updatefunc).detach();
}
/*
while (!chunkUpdateQueue.empty()) {
auto chunk = chunks[chunkUpdateQueue.back()];
chunkUpdateQueue.pop_back();
std::thread(&ChunkRenderer::updateGeometry, &chunk->renderer).detach();
auto& pos = chunkUpdateQueue.back();
auto posVec = glm::ivec3(std::get<0>(pos), std::get<1>(pos), std::get<2>(pos));
auto& mesh = mChunkMeshes.find(posVec)->second;
chunkUpdateQueue.pop_back();
//mesh.rebuildChunkGeometry();
std::thread(&ChunkMesh::rebuildChunkGeometry, &mesh).detach();
mChunkGeometryUpdateQueue.push_back(posVec);
}
for (auto& i : chunks) {
i.second->renderer.updateVertexData();
}
auto it = mChunkGeometryUpdateQueue.begin();
while (it != mChunkGeometryUpdateQueue.end()) {
if (mChunkMeshes.find(*it)->second.updateGeometry()) {
std::cout << "updated chunk " << it->x << "," << it->y << "," << it->z;
mChunkGeometryUpdateQueue.erase(it);
}
else ++it;
}
*/

}

void World::forceGlobalGeometryUpdate() {
int chunkCount = 1;
/*
for (auto& i : chunks) {
std::cout << "\rUpdating chunk geometry (" << chunkCount << "/" << chunks.size() << ")" << std::flush;
i.second->renderer.updateGeometry();
chunkCount++;
//i.second->renderer.updateVertexData();
}
*/
chunkCount = 1;
for (auto& i : mChunkMeshes) {
std::cout << "\rUpdating chunk geometry, but better (" << chunkCount << "/" << mChunkMeshes.size() << ")" << std::flush;
i.second.rebuildChunkGeometry();
i.second.updateGeometry();
++chunkCount;
}
int chunkCount = 1;
/*
for (auto& i : chunks) {
std::cout << "\rUpdating chunk geometry (" << chunkCount << "/" << chunks.size() << ")" << std::flush;
i.second->renderer.updateGeometry();
chunkCount++;
//i.second->renderer.updateVertexData();
}
*/
chunkCount = 1;
for (auto& i : mChunkMeshes) {
std::cout << "\rUpdating chunk geometry, but better (" << chunkCount << "/" << mChunkMeshes.size() << ")" << std::flush;
i.second.rebuildChunkGeometry();
i.second.updateGeometry();
++chunkCount;
}
}

}

Loading…
Cancel
Save