Tune map rendering and related diagnostics
authorPerttu Ahola <celeron55@gmail.com>
Tue, 18 Oct 2011 16:18:01 +0000 (19:18 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 18 Oct 2011 16:18:01 +0000 (19:18 +0300)
src/camera.cpp
src/game.cpp
src/map.cpp
src/utility.cpp

index 634a7cc9f7f63eb5ab3023e454a11a9ca1e071ba..ecb5a17f40c5ab47b1b1e977d6f621485a8c2bb9 100644 (file)
@@ -364,7 +364,9 @@ void Camera::updateViewingRange(f32 frametime_in)
        //dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl;
 
        // If needed frametime change is small, just return
-       if (fabs(wanted_frametime_change) < m_wanted_frametime*0.4)
+       // This value was 0.4 for many months until 2011-10-18 by c55;
+       // Let's see how this works out.
+       if (fabs(wanted_frametime_change) < m_wanted_frametime*0.25)
        {
                //dstream<<"ignoring small wanted_frametime_change"<<std::endl;
                return;
index 645d736125d6a755a0155bdd3141d6476f4d092b..e3380ace401da06211dceab384d822c2ca63dee0 100644 (file)
@@ -1983,8 +1983,10 @@ void the_game(
                                range = draw_control.wanted_range*BS + MAP_BLOCKSIZE*BS*1.5;
                                if(draw_control.range_all)
                                        range = 100000*BS;
-                               if(range < 50*BS)
-                                       range = range * 0.5 + 25*BS;
+                               /*if(range < 50*BS)
+                                       range = range * 0.5 + 25*BS;*/
+                               // Move the invisible limit a bit further
+                               //range *= 1.2;
                        }
 
                        driver->setFog(
index c7f635feb6cd64b9a64b0a2da934de5da029f116..febc40ddd98321affbdb33a9d2d9387c7366e1f6 100644 (file)
@@ -3657,14 +3657,15 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
        v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d;
 
        // Take a fair amount as we will be dropping more out later
+       // Umm... these additions are a bit strange but they are needed.
        v3s16 p_blocks_min(
                        p_nodes_min.X / MAP_BLOCKSIZE - 2,
                        p_nodes_min.Y / MAP_BLOCKSIZE - 2,
                        p_nodes_min.Z / MAP_BLOCKSIZE - 2);
        v3s16 p_blocks_max(
-                       p_nodes_max.X / MAP_BLOCKSIZE + 1,
-                       p_nodes_max.Y / MAP_BLOCKSIZE + 1,
-                       p_nodes_max.Z / MAP_BLOCKSIZE + 1);
+                       p_nodes_max.X / MAP_BLOCKSIZE + 0,
+                       p_nodes_max.Y / MAP_BLOCKSIZE + 0,
+                       p_nodes_max.Z / MAP_BLOCKSIZE + 0);
        
        u32 vertex_count = 0;
        u32 meshbuffer_count = 0;
@@ -3672,8 +3673,19 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
        // For limiting number of mesh updates per frame
        u32 mesh_update_count = 0;
        
+       // Number of blocks in rendering range
+       u32 blocks_in_range = 0;
+       // Number of blocks in rendering range but don't have a mesh
+       u32 blocks_in_range_without_mesh = 0;
+       // Blocks that had mesh that would have been drawn according to
+       // rendering range (if max blocks limit didn't kick in)
        u32 blocks_would_have_drawn = 0;
+       // Blocks that were drawn and had a mesh
        u32 blocks_drawn = 0;
+       // Blocks which had a corresponding meshbuffer for this pass
+       u32 blocks_had_pass_meshbuf = 0;
+       // Blocks from which stuff was actually drawn
+       u32 blocks_without_stuff = 0;
 
        int timecheck_counter = 0;
        core::map<v2s16, MapSector*>::Iterator si;
@@ -3746,6 +3758,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                        /*if(m_control.range_all == false &&
                                        d - 0.5*BS*MAP_BLOCKSIZE > range)
                                continue;*/
+                       
+                       blocks_in_range++;
 
 #if 1
                        /*
@@ -3764,8 +3778,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
 
                                // Mesh has not been expired and there is no mesh:
                                // block has no content
-                               if(block->mesh == NULL && mesh_expired == false)
+                               if(block->mesh == NULL && mesh_expired == false){
+                                       blocks_in_range_without_mesh++;
                                        continue;
+                               }
                        }
 
                        f32 faraway = BS*50;
@@ -3803,9 +3819,11 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                                JMutexAutoLock lock(block->mesh_mutex);
 
                                scene::SMesh *mesh = block->mesh;
-
-                               if(mesh == NULL)
+                               
+                               if(mesh == NULL){
+                                       blocks_in_range_without_mesh++;
                                        continue;
+                               }
                                
                                blocks_would_have_drawn++;
                                if(blocks_drawn >= m_control.wanted_max_blocks
@@ -3817,8 +3835,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                                sector_blocks_drawn++;
 
                                u32 c = mesh->getMeshBufferCount();
-                               meshbuffer_count += c;
-
+                               bool stuff_actually_drawn = false;
                                for(u32 i=0; i<c; i++)
                                {
                                        scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
@@ -3829,16 +3846,25 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                                        // Render transparent on transparent pass and likewise.
                                        if(transparent == is_transparent_pass)
                                        {
+                                               if(buf->getVertexCount() == 0)
+                                                       errorstream<<"Block ["<<analyze_block(block)
+                                                                       <<"] contains an empty meshbuf"<<std::endl;
                                                /*
                                                        This *shouldn't* hurt too much because Irrlicht
                                                        doesn't change opengl textures if the old
-                                                       material is set again.
+                                                       material has the same texture.
                                                */
                                                driver->setMaterial(buf->getMaterial());
                                                driver->drawMeshBuffer(buf);
                                                vertex_count += buf->getVertexCount();
+                                               meshbuffer_count++;
+                                               stuff_actually_drawn = true;
                                        }
                                }
