我使用体素构建了一个程序性地形创建器。地形以块为单位进行分割,这些块以单独的分离线程创建。自从我这样做以来,没有任何延迟,因为它们是在后台构建的。一切都适用于大约2000个块(32 * 32 * 64),但后来我得到一个“abort()被称为”错误。调试信息看起来很好。
够了,这里有一些代码:
在Manager构造函数中初始化Thread:
try{
m_creatorThread1 = std::thread(&ChunkManager::CreateChunk, this);
m_creatorThread1.detach();
}
catch (...){
m_work = false;
m_creatorThread1.join();
throw;
}
这是线程执行的功能:
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();
}
}
}
提供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);
}
}
}
}
最后是渲染块的函数:
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();
}
简而言之:每一帧都检查是否需要加载新的块,如果是,GenerateChunks会向m_buildQ向量提供需要加载的块的位置。线程在后台运行,如果buildQ中存在某些内容,则创建新的块。由于openGL原因,VAO和VBO不会在线程中初始化,但如果需要则在渲染器中初始化。
正如我所说,一切正常,直到我在应用程序中花了一些时间并创建了数千个块。有人能找到错误吗?
这里有一些调试内容:
m_chunks: size= 1392
it-ptr: points on valid chunk
thread: hnd:0x00000264 id: 0
如果有人需要更多调试信息,请告诉我。