Added a phase and optional iteration index/max-iteration to

renderGUI to allow for smooth display of progress bar.
This commit is contained in:
hiker 2018-12-06 09:58:29 +11:00
parent 0582c4018d
commit f6e758a9d6
7 changed files with 97 additions and 48 deletions

View File

@ -531,17 +531,38 @@ void MainLoop::run()
} // run
// ----------------------------------------------------------------------------
void MainLoop::renderGUI()
/** Renders the GUI. This function is used during loading a track to get a
* responsive GUI, and allow GUI animations (like a progress bar) to be
* shown.
* \param phase An integer indicated a phase. The maximum number of phases
* is used to show a progress bar.
* \param loop_index If the call is from a loop, the current loop index.
* \param loop_size The number of loop iterations. Used to smooth update
* e.g. a progress bar.
*/
void MainLoop::renderGUI(int phase, int loop_index, int loop_size)
{
// TODO: Rendering past 7000 causes the minimap to not work
// on higher graphical settings
//if(phase>7000) return;
uint64_t now = StkTime::getRealTimeMs();
float dt = (now - m_curr_time)/1000.0f;
// TODO: re-enable: Don't render if there frame rate would be too high (which would
// slow down loading time).
// if(dt<1.0/30.0f) return;
m_curr_time = now;
Log::verbose("mainloop", "Rendergui t %llu dt %f",
now, dt);
// TODO: remove debug output
Log::verbose("mainloop", "Rendergui t %llu dt %f phase %d index %d / %d",
now, dt, phase, loop_index, loop_size);
irr_driver->update(dt, /*is_loading*/true);
input_manager->update(dt);
GUIEngine::update(dt);
//TODO: remove debug output
uint64_t now2 = StkTime::getRealTimeMs();
Log::verbose("mainloop", " duration t %llu dt %llu", now, now2-now);
} // renderGUI
/* EOF */

View File

@ -58,7 +58,7 @@ public:
void requestAbort() { m_request_abort = true; }
void setThrottleFPS(bool throttle) { m_throttle_fps = throttle; }
void setAllowLargeDt(bool enable) { m_allow_large_dt = enable; }
void renderGUI();
void renderGUI(int phase, int loop_index=-1, int loop_size=-1);
// ------------------------------------------------------------------------
/** Returns true if STK is to be stoppe. */
bool isAborted() const { return m_abort; }

View File

@ -169,9 +169,9 @@ void World::init()
// mode class, which would not have been constructed at the time that this
// constructor is called, so the wrong race gui would be created.
createRaceGUI();
main_loop->renderGUI();
main_loop->renderGUI(1000);
RewindManager::create();
main_loop->renderGUI();
main_loop->renderGUI(1100);
// Grab the track file
Track *track = track_manager->getTrack(race_manager->getTrackName());
Scripting::ScriptEngine::getInstance<Scripting::ScriptEngine>();
@ -185,10 +185,10 @@ void World::init()
std::string script_path = track->getTrackFile("scripting.as");
Scripting::ScriptEngine::getInstance()->loadScript(script_path, true);
main_loop->renderGUI();
main_loop->renderGUI(1200);
// Create the physics
Physics::getInstance<Physics>();
main_loop->renderGUI();
main_loop->renderGUI(1300);
unsigned int num_karts = race_manager->getNumberOfKarts();
//assert(num_karts > 0);
@ -197,12 +197,14 @@ void World::init()
// This also defines the static Track::getCurrentTrack function.
track->loadTrackModel(race_manager->getReverseTrack());
main_loop->renderGUI(6998);
if (gk > 0)
{
ReplayPlay::get()->load();
for (unsigned int k = 0; k < gk; k++)
m_karts.push_back(ReplayPlay::get()->getGhostKart(k));
}
main_loop->renderGUI(6999);
// Assign team of AIs for team mode before createKart
if (hasTeam())
@ -210,6 +212,7 @@ void World::init()
for(unsigned int i=0; i<num_karts; i++)
{
main_loop->renderGUI(7000, i, num_karts);
if (race_manager->getKartType(i) == RaceManager::KT_GHOST) continue;
std::string kart_ident = history->replayHistory()
? history->getKartIdent(i)
@ -233,15 +236,15 @@ void World::init()
m_karts.push_back(new_kart);
} // for i
main_loop->renderGUI();
main_loop->renderGUI(7050);
// Load other custom models if needed
loadCustomModels();
main_loop->renderGUI();
main_loop->renderGUI(7100);
// Must be called after all karts are created
m_race_gui->init();
powerup_manager->computeWeightsForRace(race_manager->getNumberOfKarts());
main_loop->renderGUI();
main_loop->renderGUI(7200);
if (UserConfigParams::m_particles_effects > 1)
{
Weather::getInstance<Weather>(); // create Weather instance
@ -260,7 +263,7 @@ void World::init()
} // if server with graphics of is watching replay
} // if getNumCameras()==0
initTeamArrows();
main_loop->renderGUI();
main_loop->renderGUI(7300);
} // init
//-----------------------------------------------------------------------------