+                               if(stuff_actually_drawn)
+                                       blocks_had_pass_meshbuf++;
+                               else
+                                       blocks_without_stuff++;
                        }
                } // foreach sectorblocks
 
@@ -3848,17 +3874,30 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                }
        }
        
+       std::string prefix = "CM: ";
+
+       // Log only on solid pass because values are the same
        if(pass == scene::ESNRP_SOLID){
-               g_profiler->avg("CM: blocks drawn on solid pass", blocks_drawn);
-               g_profiler->avg("CM: vertices drawn on solid pass", vertex_count);
-               if(blocks_drawn != 0)
-                       g_profiler->avg("CM: solid meshbuffers per block",
-                                       (float)meshbuffer_count / (float)blocks_drawn);
-       } else {
-               g_profiler->avg("CM: blocks drawn on transparent pass", blocks_drawn);
-               g_profiler->avg("CM: vertices drawn on transparent pass", vertex_count);
+               g_profiler->avg(prefix+"blocks in range", blocks_in_range);
+               if(blocks_in_range != 0)
+                       g_profiler->avg(prefix+"blocks in range without mesh (frac)",
+                                       (float)blocks_in_range_without_mesh/blocks_in_range);
+               g_profiler->avg(prefix+"blocks drawn", blocks_drawn);
        }
        
+       if(pass == scene::ESNRP_SOLID)
+               prefix = "CM: solid: ";
+       else
+               prefix = "CM: transparent: ";
+
+       g_profiler->avg(prefix+"vertices drawn", vertex_count);
+       if(blocks_had_pass_meshbuf != 0)
+               g_profiler->avg(prefix+"meshbuffers per block",
+                               (float)meshbuffer_count / (float)blocks_had_pass_meshbuf);
+       if(blocks_drawn != 0)
+               g_profiler->avg(prefix+"empty blocks (frac)",
+                               (float)blocks_without_stuff / blocks_drawn);
+
        m_control.blocks_drawn = blocks_drawn;
        m_control.blocks_would_have_drawn = blocks_would_have_drawn;
 
index 6ce67cb3fa2a1c903e415dead99c6896975e8f5e..0139281fadeae59f8397db5deff75cb8d2b21997 100644 (file)
@@ -236,7 +236,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
        
        // If block is (nearly) touching the camera, don't
        // bother validating further (that is, render it anyway)
-       if(d > block_max_radius * 1.5)
+       if(d > block_max_radius)
        {
                // Cosine of the angle between the camera direction
                // and the block direction (camera_dir is an unit vector)