void frts::MainLoop::start(const SharedManagerImplPtr& shared) const { assert(shared != nullptr); Frame::time runTime = fromMilliseconds(0); Frame::time currentTime = highResTime(); Frame::time accumulator = fromMilliseconds(0); Frame::ticks tick = 0; Frame::time deltaTimeDebug = deltaTime + fromMilliseconds(1); std::string maxFrameTimeWarnMsg = R"(Frame %3% exceeded frame time of %1%ms with max frame time of %2%ms.)"; std::string frameTimeWarnMsg = R"(Frame %3% exceeded frame time of %1%ms with delta frame time of %2%ms.)"; auto frame = makeFrame(deltaTime, tick, runTime); shared->setFrame(frame); while (!shared->isQuitApplication()) { Frame::time newTime = highResTime(); // Limit frame time to a maximum to avoid spiral of death. Frame::time frameTime = newTime - currentTime; if (frameTime > maxFrameTime) { auto msg = boost::format(maxFrameTimeWarnMsg) % std::chrono::duration_cast<std::chrono::milliseconds>(frameTime).count() % std::chrono::duration_cast<std::chrono::milliseconds>(maxFrameTime).count() % frame->getNumber(); shared->getLog()->info(logModule, msg.str()); frameTime = maxFrameTime; } // For debugging. else if (frameTime > deltaTimeDebug) { auto msg = boost::format(frameTimeWarnMsg) % std::chrono::duration_cast<std::chrono::milliseconds>(frameTime).count() % std::chrono::duration_cast<std::chrono::milliseconds>(deltaTime).count() % frame->getNumber(); shared->getLog()->debug(logModule, msg.str()); } currentTime = newTime; accumulator += frameTime; while (accumulator >= deltaTime) { frame = makeFrame(deltaTime, tick, runTime); shared->setFrame(frame); update(shared); accumulator -= deltaTime; runTime += deltaTime; tick += 1; } render(shared); } }
//Main loop void Main::run() { int frames = 0, frameAtBase = 0; double baseTime = highResTime(); while (true) { if(render && glfwWindowShouldClose(window)) //process close only if rendering break; if(logging) profileLog<<"Frame "<<frames<<endl; double time = highResTime(); if(render) { glfwPollEvents(); //Set camera for raycaster camera.update(); rayCaster.setCamera(camera); } //Simulate one step using OpenCL simulation->step(); if(render) { //Get image from raycaster, pass it to OpenGL rayCaster.shoot(); g.updateTexture(rayCaster.getTexture()); // Render the raycasted texture on a quad g.renderTexture(); } double delta; delta = highResTime() - time; //current time delta framesLog<<frames<<" "<<delta<<endl; //frame time log /* Limit framerate to targetFPS (turned off, let autotuner handle) while(true) { delta = highResTime() - time; double rest = (1.0/targetFPS) - delta; if(rest <= 0) break; usleep(rest / 1000000); //sleep off the rest of the frame } */ //A major change is that of the resolution, in which case //the raycaster also needs to know. bool changed = tuner.report(delta); if(render && changed) { rayCaster.setN(simulation->getN()); rayCaster.setVolume(simulation->getOutputVolume()); } //FPS counter - update once a second frames++; if(time - baseTime > 1) { cout<<"FPS "<<frames - frameAtBase<<endl; if(logging) { framesLog<<"FPS "<<frames - frameAtBase<<endl; framesLog.Commit(); profileLog.Commit(); } frameAtBase = frames; baseTime = highResTime(); } } }