Browse Source

threaded queues for mesh updates

testing
totallyfake 4 years ago
parent
commit
2cb2e9a494
  1. 3
      .gitmodules
  2. 1
      external/concurrentqueue
  3. 1
      include/blockingconcurrentqueue.h
  4. 5
      include/chunk.h
  5. 1
      include/concurrentqueue.h
  6. 2
      include/threadpool.h
  7. 13
      include/world.h
  8. 11
      src/chunk.cpp
  9. 394
      src/chunkrenderer.cpp
  10. 31
      src/scenes/testscene.cpp
  11. 4
      src/scenes/testscene.h
  12. 4
      src/threadpool.cpp
  13. 58
      src/world.cpp

3
.gitmodules vendored

@ -4,3 +4,6 @@ @@ -4,3 +4,6 @@
[submodule "libcuckoo"]
path = libcuckoo
url = https://github.com/efficient/libcuckoo.git
[submodule "external/concurrentqueue"]
path = external/concurrentqueue
url = https://github.com/cameron314/concurrentqueue.git

1
external/concurrentqueue vendored

@ -0,0 +1 @@ @@ -0,0 +1 @@
Subproject commit 3e0eac9b7a611bb8142db82789f307f2f0ad1c33

1
include/blockingconcurrentqueue.h

@ -0,0 +1 @@ @@ -0,0 +1 @@
../external/concurrentqueue/blockingconcurrentqueue.h

5
include/chunk.h

