Fix render order of overlays (#6008)
authorDániel Juhász <juhdanad@gmail.com>
Wed, 21 Jun 2017 08:47:31 +0000 (08:47 +0000)
committerLoïc Blot <nerzhul@users.noreply.github.com>
Wed, 21 Jun 2017 08:47:31 +0000 (10:47 +0200)
* Fix render order of overlays

* Use C++11 loops

* Fix time_t

src/clientmap.cpp

index 5e88cab45556643db96126272779ef876e6a7156..73d600a7a89973e431c38163f9c500f15bd9f7a5 100644 (file)
@@ -283,49 +283,45 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
 
 struct MeshBufList
 {
-       /*!
-        * Specifies in which layer the list is.
-        * All lists which are in a lower layer are rendered before this list.
-        */
-       u8 layer;
        video::SMaterial m;
        std::vector<scene::IMeshBuffer*> bufs;
 };
 
 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, 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 (MeshBufList &l : list) {
                        // 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)
                                continue;
 
-                       if(l.layer != layer)
-                               continue;
-
                        if (l.m == m) {
                                l.bufs.push_back(buf);
                                return;
                        }
                }
                MeshBufList l;
-               l.layer = layer;
                l.m = m;
                l.bufs.push_back(buf);
-               lists.push_back(l);
+               list.push_back(l);
        }
 };
 
@@ -353,7 +349,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);
+       std::time_t time1 = time(0);
 
        /*
                Get animation parameters
@@ -469,35 +465,32 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                }
        }
 
-       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 (MeshBufList &list : lists) {
+                       timecheck_counter++;
+                       if (timecheck_counter > 50) {
+                               timecheck_counter = 0;
+                               std::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(list.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 (scene::IMeshBuffer *buf : list.bufs) {
+                               driver->drawMeshBuffer(buf);
+                               vertex_count += buf->getVertexCount();
+                               meshbuffer_count++;
+                       }
                }
-
        }
        } // ScopeProfiler