I have built up a procedural terrain creator using voxels. The terrain is divived in chunks, those chunks are created in a seperate, detached thread. Since I did this, there is no lag anymore because they get built in background. Everything works fine for about 2000 chunks (32*32*64), but then i get an "abort() has been called" error. The debug information looks just fine.
Enough words, here is some code:
In the Manager-constructor the Thread is initialized:
try{
m_creatorThread1 = std::thread(&ChunkManager::CreateChunk, this);
m_creatorThread1.detach();
}
catch (...){
m_work = false;
m_creatorThread1.join();
throw;
}
This is the function the thread executes:
void ChunkManager::CreateChunk(){
while (m_work){
if (!m_buildQ.empty()){
Position tmp = m_buildQ.back();
m_buildQ.pop_back();
Chunk* ctmp = new Chunk(this->m_terrain, tmp);
m_mutex.lock();
m_chunks.push_back(ctmp);
m_mutex.unlock();
}
}
}
the function that feeds the m_buildQ:
void ChunkManager::GenerateChunks(Position position){
for (int i = position.x - CHUNK_PRLD_X; i < position.x + CHUNK_PRLD_X; i++){
for (int j = position.z - CHUNK_PRLD_Z; j < position.z + CHUNK_PRLD_Z; j++){
Position chunkPos;
chunkPos.x = i *CHUNK_SIZE; chunkPos.z = j *CHUNK_SIZE;
if (!IsUsed(chunkPos)){
m_used.push_back(chunkPos);
m_buildQ.push_back(chunkPos);
}
}
}
}
and finally the function that renders the chunks:
void ChunkManager::Render(){
m_mutex.lock();
for (vector<Chunk*>::iterator it = m_chunks.begin(); it != m_chunks.end(); ++it){
if (m_Frustum->CheckSphere((*it)->getPosition().x +CHUNK_SIZE/2, CHUNK_HEIGHT / 2, (*it)->getPosition().z + CHUNK_SIZE/2, CHUNK_SIZE*1.3f)){
if ((*it)->hasGraphics())
(*it)->Render();
else{
(*it)->InitializeGraphics(OpenGL);
}
}
}
m_mutex.unlock();
}
In short: Every frame there is a check if new chunks need to be loaded, if so, GenerateChunks feeds the m_buildQ vector with positions of chunks that got to be loaded. The thread runs in background and creates new chunks if something is in the buildQ. because of openGL-reasons, the VAO and VBO dont get initialized in the thread but in the renderer if needed.
As I said, everything works fine until I've spent some time in the application and thousands of chunks were created. Can anyone find the mistake?
Here some things of the debug:
m_chunks: size= 1392
it-ptr: points on valid chunk
thread: hnd:0x00000264 id: 0
if someone needs more debug information just tell me.
User contributions licensed under CC BY-SA 3.0