View File

@ -19,6 +19,7 @@
#include "physics/triangle_mesh.hpp"
#include "config/stk_config.hpp"
#include "main_loop.hpp"
#include "physics/physics.hpp"
#include "utils/constants.hpp"
#include "utils/time.hpp"
@ -187,6 +188,8 @@ void TriangleMesh::createPhysicalBody(float friction,
// We need the collision shape, but not the collision object (since
// this will be created when the dynamics body is anyway).
createCollisionShape(/*create_collision_object*/false, serializedBhv);
main_loop->renderGUI(5583);
btTransform startTransform;
startTransform.setIdentity();
m_motion_state = new btDefaultMotionState(startTransform);

View File

@ -473,7 +473,7 @@ void RaceManager::startNew(bool from_overworld)
void RaceManager::startNextRace()
{
main_loop->renderGUI();
main_loop->renderGUI(0);
// Uncomment to debug audio leaks
// sfx_manager->dump();
@ -540,7 +540,7 @@ void RaceManager::startNextRace()
}
}
main_loop->renderGUI();
main_loop->renderGUI(100);
// the constructor assigns this object to the global
// variable world. Admittedly a bit ugly, but simplifies
@ -579,21 +579,21 @@ void RaceManager::startNextRace()
Log::error("RaceManager", "Could not create given race mode.");
assert(0);
}
main_loop->renderGUI();
main_loop->renderGUI(200);
// A second constructor phase is necessary in order to be able to
// call functions which are overwritten (otherwise polymorphism
// will fail and the results will be incorrect). Also in init() functions
// can be called that use World::getWorld().
World::getWorld()->init();
main_loop->renderGUI();
main_loop->renderGUI(8000);
// Now initialise all values that need to be reset from race to race
// Calling this here reduces code duplication in init and restartRace()
// functions.
World::getWorld()->reset();
irr_driver->onLoadWorld();
main_loop->renderGUI();
main_loop->renderGUI(8100);
// Save the current score and set last time to zero. This is necessary
// if someone presses esc after finishing a gp, and selects restart:
@ -605,7 +605,7 @@ void RaceManager::startNextRace()
m_kart_status[i].m_last_score = m_kart_status[i].m_score;
m_kart_status[i].m_last_time = 0;
}
main_loop->renderGUI();
main_loop->renderGUI(8200);
} // startNextRace
//-----------------------------------------------------------------------------

View File

