Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 23, 2008, 9:12:59 PM (16 years ago)
Author:
rgrieder
Message:
  • rewrote the time measure in the main loop frame smoothing is gone for good and the fps display updates faster
  • changed "render time ratio" to "tick time in ms" which represents the time necessary to tick() one frame that's saying a lot more to me
File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/hud/src/orxonox/Orxonox.cc

    r1618 r1621  
    103103    //, auMan_(0)
    104104    , timer_(0)
    105     // turn on frame smoothing by setting a value different from 0
    106     , frameSmoothingTime_(0.0f)
    107     //orxonoxHUD_(0)
    108105    , bAbort_(false)
    109106    , timefactor_(1.0f)
     
    438435
    439436
    440     // Contains the times of recently fired events
    441     // eventTimes[4] is the list for the times required for the fps counter
    442     std::deque<unsigned long> eventTimes[3];
    443     // Clear event times
    444     for (int i = 0; i < 3; ++i)
    445       eventTimes[i].clear();
    446 
    447437    // use the ogre timer class to measure time.
    448438    if (!timer_)
    449439      timer_ = new Ogre::Timer();
     440
     441    unsigned long frameCount = 0;
     442   
     443    const unsigned long refreshTime = 3000000;
     444    unsigned long refreshStartTime = 0;
     445    unsigned long tickTime = 0;
     446    unsigned long oldFrameCount = 0;
     447
     448    unsigned long timeBeforeTick = 0;
     449    unsigned long timeBeforeTickOld = 0;
     450    unsigned long timeAfterTick = 0;
     451
     452    COUT(3) << "Orxonox: Starting the main loop." << std::endl;
     453
    450454    timer_->reset();
    451 
    452     float renderTime = 0.0f;
    453     float frameTime = 0.0f;
    454 //    clock_t time = 0;
    455 
    456     COUT(3) << "Orxonox: Starting the main loop." << std::endl;
    457455    while (!bAbort_)
    458456    {
    459457      // get current time
    460       unsigned long now = timer_->getMilliseconds();
    461 
    462       // create an event to pass to the frameStarted method in ogre
    463       Ogre::FrameEvent evt;
    464       evt.timeSinceLastEvent = calculateEventTime(now, eventTimes[0]);
    465       evt.timeSinceLastFrame = calculateEventTime(now, eventTimes[1]);
    466       frameTime += evt.timeSinceLastFrame;
    467 
    468       // OverlayGroup::getHUD().setTime(now);
    469       if (mode_ != DEDICATED && frameTime > 0.4f)
    470       {
    471         GraphicsEngine::getSingleton().setAverageRTR(renderTime / frameTime);
    472         frameTime = 0.0f;
    473         renderTime = 0.0f;
    474       }
    475 
    476       // tick the core
    477       Core::tick((float)evt.timeSinceLastFrame);
     458      timeBeforeTickOld = timeBeforeTick;
     459      timeBeforeTick    = timer_->getMicroseconds();
     460      float dt = (timeBeforeTick - timeBeforeTickOld) / 1000000.0;
     461
     462
     463      // tick the core (needs real time for input and tcl thread management)
     464      Core::tick(dt);
     465
    478466      // Call those objects that need the real time
    479467      for (Iterator<TickableReal> it = ObjectList<TickableReal>::start(); it; ++it)
    480         it->tick((float)evt.timeSinceLastFrame);
     468        it->tick(dt);
    481469      // Call the scene objects
    482470      for (Iterator<Tickable> it = ObjectList<Tickable>::start(); it; ++it)
    483         it->tick((float)evt.timeSinceLastFrame * this->timefactor_);
    484       //AudioManager::tick();
     471        it->tick(dt * this->timefactor_);
     472
     473      // call server/client with normal dt
    485474      if (client_g)
    486         client_g->tick((float)evt.timeSinceLastFrame);
     475        client_g->tick(dt * this->timefactor_);
    487476      if (server_g)
    488         server_g->tick((float)evt.timeSinceLastFrame);
     477        server_g->tick(dt * this->timefactor_);
     478
     479
     480      // get current time once again
     481      timeAfterTick = timer_->getMicroseconds();
     482
     483      tickTime += timeAfterTick - timeBeforeTick;
     484      if (timeAfterTick > refreshStartTime + refreshTime)
     485      {
     486        GraphicsEngine::getSingleton().setAverageTickTime(
     487            (float)tickTime * 0.001 / (frameCount - oldFrameCount));
     488        GraphicsEngine::getSingleton().setAverageFramesPerSecond(
     489            (float)(frameCount - oldFrameCount) / (timeAfterTick - refreshStartTime) * 1000000.0);
     490        oldFrameCount = frameCount;
     491        tickTime = 0;
     492        refreshStartTime = timeAfterTick;
     493      }
     494
    489495
    490496      // don't forget to call _fireFrameStarted in ogre to make sure
    491497      // everything goes smoothly
     498      Ogre::FrameEvent evt;
     499      evt.timeSinceLastFrame = dt;
     500      evt.timeSinceLastEvent = dt; // note: same time, but shouldn't matter anyway
    492501      ogreRoot._fireFrameStarted(evt);
    493 
    494       // get current time
    495       now = timer_->getMilliseconds();
    496       calculateEventTime(now, eventTimes[2]);
    497502
    498503      if (mode_ != DEDICATED)
     
    501506        // This calls the WindowEventListener objects.
    502507        Ogre::WindowEventUtilities::messagePump();
     508        // make sure the window stays active even when not focused
     509        // (probably only necessary on windows)
    503510        GraphicsEngine::getSingleton().setWindowActivity(true);
    504511
     
    507514      }
    508515
    509       // get current time
    510       now = timer_->getMilliseconds();
    511 
    512       // create an event to pass to the frameEnded method in ogre
    513       evt.timeSinceLastEvent = calculateEventTime(now, eventTimes[0]);
    514       renderTime += calculateEventTime(now, eventTimes[2]);
    515 
    516516      // again, just to be sure ogre works fine
    517       ogreRoot._fireFrameEnded(evt);
    518       //msleep(500);
     517      ogreRoot._fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
     518
     519      ++frameCount;
    519520    }
    520521
     
    526527    return true;
    527528  }
    528 
    529   /**
    530     Method for calculating the average time between recently fired events.
    531     Code directly taken from OgreRoot.cc
    532     @param now The current time in ms.
    533     @param type The type of event to be considered.
    534   */
    535   float Orxonox::calculateEventTime(unsigned long now, std::deque<unsigned long> &times)
    536   {
    537     // Calculate the average time passed between events of the given type
    538     // during the last frameSmoothingTime_ seconds.
    539 
    540     times.push_back(now);
    541 
    542     if(times.size() == 1)
    543       return 0;
    544 
    545     // Times up to frameSmoothingTime_ seconds old should be kept
    546     unsigned long discardThreshold = (unsigned long)(frameSmoothingTime_ * 1000.0f);
    547 
    548     // Find the oldest time to keep
    549     std::deque<unsigned long>::iterator it  = times.begin();
    550     // We need at least two times
    551     std::deque<unsigned long>::iterator end = times.end() - 2;
    552 
    553     while(it != end)
    554     {
    555       if (now - *it > discardThreshold)
    556         ++it;
    557       else
    558         break;
    559     }
    560 
    561     // Remove old times
    562     times.erase(times.begin(), it);
    563 
    564     return (float)(times.back() - times.front()) / ((times.size() - 1) * 1000);
    565   }
    566529}
Note: See TracChangeset for help on using the changeset viewer.