multithread blockpicking #2
|
@ -56,7 +56,7 @@ namespace Chunk
|
||||||
std::unique_ptr<Block[]> getBlocksArray(int* len) { return (this->blocks.toArray(len)); }
|
std::unique_ptr<Block[]> getBlocksArray(int* len) { return (this->blocks.toArray(len)); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLuint VAO{0}, VBO{0}, EBO{0}, colorBuffer{0}, numVertices{0};
|
GLuint VAO{0}, VBO{0}, EBO{0}, colorBuffer{0}, numTriangles{0};
|
||||||
std::atomic<float> unload_timer{0};
|
std::atomic<float> unload_timer{0};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
namespace chunkmesher{
|
namespace chunkmesher{
|
||||||
struct MeshData{
|
struct MeshData{
|
||||||
Chunk::Chunk* chunk;
|
Chunk::Chunk* chunk;
|
||||||
|
GLuint numVertices{0};
|
||||||
|
|
||||||
std::vector<GLfloat> vertices;
|
std::vector<GLfloat> vertices;
|
||||||
std::vector<GLfloat> colors;
|
std::vector<GLfloat> colors;
|
||||||
std::vector<GLuint> indices;
|
std::vector<GLuint> indices;
|
||||||
|
|
|
@ -136,4 +136,70 @@ namespace chunkmanager
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blockpick(bool place){
|
||||||
|
// cast a ray from the camera in the direction pointed by the camera itself
|
||||||
|
glm::vec3 pos = glm::vec3(theCamera.getAtomicPosX(), theCamera.getAtomicPosY(),
|
||||||
|
theCamera.getAtomicPosZ());
|
||||||
|
for(float t = 0.0; t <= 10.0; t += 0.5){
|
||||||
|
// traverse the ray a block at the time
|
||||||
|
pos = theCamera.getPos() + t * theCamera.getFront();
|
||||||
|
|
||||||
|
// get which chunk and block the ray is at
|
||||||
|
int px = ((int)(pos.x))/CHUNK_SIZE;
|
||||||
|
int py = ((int)(pos.y))/CHUNK_SIZE;
|
||||||
|
int pz = ((int)(pos.z))/CHUNK_SIZE;
|
||||||
|
int bx = pos.x - px*CHUNK_SIZE;
|
||||||
|
int by = pos.y - py*CHUNK_SIZE;
|
||||||
|
int bz = pos.z - pz*CHUNK_SIZE;
|
||||||
|
|
||||||
|
// exit early if the position is invalid or the chunk does not exist
|
||||||
|
if(px < 0 || py < 0 || pz < 0 || px >= 1024 || py >= 1024 || pz >= 1024) return;
|
||||||
|
|
||||||
|
ChunkTable::accessor a;
|
||||||
|
if(!chunks.find(a, calculateIndex(px, py, pz))) return;
|
||||||
|
Chunk::Chunk* c = a->second;
|
||||||
|
if(!c->getState(Chunk::CHUNK_STATE_GENERATED) || c->getState(Chunk::CHUNK_STATE_EMPTY)) continue;
|
||||||
|
|
||||||
|
Block b = c->getBlock(bx, by, bz);
|
||||||
|
|
||||||
|
a.release();
|
||||||
|
// if the block is non empty
|
||||||
|
if(b != Block::AIR){
|
||||||
|
|
||||||
|
// if placing a new block
|
||||||
|
if(place){
|
||||||
|
// Go half a block backwards on the ray, to check the block where the ray was
|
||||||
|
// coming from
|
||||||
|
// Doing this and not using normal adds the unexpected (and unwanted) ability to
|
||||||
|
// place blocks diagonally, without faces colliding with the block that has
|
||||||
|
// been clicked
|
||||||
|
pos -= theCamera.getFront()*0.5f;
|
||||||
|
|
||||||
|
int px1 = ((int)(pos.x))/CHUNK_SIZE;
|
||||||
|
int py1 = ((int)(pos.y))/CHUNK_SIZE;
|
||||||
|
int pz1 = ((int)(pos.z))/CHUNK_SIZE;
|
||||||
|
int bx1 = pos.x - px1*CHUNK_SIZE;
|
||||||
|
int by1 = pos.y - py1*CHUNK_SIZE;
|
||||||
|
int bz1 = pos.z - pz1*CHUNK_SIZE;
|
||||||
|
|
||||||
|
// exit early if the position is invalid or the chunk does not exist
|
||||||
|
if(px1 < 0 || py1 < 0 || pz1 < 0 || px1 >= 1024 || py1 >= 1024 || pz1 >= 1024) return;
|
||||||
|
ChunkTable::accessor a1;
|
||||||
|
if(!chunks.find(a1, calculateIndex(px1, py1, pz1))) return;
|
||||||
|
Chunk::Chunk* c1 = a1->second;
|
||||||
|
// place the new block (only stone for now)
|
||||||
|
c1->setBlock( Block::STONE, bx1, by1, bz1);
|
||||||
|
|
||||||
|
// mark the mesh of the chunk the be updated
|
||||||
|
c1->setState(Chunk::CHUNK_STATE_MESHED, false);
|
||||||
|
}else{
|
||||||
|
// replace the current block with air to remove it
|
||||||
|
c->setBlock( Block::AIR, bx, by, bz);
|
||||||
|
|
||||||
|
c->setState(Chunk::CHUNK_STATE_MESHED, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,7 @@ void mesh(Chunk::Chunk* chunk)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Cleanup previous data
|
// Cleanup previous data
|
||||||
chunk->numVertices = 0;
|
mesh_data->numVertices = 0;
|
||||||
mesh_data->chunk = chunk;
|
mesh_data->chunk = chunk;
|
||||||
mesh_data->vertices.clear();
|
mesh_data->vertices.clear();
|
||||||
mesh_data->indices.clear();
|
mesh_data->indices.clear();
|
||||||
|
@ -202,7 +202,7 @@ void mesh(Chunk::Chunk* chunk)
|
||||||
|
|
||||||
void sendtogpu(MeshData* mesh_data)
|
void sendtogpu(MeshData* mesh_data)
|
||||||
{
|
{
|
||||||
if (mesh_data->chunk->numVertices > 0)
|
if (mesh_data->numVertices > 0)
|
||||||
{
|
{
|
||||||
if(mesh_data->chunk->VAO == 0) mesh_data->chunk->createBuffers();
|
if(mesh_data->chunk->VAO == 0) mesh_data->chunk->createBuffers();
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ void sendtogpu(MeshData* mesh_data)
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// save the number of indices of the mesh, it is needed later for drawing
|
// save the number of indices of the mesh, it is needed later for drawing
|
||||||
mesh_data->chunk->numVertices = (GLuint)(mesh_data->indices.size());
|
mesh_data->chunk->numTriangles = (GLuint)(mesh_data->indices.size());
|
||||||
|
|
||||||
// once data has been sent to the GPU, it can be cleared from system RAM
|
// once data has been sent to the GPU, it can be cleared from system RAM
|
||||||
mesh_data->vertices.clear();
|
mesh_data->vertices.clear();
|
||||||
|
@ -330,22 +330,22 @@ void quad(MeshData* mesh_data, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec
|
||||||
|
|
||||||
if (backFace)
|
if (backFace)
|
||||||
{
|
{
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 2);
|
mesh_data->indices.push_back(mesh_data->numVertices + 2);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices);
|
mesh_data->indices.push_back(mesh_data->numVertices);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 1);
|
mesh_data->indices.push_back(mesh_data->numVertices + 1);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 1);
|
mesh_data->indices.push_back(mesh_data->numVertices + 1);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 3);
|
mesh_data->indices.push_back(mesh_data->numVertices + 3);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 2);
|
mesh_data->indices.push_back(mesh_data->numVertices + 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 2);
|
mesh_data->indices.push_back(mesh_data->numVertices + 2);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 3);
|
mesh_data->indices.push_back(mesh_data->numVertices + 3);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 1);
|
mesh_data->indices.push_back(mesh_data->numVertices + 1);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 1);
|
mesh_data->indices.push_back(mesh_data->numVertices + 1);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices);
|
mesh_data->indices.push_back(mesh_data->numVertices);
|
||||||
mesh_data->indices.push_back(mesh_data->chunk->numVertices + 2);
|
mesh_data->indices.push_back(mesh_data->numVertices + 2);
|
||||||
}
|
}
|
||||||
mesh_data->chunk->numVertices += 4;
|
mesh_data->numVertices += 4;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,13 +129,13 @@ void processInput(GLFWwindow *window)
|
||||||
glfwSetWindowShouldClose(window, true);
|
glfwSetWindowShouldClose(window, true);
|
||||||
|
|
||||||
if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_2) == GLFW_PRESS && !blockpick){
|
if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_2) == GLFW_PRESS && !blockpick){
|
||||||
//chunkmanager::blockpick(false);
|
chunkmanager::blockpick(false);
|
||||||
blockpick=true;
|
blockpick=true;
|
||||||
lastBlockPick=glfwGetTime();
|
lastBlockPick=glfwGetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS && !blockpick){
|
if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS && !blockpick){
|
||||||
//chunkmanager::blockpick(true);
|
chunkmanager::blockpick(true);
|
||||||
blockpick=true;
|
blockpick=true;
|
||||||
lastBlockPick=glfwGetTime();
|
lastBlockPick=glfwGetTime();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,6 @@ namespace renderer{
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& c : chunks_torender){
|
for(auto& c : chunks_torender){
|
||||||
if(! (c->getState(Chunk::CHUNK_STATE_MESHED))) continue;
|
|
||||||
|
|
||||||
float dist = glm::distance(c->getPosition(), cameraChunkPos);
|
float dist = glm::distance(c->getPosition(), cameraChunkPos);
|
||||||
if(dist <= static_cast<float>(RENDER_DISTANCE)){
|
if(dist <= static_cast<float>(RENDER_DISTANCE)){
|
||||||
if(!c->getState(Chunk::CHUNK_STATE_MESH_LOADED)) continue;
|
if(!c->getState(Chunk::CHUNK_STATE_MESH_LOADED)) continue;
|
||||||
|
@ -95,7 +93,7 @@ namespace renderer{
|
||||||
|
|
||||||
if (!out)
|
if (!out)
|
||||||
{
|
{
|
||||||
if(c->numVertices > 0)
|
if(c->numTriangles > 0)
|
||||||
{
|
{
|
||||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // wireframe mode
|
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // wireframe mode
|
||||||
theShader->setMat4("model", model);
|
theShader->setMat4("model", model);
|
||||||
|
@ -103,7 +101,7 @@ namespace renderer{
|
||||||
theShader->setMat4("projection", theCamera.getProjection());
|
theShader->setMat4("projection", theCamera.getProjection());
|
||||||
|
|
||||||
glBindVertexArray(c->VAO);
|
glBindVertexArray(c->VAO);
|
||||||
glDrawElements(GL_TRIANGLES, c->numVertices , GL_UNSIGNED_INT, 0);
|
glDrawElements(GL_TRIANGLES, c->numTriangles , GL_UNSIGNED_INT, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue