diff options
author | Perttu Ahola <celeron55@gmail.com> | 2011-10-18 19:18:01 +0300 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2011-10-18 19:18:01 +0300 |
commit | 4e1055543c01af8f17f1ab2e742922575170251e (patch) | |
tree | 04d84e354853d4dbaf8d9a431384c51511c30f30 | |
parent | 8ead29a302e5bad1f67d2e83c4999c9164c6c03d (diff) | |
download | minetest-4e1055543c01af8f17f1ab2e742922575170251e.tar.gz minetest-4e1055543c01af8f17f1ab2e742922575170251e.tar.bz2 minetest-4e1055543c01af8f17f1ab2e742922575170251e.zip |
Tune map rendering and related diagnostics
-rw-r--r-- | src/camera.cpp | 4 | ||||
-rw-r--r-- | src/game.cpp | 6 | ||||
-rw-r--r-- | src/map.cpp | 73 | ||||
-rw-r--r-- | src/utility.cpp | 2 |
4 files changed, 64 insertions, 21 deletions
diff --git a/src/camera.cpp b/src/camera.cpp index 634a7cc9f..ecb5a17f4 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -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; diff --git a/src/game.cpp b/src/game.cpp index 645d73612..e3380ace4 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -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( diff --git a/src/map.cpp b/src/map.cpp index c7f635feb..febc40ddd 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -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; diff --git a/src/utility.cpp b/src/utility.cpp index 6ce67cb3f..0139281fa 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -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) |