fallimentary attempt at fixing memory management with onetbb
parent
00cdd22e10
commit
1ec529fae5
|
@ -116,7 +116,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glm::vec3 cameraPos = glm::vec3(512.0, 80.0f, 512.0f);
|
glm::vec3 cameraPos = glm::vec3(512.0, 256.0f, 512.0f);
|
||||||
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
|
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||||
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
|
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||||
glm::vec3 direction = glm::vec3(0.0f);
|
glm::vec3 direction = glm::vec3(0.0f);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
|
|
||||||
// Seconds to be passed outside of render distance for a chunk to be destroyed
|
// Seconds to be passed outside of render distance for a chunk to be destroyed
|
||||||
#define UNLOAD_TIMEOUT 10
|
#define UNLOAD_TIMEOUT 0
|
||||||
|
|
||||||
#define MESHING_PRIORITY_NORMAL 0
|
#define MESHING_PRIORITY_NORMAL 0
|
||||||
#define MESHING_PRIORITY_PLAYER_EDIT 10
|
#define MESHING_PRIORITY_PLAYER_EDIT 10
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
#include "shader.hpp"
|
#include "shader.hpp"
|
||||||
|
|
||||||
namespace renderer{
|
namespace renderer{
|
||||||
typedef oneapi::tbb::concurrent_unordered_set<Chunk::Chunk*> RenderSet;
|
//typedef oneapi::tbb::concurrent_unordered_set<Chunk::Chunk*> RenderSet;
|
||||||
|
typedef oneapi::tbb::concurrent_queue<Chunk::Chunk*> RenderQueue;
|
||||||
|
|
||||||
void init(GLFWwindow* window);
|
void init(GLFWwindow* window);
|
||||||
void render();
|
void render();
|
||||||
|
@ -20,7 +21,7 @@ namespace renderer{
|
||||||
void saveScreenshot(bool forceFullHD=false);
|
void saveScreenshot(bool forceFullHD=false);
|
||||||
|
|
||||||
Shader* getRenderShader();
|
Shader* getRenderShader();
|
||||||
RenderSet& getChunksToRender();
|
RenderQueue& getChunksToRender();
|
||||||
oneapi::tbb::concurrent_queue<chunkmesher::MeshData*>& getMeshDataQueue();
|
oneapi::tbb::concurrent_queue<chunkmesher::MeshData*>& getMeshDataQueue();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,4 +7,4 @@ set(SOURCE_FILES main.cpp chunk.cpp chunkmanager.cpp chunkmesher.cpp chunkgenera
|
||||||
add_executable(OpenGLTest ${SOURCE_FILES})
|
add_executable(OpenGLTest ${SOURCE_FILES})
|
||||||
|
|
||||||
target_link_libraries(OpenGLTest glfw tbb glad glm imgui)
|
target_link_libraries(OpenGLTest glfw tbb glad glm imgui)
|
||||||
install(TARGETS OpenGLTest DESTINATION ${DIVISIBLE_INSTALL_BIN_DIR})
|
install(TARGETS OpenGLTest DESTINATION)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "chunkmanager.hpp"
|
#include "chunkmanager.hpp"
|
||||||
|
|
||||||
|
#include <oneapi/tbb.h>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <oneapi/tbb.h>
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
#include <glm/gtx/string_cast.hpp>
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
@ -63,7 +63,7 @@ namespace chunkmanager
|
||||||
chunkmesher::getMeshDataQueue().push(new chunkmesher::MeshData());
|
chunkmesher::getMeshDataQueue().push(new chunkmesher::MeshData());
|
||||||
|
|
||||||
should_run = true;
|
should_run = true;
|
||||||
update_thread = std::thread(update);
|
//update_thread = std::thread(update);
|
||||||
gen_thread = std::thread(generate);
|
gen_thread = std::thread(generate);
|
||||||
mesh_thread = std::thread(mesh);
|
mesh_thread = std::thread(mesh);
|
||||||
|
|
||||||
|
@ -92,11 +92,14 @@ namespace chunkmanager
|
||||||
}
|
}
|
||||||
|
|
||||||
oneapi::tbb::concurrent_queue<Chunk::Chunk*> chunks_todelete;
|
oneapi::tbb::concurrent_queue<Chunk::Chunk*> chunks_todelete;
|
||||||
|
oneapi::tbb::concurrent_queue<Chunk::Chunk*> chunks_primary_delete;
|
||||||
int nUnloaded{0};
|
int nUnloaded{0};
|
||||||
int already{0};
|
int already{0};
|
||||||
bool first{true};
|
bool first{true};
|
||||||
void update(){
|
void update(){
|
||||||
while(should_run) {
|
}
|
||||||
|
|
||||||
|
void primary_thread_update(){
|
||||||
int chunkX=static_cast<int>(theCamera.getAtomicPosX() / CHUNK_SIZE);
|
int chunkX=static_cast<int>(theCamera.getAtomicPosX() / CHUNK_SIZE);
|
||||||
int chunkY=static_cast<int>(theCamera.getAtomicPosY() / CHUNK_SIZE);
|
int chunkY=static_cast<int>(theCamera.getAtomicPosY() / CHUNK_SIZE);
|
||||||
int chunkZ=static_cast<int>(theCamera.getAtomicPosZ() / CHUNK_SIZE);
|
int chunkZ=static_cast<int>(theCamera.getAtomicPosZ() / CHUNK_SIZE);
|
||||||
|
@ -139,43 +142,66 @@ namespace chunkmanager
|
||||||
|
|
||||||
|
|
||||||
debug::window::set_parameter("update_chunks_total", (int) (chunks.size()));
|
debug::window::set_parameter("update_chunks_total", (int) (chunks.size()));
|
||||||
debug::window::set_parameter("update_chunks_bucket", (int) (chunks.max_size()));
|
|
||||||
|
|
||||||
// Perform needed operations on all the chunks
|
// Perform needed operations on all the chunks
|
||||||
oneapi::tbb::parallel_for(chunks.range(), [](ChunkTable::range_type &r){
|
oneapi::tbb::parallel_for(chunks.range(), [=](ChunkTable::range_type &r){
|
||||||
for(ChunkTable::const_iterator a = r.begin(); a != r.end(); a++){
|
for(ChunkTable::const_iterator a = r.begin(); a != r.end(); a++){
|
||||||
if(a->second->getState(Chunk::CHUNK_STATE_UNLOADED)){
|
if(a->second->getState(Chunk::CHUNK_STATE_UNLOADED)){
|
||||||
chunks_todelete.push(a->second);
|
if(a->second->getState(Chunk::CHUNK_STATE_MESH_LOADED)) chunks_todelete.push(a->second);
|
||||||
|
//nUnloaded++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! (a->second->getState(Chunk::CHUNK_STATE_GENERATED))) {
|
int distx = a->second->getPosition().x - chunkX;
|
||||||
chunks_to_generate_queue.push(std::make_pair(a->second, GENERATION_PRIORITY_NORMAL));
|
int disty = a->second->getPosition().y - chunkY;
|
||||||
}else if(a->second->getState(Chunk::CHUNK_STATE_EMPTY)){
|
int distz = a->second->getPosition().z - chunkZ;
|
||||||
continue;
|
if(distx >= -RENDER_DISTANCE && distx < RENDER_DISTANCE &&
|
||||||
}else if(! (a->second->getState(Chunk::CHUNK_STATE_MESHED))){
|
disty >= -RENDER_DISTANCE && disty < RENDER_DISTANCE &&
|
||||||
int x = a->second->getPosition().x;
|
distz >= -RENDER_DISTANCE && distz < RENDER_DISTANCE){
|
||||||
int y = a->second->getPosition().y;
|
|
||||||
int z = a->second->getPosition().z;
|
|
||||||
|
|
||||||
ChunkTable::const_accessor a1;
|
// reset out-of-vision and unload flags
|
||||||
if(
|
a->second->setState(Chunk::CHUNK_STATE_OUTOFVISION, false);
|
||||||
(x + 1 > 1023 || (chunks.find(a1, calculateIndex(x+1, y, z)) &&
|
a->second->setState(Chunk::CHUNK_STATE_UNLOADED, false);
|
||||||
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
|
||||||
(x - 1 < 0|| (chunks.find(a1, calculateIndex(x-1, y, z)) &&
|
if(! (a->second->getState(Chunk::CHUNK_STATE_GENERATED))) {
|
||||||
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
chunks_to_generate_queue.push(std::make_pair(a->second, GENERATION_PRIORITY_NORMAL));
|
||||||
(y + 1 > 1023 || (chunks.find(a1, calculateIndex(x, y+1, z)) &&
|
}else if(! (a->second->getState(Chunk::CHUNK_STATE_MESHED))){
|
||||||
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
int x = a->second->getPosition().x;
|
||||||
(y - 1 < 0|| (chunks.find(a1, calculateIndex(x, y-1, z)) &&
|
int y = a->second->getPosition().y;
|
||||||
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
int z = a->second->getPosition().z;
|
||||||
(z + 1 > 1023 || (chunks.find(a1, calculateIndex(x, y, z+1)) &&
|
|
||||||
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
ChunkTable::const_accessor a1;
|
||||||
(z - 1 < 0|| (chunks.find(a1, calculateIndex(x, y, z-1)) &&
|
if(
|
||||||
a1->second->getState(Chunk::CHUNK_STATE_GENERATED)))
|
(x + 1 > 1023 || (chunks.find(a1, calculateIndex(x+1, y, z)) &&
|
||||||
)
|
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
||||||
chunks_to_mesh_queue.push(std::make_pair(a->second, MESHING_PRIORITY_NORMAL));
|
(x - 1 < 0|| (chunks.find(a1, calculateIndex(x-1, y, z)) &&
|
||||||
|
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
||||||
|
(y + 1 > 1023 || (chunks.find(a1, calculateIndex(x, y+1, z)) &&
|
||||||
|
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
||||||
|
(y - 1 < 0|| (chunks.find(a1, calculateIndex(x, y-1, z)) &&
|
||||||
|
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
||||||
|
(z + 1 > 1023 || (chunks.find(a1, calculateIndex(x, y, z+1)) &&
|
||||||
|
a1->second->getState(Chunk::CHUNK_STATE_GENERATED))) &&
|
||||||
|
(z - 1 < 0|| (chunks.find(a1, calculateIndex(x, y, z-1)) &&
|
||||||
|
a1->second->getState(Chunk::CHUNK_STATE_GENERATED)))
|
||||||
|
)
|
||||||
|
chunks_to_mesh_queue.push(std::make_pair(a->second, MESHING_PRIORITY_NORMAL));
|
||||||
|
}else{
|
||||||
|
renderer::getChunksToRender().push(a->second);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
renderer::getChunksToRender().insert(a->second);
|
if(a->second->getState(Chunk::CHUNK_STATE_OUTOFVISION)){
|
||||||
|
// If chunk was already out and enough time has passed
|
||||||
|
if(glfwGetTime() - a->second->unload_timer > UNLOAD_TIMEOUT){
|
||||||
|
// Mark the chunk to be unloaded
|
||||||
|
a->second->setState(Chunk::CHUNK_STATE_UNLOADED, true);
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
// Mark has out of vision and annotate when it started
|
||||||
|
a->second->setState(Chunk::CHUNK_STATE_OUTOFVISION, true);
|
||||||
|
a->second->setState(Chunk::CHUNK_STATE_UNLOADED, false);
|
||||||
|
a->second->unload_timer = glfwGetTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -191,15 +217,13 @@ namespace chunkmanager
|
||||||
|
|
||||||
//std::cout << n->getState(Chunk::CHUNK_STATE_GENERATED) << "\n";
|
//std::cout << n->getState(Chunk::CHUNK_STATE_GENERATED) << "\n";
|
||||||
if(chunks.erase(index)){
|
if(chunks.erase(index)){
|
||||||
|
//n->deleteBuffers();
|
||||||
delete n;
|
delete n;
|
||||||
nUnloaded++;
|
|
||||||
}else
|
}else
|
||||||
std::cout << "failed to free chunk at" << glm::to_string(n->getPosition()) <<
|
std::cout << "failed to free chunk at" << glm::to_string(n->getPosition()) <<
|
||||||
std::endl;
|
std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug::window::set_parameter("update_chunks_freed", nUnloaded);
|
debug::window::set_parameter("update_chunks_freed", nUnloaded);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// uint32_t is fine, since i'm limiting the coordinate to only use up to ten bits (1023). There's actually two spare bits
|
// uint32_t is fine, since i'm limiting the coordinate to only use up to ten bits (1023). There's actually two spare bits
|
||||||
|
@ -212,14 +236,11 @@ namespace chunkmanager
|
||||||
|
|
||||||
void stop() {
|
void stop() {
|
||||||
should_run=false;
|
should_run=false;
|
||||||
update_thread.join();
|
//update_thread.join();
|
||||||
gen_thread.join();
|
gen_thread.join();
|
||||||
mesh_thread.join();
|
mesh_thread.join();
|
||||||
}
|
}
|
||||||
void destroy(){
|
void destroy(){
|
||||||
for(const auto& n : chunks){
|
|
||||||
delete n.second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void blockpick(bool place){
|
void blockpick(bool place){
|
||||||
|
|
|
@ -117,8 +117,6 @@ namespace debug{
|
||||||
std::any_cast<int>(parameters.at("update_chunks_total")));
|
std::any_cast<int>(parameters.at("update_chunks_total")));
|
||||||
ImGui::Text("Chunks freed from memory: %d",
|
ImGui::Text("Chunks freed from memory: %d",
|
||||||
std::any_cast<int>(parameters.at("update_chunks_freed")));
|
std::any_cast<int>(parameters.at("update_chunks_freed")));
|
||||||
ImGui::Text("Bucket size: %d",
|
|
||||||
std::any_cast<int>(parameters.at("update_chunks_bucket")));
|
|
||||||
ImGui::Text("Chunks explored: %d",
|
ImGui::Text("Chunks explored: %d",
|
||||||
std::any_cast<int>(parameters.at("update_chunks_explored")));
|
std::any_cast<int>(parameters.at("update_chunks_explored")));
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,8 @@ int main()
|
||||||
// Render pass
|
// Render pass
|
||||||
renderer::render();
|
renderer::render();
|
||||||
|
|
||||||
|
chunkmanager::primary_thread_update();
|
||||||
|
|
||||||
// Swap buffers to avoid tearing
|
// Swap buffers to avoid tearing
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
122
src/renderer.cpp
122
src/renderer.cpp
|
@ -15,15 +15,14 @@
|
||||||
#include "stb_image_write.h"
|
#include "stb_image_write.h"
|
||||||
|
|
||||||
namespace renderer{
|
namespace renderer{
|
||||||
RenderSet chunks_torender;
|
RenderQueue chunks_torender;
|
||||||
oneapi::tbb::concurrent_vector<Chunk::Chunk*> render_todelete;
|
|
||||||
oneapi::tbb::concurrent_queue<chunkmesher::MeshData*> MeshDataQueue;
|
oneapi::tbb::concurrent_queue<chunkmesher::MeshData*> MeshDataQueue;
|
||||||
|
|
||||||
Shader* theShader, *quadShader;
|
Shader* theShader, *quadShader;
|
||||||
GLuint chunkTexture;
|
GLuint chunkTexture;
|
||||||
|
|
||||||
Shader* getRenderShader() { return theShader; }
|
Shader* getRenderShader() { return theShader; }
|
||||||
RenderSet& getChunksToRender(){ return chunks_torender; }
|
RenderQueue& getChunksToRender(){ return chunks_torender; }
|
||||||
oneapi::tbb::concurrent_queue<chunkmesher::MeshData*>& getMeshDataQueue(){ return MeshDataQueue; }
|
oneapi::tbb::concurrent_queue<chunkmesher::MeshData*>& getMeshDataQueue(){ return MeshDataQueue; }
|
||||||
|
|
||||||
GLuint renderTexFrameBuffer, renderTex, renderTexDepthBuffer, quadVAO, quadVBO;
|
GLuint renderTexFrameBuffer, renderTex, renderTexDepthBuffer, quadVAO, quadVBO;
|
||||||
|
@ -147,102 +146,59 @@ namespace renderer{
|
||||||
chunkmesher::getMeshDataQueue().push(m);
|
chunkmesher::getMeshDataQueue().push(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& c : chunks_torender){
|
Chunk::Chunk* c;
|
||||||
//float dist = glm::distance(c->getPosition(), cameraChunkPos);
|
while(chunks_torender.try_pop(c)){
|
||||||
//if(static_cast<int>(dist) <= RENDER_DISTANCE + 1){
|
if(!c->getState(Chunk::CHUNK_STATE_MESH_LOADED)) continue;
|
||||||
int distx = c->getPosition().x - cameraChunkPos.x;
|
|
||||||
int disty = c->getPosition().y - cameraChunkPos.y;
|
total++;
|
||||||
int distz = c->getPosition().z - cameraChunkPos.z;
|
|
||||||
if(distx >= -RENDER_DISTANCE && distx < RENDER_DISTANCE &&
|
|
||||||
disty >= -RENDER_DISTANCE && disty < RENDER_DISTANCE &&
|
|
||||||
distz >= -RENDER_DISTANCE && distz < RENDER_DISTANCE){
|
|
||||||
if(!c->getState(Chunk::CHUNK_STATE_MESH_LOADED)) continue;
|
|
||||||
|
|
||||||
// reset out-of-vision and unload flags
|
if(c->numVertices > 0)
|
||||||
c->setState(Chunk::CHUNK_STATE_OUTOFVISION, false);
|
{
|
||||||
c->setState(Chunk::CHUNK_STATE_UNLOADED, false);
|
|
||||||
|
|
||||||
if(c->numVertices > 0)
|
// Increase total vertex count
|
||||||
{
|
vertices += c->numVertices;
|
||||||
|
|
||||||
// Increase total vertex count
|
// Perform frustum culling and eventually render
|
||||||
vertices += c->numVertices;
|
glm::vec3 chunk = c->getPosition();
|
||||||
|
glm::vec4 chunkW = glm::vec4(chunk.x*static_cast<float>(CHUNK_SIZE), chunk.y*static_cast<float>(CHUNK_SIZE), chunk.z*static_cast<float>(CHUNK_SIZE),1.0);
|
||||||
|
glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE) * chunk);
|
||||||
|
|
||||||
// Perform frustum culling and eventually render
|
// Check if all the corners of the chunk are outside any of the planes
|
||||||
glm::vec3 chunk = c->getPosition();
|
// TODO (?) implement frustum culling as per (Inigo Quilez)[https://iquilezles.org/articles/frustumcorrect/], and check each
|
||||||
glm::vec4 chunkW = glm::vec4(chunk.x*static_cast<float>(CHUNK_SIZE), chunk.y*static_cast<float>(CHUNK_SIZE), chunk.z*static_cast<float>(CHUNK_SIZE),1.0);
|
// plane against each corner of the chunk
|
||||||
glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE) * chunk);
|
bool out=false;
|
||||||
|
int a{0};
|
||||||
|
for(int p = 0; p < 6; p++){
|
||||||
|
a = 0;
|
||||||
|
for(int i = 0; i < 8; i++) a += glm::dot(frustumPlanes[p], glm::vec4(chunkW.x + ((float)(i & 1))*CHUNK_SIZE, chunkW.y
|
||||||
|
+ ((float)((i & 2) >> 1))*CHUNK_SIZE, chunkW.z + ((float)((i & 4) >> 2))*CHUNK_SIZE, 1.0)) < 0.0;
|
||||||
|
|
||||||
// Check if all the corners of the chunk are outside any of the planes
|
if(a==8){
|
||||||
// TODO (?) implement frustum culling as per (Inigo Quilez)[https://iquilezles.org/articles/frustumcorrect/], and check each
|
out=true;
|
||||||
// plane against each corner of the chunk
|
break;
|
||||||
bool out=false;
|
|
||||||
int a{0};
|
|
||||||
for(int p = 0; p < 6; p++){
|
|
||||||
a = 0;
|
|
||||||
for(int i = 0; i < 8; i++) a += glm::dot(frustumPlanes[p], glm::vec4(chunkW.x + ((float)(i & 1))*CHUNK_SIZE, chunkW.y
|
|
||||||
+ ((float)((i & 2) >> 1))*CHUNK_SIZE, chunkW.z + ((float)((i & 4) >> 2))*CHUNK_SIZE, 1.0)) < 0.0;
|
|
||||||
|
|
||||||
if(a==8){
|
|
||||||
out=true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!out)
|
|
||||||
{
|
|
||||||
theShader->setMat4("model", model);
|
|
||||||
theShader->setMat4("view", theCamera.getView());
|
|
||||||
theShader->setMat4("projection", theCamera.getProjection());
|
|
||||||
|
|
||||||
glBindVertexArray(c->VAO);
|
|
||||||
glDrawArrays(GL_POINTS, 0, c->numVertices);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
toGpu++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
// When the chunk is outside render distance
|
|
||||||
|
|
||||||
/*if(c->getState(Chunk::CHUNK_STATE_OUTOFVISION)){
|
if (!out)
|
||||||
oof++;
|
{
|
||||||
if(glfwGetTime() - c->unload_timer > UNLOAD_TIMEOUT){
|
theShader->setMat4("model", model);
|
||||||
// If chunk was already out and enough time has passed
|
theShader->setMat4("view", theCamera.getView());
|
||||||
// Mark the chunk to be unloaded
|
theShader->setMat4("projection", theCamera.getProjection());
|
||||||
// And mark is to be removed from the render set
|
|
||||||
render_todelete.push_back(c);
|
glBindVertexArray(c->VAO);
|
||||||
}
|
glDrawArrays(GL_POINTS, 0, c->numVertices);
|
||||||
} else{
|
glBindVertexArray(0);
|
||||||
// Mark has out of vision and annotate when it started
|
|
||||||
c->setState(Chunk::CHUNK_STATE_OUTOFVISION, true);
|
toGpu++;
|
||||||
c->setState(Chunk::CHUNK_STATE_UNLOADED, false);
|
}
|
||||||
c->unload_timer = glfwGetTime();
|
|
||||||
}*/
|
|
||||||
c->setState(Chunk::CHUNK_STATE_OUTOFVISION, true);
|
|
||||||
c->setState(Chunk::CHUNK_STATE_UNLOADED, true);
|
|
||||||
//render_todelete.push_back(c);
|
|
||||||
oof++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
total = chunks_torender.size();
|
|
||||||
debug::window::set_parameter("render_chunks_total", total);
|
debug::window::set_parameter("render_chunks_total", total);
|
||||||
debug::window::set_parameter("render_chunks_rendered", toGpu);
|
debug::window::set_parameter("render_chunks_rendered", toGpu);
|
||||||
debug::window::set_parameter("render_chunks_culled", total-toGpu);
|
debug::window::set_parameter("render_chunks_culled", total-toGpu);
|
||||||
debug::window::set_parameter("render_chunks_oof", oof);
|
|
||||||
debug::window::set_parameter("render_chunks_deleted", (int) (render_todelete.size()));
|
|
||||||
debug::window::set_parameter("render_chunks_vertices", vertices);
|
debug::window::set_parameter("render_chunks_vertices", vertices);
|
||||||
|
|
||||||
/*for(auto& c : render_todelete){
|
|
||||||
// we can get away with unsafe erase as access to the container is only done by this
|
|
||||||
// thread
|
|
||||||
chunks_torender.unsafe_erase(c);
|
|
||||||
c->setState(Chunk::CHUNK_STATE_UNLOADED, true);
|
|
||||||
//c->deleteBuffers();
|
|
||||||
}
|
|
||||||
render_todelete.clear();*/
|
|
||||||
|
|
||||||
/* DISPLAY TEXTURE ON A QUAD THAT FILLS THE SCREEN */
|
/* DISPLAY TEXTURE ON A QUAD THAT FILLS THE SCREEN */
|
||||||
// Now to render the quad, with the texture on top
|
// Now to render the quad, with the texture on top
|
||||||
// Switch to the default frame buffer
|
// Switch to the default frame buffer
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "oneapi/tbb/concurrent_hash_map.h"
|
||||||
|
#include "oneapi/tbb/tbb_allocator.h"
|
||||||
|
|
||||||
|
typedef oneapi::tbb::concurrent_hash_map<int, int, oneapi::tbb::tbb_allocator<int>> CTable;
|
||||||
|
|
||||||
|
CTable table;
|
||||||
|
void f(){
|
||||||
|
/*while(table.size() > 0){
|
||||||
|
std::cout << "---------------\n";
|
||||||
|
oneapi::tbb::parallel_for(table.range(), [=](Table::range_type &r){
|
||||||
|
for(Table::const_iterator a = r.begin(); a != r.end(); a++){
|
||||||
|
std::cout << a->first << ": " << a->second << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
std::thread t = std::thread(f);
|
||||||
|
|
||||||
|
//Table::accessor a;
|
||||||
|
/*table.emplace(a, std::make_pair(0, "zero"));
|
||||||
|
table.emplace(a, std::make_pair(1, "one"));
|
||||||
|
table.emplace(a, std::make_pair(2, "two"));
|
||||||
|
table.emplace(a, std::make_pair(3, "three"));
|
||||||
|
table.emplace(a, std::make_pair(4, "four"));
|
||||||
|
table.emplace(a, std::make_pair(5, "five"));*/
|
||||||
|
|
||||||
|
t.join();
|
||||||
|
}
|
Loading…
Reference in New Issue