Tune map rendering and related diagnostics

This commit is contained in:
Perttu Ahola 2011-10-18 19:18:01 +03:00
parent 8ead29a302
commit 4e1055543c
4 changed files with 64 additions and 21 deletions

@ -364,7 +364,9 @@ void Camera::updateViewingRange(f32 frametime_in)
//dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl; //dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl;
// If needed frametime change is small, just return // 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; //dstream<<"ignoring small wanted_frametime_change"<<std::endl;
return; return;

@ -1983,8 +1983,10 @@ void the_game(
range = draw_control.wanted_range*BS + MAP_BLOCKSIZE*BS*1.5; range = draw_control.wanted_range*BS + MAP_BLOCKSIZE*BS*1.5;
if(draw_control.range_all) if(draw_control.range_all)
range = 100000*BS; range = 100000*BS;
if(range < 50*BS) /*if(range < 50*BS)
range = range * 0.5 + 25*BS; range = range * 0.5 + 25*BS;*/
// Move the invisible limit a bit further
//range *= 1.2;
} }
driver->setFog( driver->setFog(

@ -3657,14 +3657,15 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d; v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d;
// Take a fair amount as we will be dropping more out later // 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( v3s16 p_blocks_min(
p_nodes_min.X / MAP_BLOCKSIZE - 2, p_nodes_min.X / MAP_BLOCKSIZE - 2,
p_nodes_min.Y / MAP_BLOCKSIZE - 2, p_nodes_min.Y / MAP_BLOCKSIZE - 2,
p_nodes_min.Z / MAP_BLOCKSIZE - 2); p_nodes_min.Z / MAP_BLOCKSIZE - 2);
v3s16 p_blocks_max( v3s16 p_blocks_max(
p_nodes_max.X / MAP_BLOCKSIZE + 1, p_nodes_max.X / MAP_BLOCKSIZE + 0,
p_nodes_max.Y / MAP_BLOCKSIZE + 1, p_nodes_max.Y / MAP_BLOCKSIZE + 0,
p_nodes_max.Z / MAP_BLOCKSIZE + 1); p_nodes_max.Z / MAP_BLOCKSIZE + 0);
u32 vertex_count = 0; u32 vertex_count = 0;
u32 meshbuffer_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 // For limiting number of mesh updates per frame
u32 mesh_update_count = 0; 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; u32 blocks_would_have_drawn = 0;
// Blocks that were drawn and had a mesh
u32 blocks_drawn = 0; 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; int timecheck_counter = 0;
core::map<v2s16, MapSector*>::Iterator si; core::map<v2s16, MapSector*>::Iterator si;
@ -3747,6 +3759,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
d - 0.5*BS*MAP_BLOCKSIZE > range) d - 0.5*BS*MAP_BLOCKSIZE > range)
continue;*/ continue;*/
blocks_in_range++;
#if 1 #if 1
/* /*
Update expired mesh (used for day/night change) Update expired mesh (used for day/night change)
@ -3764,9 +3778,11 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
// Mesh has not been expired and there is no mesh: // Mesh has not been expired and there is no mesh:
// block has no content // block has no content
if(block->mesh == NULL && mesh_expired == false) if(block->mesh == NULL && mesh_expired == false){
blocks_in_range_without_mesh++;
continue; continue;
} }
}
f32 faraway = BS*50; f32 faraway = BS*50;
//f32 faraway = m_control.wanted_range * BS; //f32 faraway = m_control.wanted_range * BS;
@ -3804,8 +3820,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
scene::SMesh *mesh = block->mesh; scene::SMesh *mesh = block->mesh;
if(mesh == NULL) if(mesh == NULL){
blocks_in_range_without_mesh++;
continue; continue;
}
blocks_would_have_drawn++; blocks_would_have_drawn++;
if(blocks_drawn >= m_control.wanted_max_blocks if(blocks_drawn >= m_control.wanted_max_blocks
@ -3817,8 +3835,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
sector_blocks_drawn++; sector_blocks_drawn++;
u32 c = mesh->getMeshBufferCount(); u32 c = mesh->getMeshBufferCount();
meshbuffer_count += c; bool stuff_actually_drawn = false;
for(u32 i=0; i<c; i++) for(u32 i=0; i<c; i++)
{ {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(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. // Render transparent on transparent pass and likewise.
if(transparent == is_transparent_pass) 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 This *shouldn't* hurt too much because Irrlicht
doesn't change opengl textures if the old doesn't change opengl textures if the old
material is set again. material has the same texture.
*/ */
driver->setMaterial(buf->getMaterial()); driver->setMaterial(buf->getMaterial());
driver->drawMeshBuffer(buf); driver->drawMeshBuffer(buf);
vertex_count += buf->getVertexCount(); vertex_count += buf->getVertexCount();
meshbuffer_count++;
stuff_actually_drawn = true;
} }
} }
if(stuff_actually_drawn)
blocks_had_pass_meshbuf++;
else
blocks_without_stuff++;
} }
} // foreach sectorblocks } // 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){ if(pass == scene::ESNRP_SOLID){
g_profiler->avg("CM: blocks drawn on solid pass", blocks_drawn); g_profiler->avg(prefix+"blocks in range", blocks_in_range);
g_profiler->avg("CM: vertices drawn on solid pass", vertex_count); if(blocks_in_range != 0)
if(blocks_drawn != 0) g_profiler->avg(prefix+"blocks in range without mesh (frac)",
g_profiler->avg("CM: solid meshbuffers per block", (float)blocks_in_range_without_mesh/blocks_in_range);
(float)meshbuffer_count / (float)blocks_drawn); g_profiler->avg(prefix+"blocks drawn", 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);
} }
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_drawn = blocks_drawn;
m_control.blocks_would_have_drawn = blocks_would_have_drawn; m_control.blocks_would_have_drawn = blocks_would_have_drawn;

@ -236,7 +236,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
// If block is (nearly) touching the camera, don't // If block is (nearly) touching the camera, don't
// bother validating further (that is, render it anyway) // 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 // Cosine of the angle between the camera direction
// and the block direction (camera_dir is an unit vector) // and the block direction (camera_dir is an unit vector)