@ -29,6 +29,7 @@ namespace vtk { @@ -29,6 +29,7 @@ namespace vtk {
class World;
class Chunk {
friend class World;
public:
Chunk(World& world);
bool isLoaded();
@ -45,10 +46,14 @@ public: @@ -45,10 +46,14 @@ public:
ChunkRenderer renderer;
protected:
void setQueuedForMeshRebuild(const bool& rebuild = true);
bool isQueuedForMeshRebuild();
std::array<unsigned, 4096> voxels;
World& mLinkedWorld;
glm::ivec3 mPos;
std::atomic<bool> mLoaded;
std::atomic<bool> mQueuedForMeshRebuild;
};
}

1
include/concurrentqueue.h

@ -0,0 +1 @@ @@ -0,0 +1 @@
../external/concurrentqueue/concurrentqueue.h

2
include/threadpool.h

@ -27,6 +27,8 @@ public: @@ -27,6 +27,8 @@ public:
void addThreads(const int& count); // add new threads to the pool
void addJob(std::function<void()> newJob); // add a job to the pool
int threadCount();
private:
void threadIdle();

13
include/world.h

@ -23,7 +23,9 @@ @@ -23,7 +23,9 @@
#include "voxelmath.h"
#include "terraingen.h"
#include "graphics/chunkmesh.h"
#include "cuckoohash_map.hh"
#include "concurrentqueue.h"
#include <unordered_map>
#include <vector>
@ -35,6 +37,7 @@ namespace vtk { @@ -35,6 +37,7 @@ namespace vtk {
class Chunk;
class World {
friend class Chunk;
public:
World();
bool isVoxelSolid(const int& x, const int& y, const int& z);
@ -49,8 +52,8 @@ public: @@ -49,8 +52,8 @@ public:
Chunk* getChunk(const glm::ivec3& pos);
void queueChunkUpdate(const int& x, const int& y, const int& z, const bool& back = false);
void queueChunkUpdate(const glm::ivec3& pos, const bool& back = false);
void queueChunkUpdate(const int& x, const int& y, const int& z, const bool& highpriority = false);
void queueChunkUpdate(const glm::ivec3& pos, const bool& highpriority = false);
void queueChunkLoad(const glm::ivec3& pos);
@ -63,11 +66,15 @@ public: @@ -63,11 +66,15 @@ public:
//std::unordered_map<glm::ivec3, Chunk*, ivec3Hash> mChunks;
cuckoohash_map<glm::ivec3, Chunk*, ivec3Hash> mChunks;
std::unordered_map<glm::ivec3, ChunkMesh, ivec3Hash> mChunkMeshes;
cuckoohash_map<glm::ivec3, ChunkMesh*, ivec3Hash> mChunkMeshes;
std::vector<iPos> chunkUpdateQueue;
std::deque<glm::ivec3> mChunkUpdateQueue;
std::deque<glm::ivec3> mChunkLoadQueue;
// mesh update queues
moodycamel::ConcurrentQueue<glm::ivec3> mMeshUpdateQueue; // regular one
moodycamel::ConcurrentQueue<glm::ivec3> mMeshUpdateQueueSoon; // high priority one
unsigned chunkSize;
float voxelSize;

11
src/chunk.cpp

@ -24,7 +24,8 @@ namespace vtk { @@ -24,7 +24,8 @@ namespace vtk {
Chunk::Chunk(World& world) :
mLinkedWorld(world),
mLoaded(false)
mLoaded(false),
mQueuedForMeshRebuild(false)
{
mPos = glm::ivec3(0,0,0);
renderer.linkedChunk = this;
@ -93,4 +94,12 @@ World& Chunk::getWorld() { @@ -93,4 +94,12 @@ World& Chunk::getWorld() {
return mLinkedWorld;
}
void Chunk::setQueuedForMeshRebuild(const bool& rebuild) {
mQueuedForMeshRebuild = rebuild;
}
bool Chunk::isQueuedForMeshRebuild() {
return mQueuedForMeshRebuild.load();
}
}

394
src/chunkrenderer.cpp

@ -1,394 +0,0 @@ @@ -1,394 +0,0 @@
/*
* =====================================================================================
*
* Filename: chunkrenderer.cpp
*
* Description:
*
* Version: 1.0
* Created: 04/04/2014 11:34:53 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include "chunkrenderer.h"
#include "chunk.h"
#include "world.h"
#include <GL/glew.h>
#include <GL/gl.h>
#include <iostream>
namespace vtk {
void ChunkRenderer::init() {
hasGeometryChanged = false;
hasTexturesChanged = false;
hasLightingChanged = false;
updatingGeometry = false;
chunkSize = 16;
lightingMethod = 0;
voxelSize = 1.0f;
//generate VBOs
for (auto& i : vertexBuffers) {
for(auto& j : i) {
glGenBuffers(1, &j);
}
}
//generate VAOs
for (auto& i : vertexArrays) {
glGenVertexArrays(1, &i);
}
//bind VAOs
for (int i = 0; i < 6; i++) {
glBindVertexArray(vertexArrays[i]);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][1]);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][2]);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(2);
}
}
void ChunkRenderer::drawChunk() {
for (int i = 0; i < 6; i++) {
glBindVertexArray(vertexArrays[i]);
glDrawArrays(GL_TRIANGLES, 0, vertexCounts[i]);
}
}
void ChunkRenderer::setChunkPosition(const int&x, const int& y, const int&z) {
chunkPos = std::make_tuple(x, y, z);
}
void ChunkRenderer::updateGeometry() {
updatingGeometry = true;
for (auto& i : geometryVertices)
i.clear();
for (auto& i : faceCounts)
i = 0;
for (unsigned i = 0; i < chunkSize; i++) {
for (unsigned j = 0; j < chunkSize; j++) {
for (unsigned k = 0; k < chunkSize; k++) {
if (linkedChunk->isVoxelSolid(i,j,k)) {
if (!linkedChunk->isVoxelSolid(i+1,j,k)) {
//right face
//top left
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//bottom left
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom right
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
//bottom left
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[0], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize);
faceCounts[0]++;
}
if (!linkedChunk->isVoxelSolid(i-1,j,k)) {
//left face
//top left
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//top right
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize, k * voxelSize);
//bottom right
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize, k * voxelSize);
//top right
addVertex(geometryVertices[1], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
faceCounts[1]++;
}
if (!linkedChunk->isVoxelSolid(i,j+1,k)) {
//top face
//bottom left
addVertex(geometryVertices[2], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top left
addVertex(geometryVertices[2], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//bottom right
addVertex(geometryVertices[2], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[2], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//bottom right
addVertex(geometryVertices[2], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top left
addVertex(geometryVertices[2], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
faceCounts[2]++;
}
if (!linkedChunk->isVoxelSolid(i,j-1,k)) {
//bottom face
//top right
addVertex(geometryVertices[3], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom right
addVertex(geometryVertices[3], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
//top left
addVertex(geometryVertices[3], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[3], i * voxelSize, j * voxelSize, k * voxelSize);
//top left
addVertex(geometryVertices[3], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom right
addVertex(geometryVertices[3], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
faceCounts[3]++;
}
if (!linkedChunk->isVoxelSolid(i,j,k-1)) {
//back face
//top left
addVertex(geometryVertices[4], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//top right
addVertex(geometryVertices[4], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
//bottom left
addVertex(geometryVertices[4], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
//bottom right
addVertex(geometryVertices[4], i * voxelSize, j * voxelSize, k * voxelSize);
//bottom left
addVertex(geometryVertices[4], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize);
//top right
addVertex(geometryVertices[4], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize);
faceCounts[4]++;
}
if (!linkedChunk->isVoxelSolid(i,j,k+1)) {
//front face
//bottom right
addVertex(geometryVertices[5], i * voxelSize + voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[5], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[5], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top left
addVertex(geometryVertices[5], i * voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//top right
addVertex(geometryVertices[5], i * voxelSize + voxelSize, j * voxelSize + voxelSize, k * voxelSize + voxelSize);
//bottom left
addVertex(geometryVertices[5], i * voxelSize, j * voxelSize, k * voxelSize + voxelSize);
faceCounts[5]++;
}
}
}
}
}
hasGeometryChanged = true;
updateTexCoords();
updateLighting();
updatingGeometry = false;
}
void ChunkRenderer::updateTexCoords() {
auto linkedWorld = linkedChunk->getWorld();
for (auto& i : textureCoords)
i.clear();
for (unsigned i = 0; i < chunkSize; i++) {
for (unsigned j = 0; j < chunkSize; j++) {
for (unsigned k = 0; k < chunkSize; k++) {
if (linkedChunk->isVoxelSolid(i,j,k)) {
if (!linkedChunk->isVoxelSolid(i+1,j,k)) {
//right face
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::TOPLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::TOPRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::BOTTOMRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[0], linkedChunk->getWorldCoords(i,j,k), Face3D::RIGHT, Corner2D::TOPRIGHT);
}
if (!linkedChunk->isVoxelSolid(i-1,j,k)) {
//left face
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::TOPLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::TOPRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::BOTTOMRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[1], linkedChunk->getWorldCoords(i,j,k), Face3D::LEFT, Corner2D::TOPRIGHT);
}
if (!linkedChunk->isVoxelSolid(i,j+1,k)) {
//top face
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::TOPLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::BOTTOMRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::TOPRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::BOTTOMRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[2], linkedChunk->getWorldCoords(i,j,k), Face3D::TOP, Corner2D::TOPLEFT);
}
if (!linkedChunk->isVoxelSolid(i,j-1,k)) {
//bottom face
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::TOPRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::BOTTOMRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::TOPLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::TOPLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[3], linkedChunk->getWorldCoords(i,j,k), Face3D::BOTTOM, Corner2D::BOTTOMRIGHT);
}
if (!linkedChunk->isVoxelSolid(i,j,k-1)) {
//back face
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::TOPLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::TOPRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::BOTTOMRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[4], linkedChunk->getWorldCoords(i,j,k), Face3D::BACK, Corner2D::TOPRIGHT);
}
if (!linkedChunk->isVoxelSolid(i,j,k+1)) {
//front face
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::BOTTOMRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::BOTTOMLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::TOPRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::TOPLEFT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::TOPRIGHT);
linkedWorld.voxelInfo.pushTexCoordFromWorldCoords(textureCoords[5], linkedChunk->getWorldCoords(i,j,k), Face3D::FRONT, Corner2D::BOTTOMLEFT);
}
}
}
}
}
hasTexturesChanged = true;
}
void ChunkRenderer::updateLighting() {
for (auto& i : lightingData)
i.clear();
for (unsigned i = 0; i < chunkSize; i++) {
for (unsigned j = 0; j < chunkSize; j++) {
for (unsigned k = 0; k < chunkSize; k++) {
if (linkedChunk->isVoxelSolid(i,j,k)) {
if (lightingMethod == 0) { //fullbright lighting
//face U , V , I
//right face
if (!linkedChunk->isVoxelSolid(i+1,j,k)) {
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //TL
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //TR
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //BL
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //BR
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //BL
addVertex(lightingData[0], 0.8f, 0.8f, 0.8f); //TR
}
if (!linkedChunk->isVoxelSolid(i-1,j,k)) {
//left face
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //TL
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //TR
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //BL
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //BR
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //BL
addVertex(lightingData[1], 0.8f, 0.8f, 0.8f); //TR
}
if (!linkedChunk->isVoxelSolid(i,j+1,k)) {
//top face
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //TL
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //TR
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //BL
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //BR
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //BL
addVertex(lightingData[2], 1.0f, 1.0f, 1.0f); //TR
}
if (!linkedChunk->isVoxelSolid(i,j-1,k)) {
//bottom face
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //TL
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //TR
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //BL
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //BR
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //BL
addVertex(lightingData[3], 0.5f, 0.5f, 0.5f); //TR
}
if (!linkedChunk->isVoxelSolid(i,j,k-1)) {
//back face
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //TL
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //TR
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //BL
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //BR
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //BL
addVertex(lightingData[4], 0.7f, 0.7f, 0.7f); //TR
}
if (!linkedChunk->isVoxelSolid(i,j,k+1)) {
//front face
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //TL
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //TR
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //BL
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //BR
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //BL
addVertex(lightingData[5], 0.9f, 0.9f, 0.9f); //TR
}
} else if (lightingMethod == 1) { //blocky lighting (Need to implement!)
} else if (lightingMethod == 2) { //smooth lighting (Need to implement!)
}
}
}
}
}
hasLightingChanged = true;
}
void ChunkRenderer::updateVertexData() {
if (!updatingGeometry) {
//std::cout << "testing";
for (unsigned i = 0; i < 6; i++) {
if (hasGeometryChanged) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * geometryVertices[i].size(), geometryVertices[i].data(), GL_STATIC_DRAW);
//hasGeometryChanged = false;
}
if (hasTexturesChanged) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * textureCoords[i].size(), textureCoords[i].data(), GL_STATIC_DRAW);
//hasTexturesChanged = false;
}
if (hasLightingChanged) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[i][2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * lightingData[i].size(), lightingData[i].data(), GL_STATIC_DRAW);
//hasLightingChanged = false;
}
}
if (hasGeometryChanged) hasGeometryChanged = false;
if (hasTexturesChanged) hasTexturesChanged = false;
if (hasLightingChanged) hasLightingChanged = false;
for (int i = 0; i < 6; i++) {
vertexCounts[i] = faceCounts[i] * 6;
}
}
}
void ChunkRenderer::addVertex(std::vector<float>& data, const float& x, const float& y, const float& z) {
data.push_back(x);
data.push_back(y);
data.push_back(z);
}
}

31
src/scenes/testscene.cpp

@ -86,6 +86,7 @@ void TestScene::init() { @@ -86,6 +86,7 @@ void TestScene::init() {
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" ));
handler.setAction("Toggle Noclip", conf->getValue<std::string>("controls.bindings.noclip", "V"));
//set signals for handler
handler.getEventSignal(SDL_QUIT ).connect<Game , &Game::stop >(linkedGame);
@ -120,6 +121,8 @@ void TestScene::init() { @@ -120,6 +121,8 @@ void TestScene::init() {
//world.forceGlobalGeometryUpdate();
voxelType = 1;
mNoclip = true;
mNoclipDebounce = false;
}
void TestScene::reInit() {
@ -138,11 +141,18 @@ void TestScene::update(const float& dTime) { @@ -138,11 +141,18 @@ void TestScene::update(const float& dTime) {
if (handler.isActionDown("Move Backward")) camera.moveRelative(glm::vec3( 0.0f, 0.0f, -1.0f) * dTime * 16.0f);
if (handler.isActionDown("Move Left" )) camera.moveRelative(glm::vec3(-1.0f, 0.0f, 0.0f) * dTime * 16.0f);
if (handler.isActionDown("Move Right" )) camera.moveRelative(glm::vec3( 1.0f, 0.0f, 0.0f) * dTime * 16.0f);
if (handler.isActionDown("Move Up" )) camera.move(glm::vec3( 0.0f, 1.0f, 0.0f) * dTime * 8.0f);
if (handler.isActionDown("Move Down" )) camera.move(glm::vec3( 0.0f, -1.0f, 0.0f) * dTime * 8.0f);
if (handler.isActionDown("Move Up" ) && mNoclip) camera.move(glm::vec3( 0.0f, 1.0f, 0.0f) * dTime * 8.0f);
if (handler.isActionDown("Move Down" ) && mNoclip) camera.move(glm::vec3( 0.0f, -1.0f, 0.0f) * dTime * 8.0f);
if (handler.isActionDown("Select Type 1")) voxelType = 1;
if (handler.isActionDown("Select Type 2")) voxelType = 2;
if (!mNoclipDebounce && handler.isActionDown("Toggle Noclip")) {
mNoclipDebounce = true;
mNoclip = !mNoclip;
std::cout << mNoclip << "\n" << std::flush;
} else {
//mNoclipDebounce = false;
}
//place voxel testing
if ((handler.isActionDown("Place Voxel") || handler.isActionDown("Delete Voxel")) && !placeVoxel) {
@ -169,7 +179,22 @@ void TestScene::update(const float& dTime) { @@ -169,7 +179,22 @@ void TestScene::update(const float& dTime) {
mCamLastLoadPosition = camera.getPosition();
world.queueChunkLoadsAroundPoint(camera.getPosition(), 16);
}
//player "physics"
if (!mNoclip) {
mVelocity = glm::vec3(0.0f, mVelocity.y + (-9.8f * dTime), 0.0f);
// check ground collision
glm::ivec3 cameraIPos = camera.getPosition();
cameraIPos.y = cameraIPos.y - 2;
if (world.isVoxelSolid(cameraIPos.x, cameraIPos.y, cameraIPos.z)) {
std::cout << cameraIPos.y << "\n" << std::flush;
auto newCameraPos = camera.getPosition();
newCameraPos.y = (float)cameraIPos.y + 2.8f;
camera.setPosition(newCameraPos);
mVelocity.y = 0.0f;
}
camera.move(mVelocity * dTime);
}
}
void TestScene::draw() {

4
src/scenes/testscene.h

@ -63,6 +63,10 @@ protected: @@ -63,6 +63,10 @@ protected:
bool placeVoxel;
unsigned voxelType;
bool mNoclip;
bool mNoclipDebounce;
glm::vec3 mVelocity;
//controls
InputHandler handler;

4
src/threadpool.cpp

@ -48,5 +48,9 @@ void ThreadPool::addJob(std::function<void ()> newJob) { @@ -48,5 +48,9 @@ void ThreadPool::addJob(std::function<void ()> newJob) {
}
mCondition.notify_one();
}
int ThreadPool::threadCount() {
return mThreads.size();
}
}

58
src/world.cpp

@ -106,7 +106,7 @@ bool World::generateChunk(const int& x, const int& y, const int& z) { @@ -106,7 +106,7 @@ bool World::generateChunk(const int& x, const int& y, const int& z) {
bool World::insertChunk(Chunk* chunk) {
mChunks.insert(chunk->getPos(), chunk);
mChunkMeshes.emplace(chunk->getPos(), ChunkMesh(*this, chunk->getPos()));
mChunkMeshes.insert(chunk->getPos(), new ChunkMesh(*this, chunk->getPos()));
return true;
}
@ -117,21 +117,20 @@ Chunk* World::getChunk(const glm::ivec3& pos) { @@ -117,21 +117,20 @@ Chunk* World::getChunk(const glm::ivec3& pos) {
else return nullptr;
}
void World::queueChunkUpdate(const int& x, const int& y, const int& z, const bool& back) {
void World::queueChunkUpdate(const int& x, const int& y, const int& z, const bool& highpriority) {
queueChunkUpdate(glm::ivec3(x,y,z));
}
void World::queueChunkUpdate(const glm::ivec3& pos, const bool& back) {
if (!getChunk(pos)) 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
}
void World::queueChunkUpdate(const glm::ivec3& pos, const bool& highpriority) {
auto chunk = getChunk(pos);
if (!chunk || chunk->isQueuedForMeshRebuild()) return;
chunk->setQueuedForMeshRebuild(true);
if (back) {
mChunkUpdateQueue.push_back(pos);
} else {
mChunkUpdateQueue.push_front(pos);
if (highpriority) { // queue for higher rebuild priority
mMeshUpdateQueueSoon.enqueue(pos);
return;
}
mMeshUpdateQueue.enqueue(pos);
}
void World::queueChunkLoad(const glm::ivec3 &pos) {
@ -145,28 +144,53 @@ void World::queueChunkLoad(const glm::ivec3 &pos) { @@ -145,28 +144,53 @@ void World::queueChunkLoad(const glm::ivec3 &pos) {
}
void World::draw() {
for (auto& i : mChunkMeshes) {
auto lt = mChunkMeshes.lock_table();
for (const auto& i : lt) {
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();
i.second->draw();
}
}
void World::update() {
if (!rebuildThreadActive && !mChunkUpdateQueue.empty( )) {
//if the rebuild thread is not active and there are meshes to be updated
if (!rebuildThreadActive && (mMeshUpdateQueueSoon.size_approx() > 0 ||
mMeshUpdateQueue.size_approx() > 0)) {
auto updatefunc = [&]() {
glm::ivec3 pos;
while (mMeshUpdateQueueSoon.try_dequeue(pos)) {
ChunkMesh* mesh;
mChunkMeshes.find(pos, mesh);
if (mesh) {
mesh->rebuildChunkGeometry();
}
getChunk(pos)->setQueuedForMeshRebuild(false);
}
while (mMeshUpdateQueue.try_dequeue(pos)) {
ChunkMesh* mesh;
mChunkMeshes.find(pos, mesh);
if (mesh) {
mesh->rebuildChunkGeometry();
}
getChunk(pos)->setQueuedForMeshRebuild(false);
}
rebuildThreadActive = false;
/*
while (!mChunkUpdateQueue.empty()) {
auto& pos = mChunkUpdateQueue.back();
auto& mesh = mChunkMeshes.find(pos)->second;
ChunkMesh* mesh;
mChunkMeshes.find(pos, mesh);
mChunkUpdateQueue.pop_back();
if (!mesh.rebuildChunkGeometry())
if (!mesh->rebuildChunkGeometry())
queueChunkUpdate(pos);
}
rebuildThreadActive = false;
*/
};
rebuildThreadActive = true;
@ -189,6 +213,7 @@ void World::update() { @@ -189,6 +213,7 @@ void World::update() {
}
void World::forceGlobalGeometryUpdate() {
/*
int chunkCount = 1;
chunkCount = 1;
for (auto& i : mChunkMeshes) {
@ -197,6 +222,7 @@ void World::forceGlobalGeometryUpdate() { @@ -197,6 +222,7 @@ void World::forceGlobalGeometryUpdate() {
i.second.updateGeometry();
++chunkCount;
}
*/
}
void World::queueChunkLoadsAroundPoint(const glm::vec3 &point, const int &chunkRadius) {

Loading…
Cancel
Save