diff options
Diffstat (limited to 'src/clientmap.cpp')
-rw-r--r-- | src/clientmap.cpp | 124 |
1 files changed, 67 insertions, 57 deletions
diff --git a/src/clientmap.cpp b/src/clientmap.cpp index 4cae03bf2..21937ac81 100644 --- a/src/clientmap.cpp +++ b/src/clientmap.cpp @@ -296,34 +296,40 @@ struct MeshBufList struct MeshBufListList { - std::vector<MeshBufList> lists; + /*! + * Stores the mesh buffers of the world. + * The array index is the material's layer. + * The vector part groups vertices by material. + */ + std::vector<MeshBufList> lists[MAX_TILE_LAYERS]; void clear() { - lists.clear(); + for (int l = 0; l < MAX_TILE_LAYERS; l++) + lists[l].clear(); } - void add(scene::IMeshBuffer *buf) + void add(scene::IMeshBuffer *buf, u8 layer) { + // Append to the correct layer + std::vector<MeshBufList> &list = lists[layer]; const video::SMaterial &m = buf->getMaterial(); - for(std::vector<MeshBufList>::iterator i = lists.begin(); - i != lists.end(); ++i){ - MeshBufList &l = *i; - + for (std::vector<MeshBufList>::iterator it = list.begin(); it != list.end(); + ++it) { // comparing a full material is quite expensive so we don't do it if // not even first texture is equal - if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture) + if ((*it).m.TextureLayer[0].Texture != m.TextureLayer[0].Texture) continue; - if (l.m == m) { - l.bufs.push_back(buf); + if ((*it).m == m) { + (*it).bufs.push_back(buf); return; } } MeshBufList l; l.m = m; l.bufs.push_back(buf); - lists.push_back(l); + list.push_back(l); } }; @@ -351,7 +357,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) Measuring time is very useful for long delays when the machine is swapping a lot. */ - int time1 = time(0); + time_t time1 = time(0); /* Get animation parameters @@ -434,63 +440,67 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) MapBlockMesh *mapBlockMesh = block->mesh; assert(mapBlockMesh); - scene::IMesh *mesh = mapBlockMesh->getMesh(); - assert(mesh); + for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { + scene::IMesh *mesh = mapBlockMesh->getMesh(layer); + assert(mesh); - u32 c = mesh->getMeshBufferCount(); - for (u32 i = 0; i < c; i++) - { - scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + u32 c = mesh->getMeshBufferCount(); + for (u32 i = 0; i < c; i++) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); - video::SMaterial& material = buf->getMaterial(); - video::IMaterialRenderer* rnd = + video::SMaterial& material = buf->getMaterial(); + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); - bool transparent = (rnd && rnd->isTransparent()); - if (transparent == is_transparent_pass) { - if (buf->getVertexCount() == 0) - errorstream << "Block [" << analyze_block(block) - << "] contains an empty meshbuf" << std::endl; - - material.setFlag(video::EMF_TRILINEAR_FILTER, m_cache_trilinear_filter); - material.setFlag(video::EMF_BILINEAR_FILTER, m_cache_bilinear_filter); - material.setFlag(video::EMF_ANISOTROPIC_FILTER, m_cache_anistropic_filter); - material.setFlag(video::EMF_WIREFRAME, m_control.show_wireframe); - - drawbufs.add(buf); + bool transparent = (rnd && rnd->isTransparent()); + if (transparent == is_transparent_pass) { + if (buf->getVertexCount() == 0) + errorstream << "Block [" << analyze_block(block) + << "] contains an empty meshbuf" << std::endl; + + material.setFlag(video::EMF_TRILINEAR_FILTER, + m_cache_trilinear_filter); + material.setFlag(video::EMF_BILINEAR_FILTER, + m_cache_bilinear_filter); + material.setFlag(video::EMF_ANISOTROPIC_FILTER, + m_cache_anistropic_filter); + material.setFlag(video::EMF_WIREFRAME, + m_control.show_wireframe); + + drawbufs.add(buf, layer); + } } } } } - std::vector<MeshBufList> &lists = drawbufs.lists; - - int timecheck_counter = 0; - for (std::vector<MeshBufList>::iterator i = lists.begin(); - i != lists.end(); ++i) { - timecheck_counter++; - if (timecheck_counter > 50) { - timecheck_counter = 0; - int time2 = time(0); - if (time2 > time1 + 4) { - infostream << "ClientMap::renderMap(): " - "Rendering takes ages, returning." - << std::endl; - return; + // Render all layers in order + for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { + std::vector<MeshBufList> &lists = drawbufs.lists[layer]; + + int timecheck_counter = 0; + for (std::vector<MeshBufList>::iterator it = lists.begin(); it != lists.end(); + ++it) { + timecheck_counter++; + if (timecheck_counter > 50) { + timecheck_counter = 0; + time_t time2 = time(0); + if (time2 > time1 + 4) { + infostream << "ClientMap::renderMap(): " + "Rendering takes ages, returning." + << std::endl; + return; + } } - } - - MeshBufList &list = *i; - driver->setMaterial(list.m); + driver->setMaterial((*it).m); - for (std::vector<scene::IMeshBuffer*>::iterator j = list.bufs.begin(); - j != list.bufs.end(); ++j) { - scene::IMeshBuffer *buf = *j; - driver->drawMeshBuffer(buf); - vertex_count += buf->getVertexCount(); - meshbuffer_count++; + for (std::vector<scene::IMeshBuffer*>::iterator it2 = (*it).bufs.begin(); + it2 != (*it).bufs.end(); ++it2) { + driver->drawMeshBuffer(*it2); + vertex_count += (*it2)->getVertexCount(); + meshbuffer_count++; + } } - } } // ScopeProfiler |