@ -21,6 +21,7 @@
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "main_loop.hpp"
#include "modes/world.hpp"
#include "race/race_manager.hpp"
#include "tracks/check_lap.hpp"
@ -103,6 +104,8 @@ void DriveGraph::load(const std::string &quad_file_name,
// Each quad is part of the graph exactly once now.
for (unsigned int i = 0; i < quad->getNumNodes(); i++)
{
main_loop->renderGUI(3331, i, quad->getNumNodes());
const XMLNode *xml_node = quad->getNode(i);
if (!(xml_node->getName() == "quad" || xml_node->getName() == "height-testing"))
{
@ -184,6 +187,8 @@ void DriveGraph::load(const std::string &quad_file_name,
// the node definitions, before the edges can be set.
for(unsigned int node_index=0; node_index<xml->getNumNodes(); node_index++)
{
main_loop->renderGUI(3333, node_index, xml->getNumNodes());
const XMLNode *xml_node = xml->getNode(node_index);
// Load the definition of edges between the graph nodes:
// -----------------------------------------------------

View File

@ -850,6 +850,8 @@ void Track::createPhysicsModel(unsigned int main_track_count)
// (like invisible walls).
for (unsigned int i = 0; i<m_static_physics_only_nodes.size(); i++)
{
main_loop->renderGUI(5550, i, m_static_physics_only_nodes.size());
convertTrackToBullet(m_static_physics_only_nodes[i]);
if (UserConfigParams::m_physics_debug &&
m_static_physics_only_nodes[i]->getType() == scene::ESNT_MESH)
@ -869,11 +871,13 @@ void Track::createPhysicsModel(unsigned int main_track_count)
else
irr_driver->removeNode(m_static_physics_only_nodes[i]);
}
main_loop->renderGUI(5560);
if (!UserConfigParams::m_physics_debug)
m_static_physics_only_nodes.clear();
for (unsigned int i = 0; i<m_object_physics_only_nodes.size(); i++)
{
main_loop->renderGUI(5565, i, m_static_physics_only_nodes.size());
convertTrackToBullet(m_object_physics_only_nodes[i]);
m_object_physics_only_nodes[i]->setVisible(false);
m_object_physics_only_nodes[i]->grab();
@ -884,11 +888,16 @@ void Track::createPhysicsModel(unsigned int main_track_count)
m_gfx_effect_mesh->removeAll();
for(unsigned int i=main_track_count; i<m_all_nodes.size(); i++)
{
main_loop->renderGUI(5570, i, m_all_nodes.size());
convertTrackToBullet(m_all_nodes[i]);
uploadNodeVertexBuffer(m_all_nodes[i]);
}
main_loop->renderGUI(5580);
m_track_mesh->createPhysicalBody(m_friction);
main_loop->renderGUI(5585);
m_gfx_effect_mesh->createCollisionShape();
main_loop->renderGUI(5590);
} // createPhysicsModel
// -----------------------------------------------------------------------------
@ -1218,7 +1227,7 @@ bool Track::loadMainTrack(const XMLNode &root)
// m_all_cached_meshes.
m_all_cached_meshes.push_back(tangent_mesh);
irr_driver->grabAllTextures(tangent_mesh);
main_loop->renderGUI();
main_loop->renderGUI(4000);
#ifdef DEBUG
std::string debug_name=model_name+" (main track, octtree)";
@ -1253,7 +1262,7 @@ bool Track::loadMainTrack(const XMLNode &root)
{
for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++)
{
main_loop->renderGUI();
main_loop->renderGUI(4100, i, lod_xml_node->getNumNodes());
const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
@ -1262,11 +1271,11 @@ bool Track::loadMainTrack(const XMLNode &root)
}
}
}
main_loop->renderGUI();
main_loop->renderGUI(4200);
for (unsigned int i=0; i<track_node->getNumNodes(); i++)
{
main_loop->renderGUI();
main_loop->renderGUI(4300, i, track_node->getNumNodes());
const XMLNode *n=track_node->getNode(i);
// Animated textures have already been handled
@ -1437,9 +1446,11 @@ bool Track::loadMainTrack(const XMLNode &root)
// This will (at this stage) only convert the main track model.
for(unsigned int i=0; i<m_all_nodes.size(); i++)
{
main_loop->renderGUI(4350, i, m_all_nodes.size());
convertTrackToBullet(m_all_nodes[i]);
main_loop->renderGUI(4360, i, m_all_nodes.size());
uploadNodeVertexBuffer(m_all_nodes[i]);
main_loop->renderGUI();
main_loop->renderGUI(4400, i, m_all_nodes.size());
}
// Free the tangent (track mesh) after converting to physics
@ -1454,7 +1465,7 @@ bool Track::loadMainTrack(const XMLNode &root)
m_gfx_effect_mesh->createCollisionShape();
scene_node->setMaterialFlag(video::EMF_LIGHTING, true);
scene_node->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
main_loop->renderGUI();
main_loop->renderGUI(4500);
return true;
} // loadMainTrack
@ -1749,7 +1760,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
{
reverse_track = false;
}
main_loop->renderGUI();
main_loop->renderGUI(3000);
CheckManager::create();
assert(m_all_cached_meshes.size()==0);
if(UserConfigParams::logMemory())
@ -1789,7 +1800,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
// Add the track directory to the texture search path
file_manager->pushTextureSearchPath(m_root, unique_id);
file_manager->pushModelSearchPath(m_root);
main_loop->renderGUI();
main_loop->renderGUI(3100);
#ifndef SERVER_ONLY
if (CVS->isGLSL())
@ -1797,7 +1808,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
SP::SPShaderManager::get()->loadSPShaders(m_root);
}
#endif
main_loop->renderGUI();
main_loop->renderGUI(3200);
// First read the temporary materials.xml file if it exists
try
@ -1817,7 +1828,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
// no temporary materials.xml file, ignore
(void)e;
}
main_loop->renderGUI();
main_loop->renderGUI(3300);
// Start building the scene graph
// Soccer field with navmesh requires it
@ -1859,11 +1870,13 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
}
} // for i<root->getNumNodes()
}
main_loop->renderGUI(3320);
if (!m_is_arena && !m_is_soccer && !m_is_cutscene)
loadDriveGraph(mode_id, reverse_track);
else if ((m_is_arena || m_is_soccer) && !m_is_cutscene && m_has_navmesh)
loadArenaGraph(*root);
main_loop->renderGUI(3340);
if (NetworkConfig::get()->isNetworking())
NetworkItemManager::create();
@ -1873,6 +1886,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
ItemManager::updateRandomSeed((uint32_t)StkTime::getTimeSinceEpoch());
ItemManager::create();
}
main_loop->renderGUI(3360);
// Set the default start positions. Node that later the default
// positions can still be overwritten.
@ -1906,7 +1920,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
sidewards_distance,
upwards_distance);
}
main_loop->renderGUI();
main_loop->renderGUI(3400);
// we need to check for fog before loading the main track model
if (const XMLNode *node = root->getNode("sun"))
@ -1923,7 +1937,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
node->get("fog-start-height", &m_fog_height_start);
node->get("fog-end-height", &m_fog_height_end);
}
main_loop->renderGUI();
main_loop->renderGUI(3500);
#ifndef SERVER_ONLY
if (!ProfileWorld::isNoGraphics() && CVS->isGLSL() && m_use_fog)
@ -1950,7 +1964,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
SP::resetEmptyFogColor();
}
#endif
main_loop->renderGUI();
main_loop->renderGUI(3600);
if (const XMLNode *node = root->getNode("lightshaft"))
{
@ -1961,12 +1975,12 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
}
loadMainTrack(*root);
main_loop->renderGUI();
main_loop->renderGUI(4700);
unsigned int main_track_count = (unsigned int)m_all_nodes.size();
ModelDefinitionLoader model_def_loader(this);
main_loop->renderGUI();
main_loop->renderGUI(4800);
// Load LOD groups
const XMLNode *lod_xml_node = root->getNode("lod");
@ -1974,7 +1988,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
{
for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++)
{
main_loop->renderGUI();
main_loop->renderGUI(4900, i, lod_xml_node->getNumNodes());
const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
@ -1985,7 +1999,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
}
loadObjects(root, path, model_def_loader, true, NULL, NULL);
main_loop->renderGUI();
main_loop->renderGUI(5000);
// Correct the parenting of meta library
for (auto& p : m_meta_library)
@ -1998,19 +2012,19 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
meta_ln->getNode()->setParent(ln->getNode());
recursiveUpdatePosition(meta_ln->getNode());
recursiveUpdatePhysics(p.second->getChildren());
main_loop->renderGUI();
main_loop->renderGUI(5050);
}
model_def_loader.cleanLibraryNodesAfterLoad();
main_loop->renderGUI();
main_loop->renderGUI(5100);
Scripting::ScriptEngine::getInstance()->compileLoadedScripts();
main_loop->renderGUI();
main_loop->renderGUI(5200);
// Init all track objects
m_track_object_manager->init();
main_loop->renderGUI();
main_loop->renderGUI(5300);
// ---- Fog
@ -2043,6 +2057,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
m_sky_sphere_percent);
for(unsigned int i=0; i<node->getMaterialCount(); i++)
{
main_loop->renderGUI(5350, i, node->getMaterialCount());
video::SMaterial &irrMaterial=node->getMaterial(i);
for(unsigned int j=0; j<video::MATERIAL_MAX_TEXTURES; j++)
{
@ -2067,7 +2083,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
irr_driver->setClearbackBufferColor(m_sky_color);
}
#endif
main_loop->renderGUI();
main_loop->renderGUI(5400);
// ---- Set ambient color
m_ambient_color = m_default_ambient_color;
@ -2107,10 +2123,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
m_sun->grab();
}
#endif
main_loop->renderGUI();
main_loop->renderGUI(5500);
createPhysicsModel(main_track_count);
main_loop->renderGUI();
main_loop->renderGUI(5600);
freeCachedMeshVertexBuffer();
@ -2131,7 +2147,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
}
} // for i<root->getNumNodes()
}
main_loop->renderGUI();
main_loop->renderGUI(5700);
if (m_is_ctf &&
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
@ -2147,7 +2163,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
} // for i<root->getNumNodes()
}
delete root;
main_loop->renderGUI();
main_loop->renderGUI(5800);
if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isClient())
@ -2155,7 +2171,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
static_cast<NetworkItemManager*>(NetworkItemManager::get())
->initClientConfirmState();
}
main_loop->renderGUI();
main_loop->renderGUI(5900);
if (UserConfigParams::m_track_debug && Graph::get() && !m_is_cutscene)
Graph::get()->createDebugMesh();
@ -2184,7 +2200,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
{
DriveGraph::get()->computeChecklineRequirements();
}
main_loop->renderGUI();
main_loop->renderGUI(6000);
EasterEggHunt *easter_world = dynamic_cast<EasterEggHunt*>(world);
if(easter_world)
@ -2192,7 +2208,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
std::string dir = StringUtils::getPath(m_filename);
easter_world->readData(dir+"/easter_eggs.xml");
}
main_loop->renderGUI();
main_loop->renderGUI(6100);
STKTexManager::getInstance()->unsetTextureErrorMessage();
#ifndef SERVER_ONLY
@ -2227,6 +2243,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path,
for (unsigned int i = 0; i < node_count; i++)
{
main_loop->renderGUI(4950, i, node_count);
const XMLNode *node = root->getNode(i);
const std::string name = node->getName();
// The track object was already converted before the loop, and the