Merge pull request #18 from SHADE-DP/SP3-19-frame-rate-controller
FRC implemented Handles the main game loop, which includes: Handling restarting of scenes by freeing and initializing again Handling changes of scenes by unloading previous scene and loading the next Calling to update on a fixed time basis and reducing the accumulator Calling to render on a variable time basis and adding to the accumulator Measuring of variable time elapsed per frame Ready for integration. Anticipating much change from this implementation during integration.
This commit is contained in:
commit
5ebdf87714
|
@ -123,6 +123,7 @@
|
|||
<ClInclude Include="src\ECS_Base\System\SHSystemManager.h" />
|
||||
<ClInclude Include="src\Engine\SHEngine.h" />
|
||||
<ClInclude Include="src\Filesystem\SHFileSystem.h" />
|
||||
<ClInclude Include="src\FRC\SHFramerateController.h" />
|
||||
<ClInclude Include="src\Graphics\Buffers\SHVkBuffer.h" />
|
||||
<ClInclude Include="src\Graphics\Commands\SHCommandPoolResetMode.h" />
|
||||
<ClInclude Include="src\Graphics\Commands\SHVkCommandBuffer.h" />
|
||||
|
@ -210,6 +211,7 @@
|
|||
<ClCompile Include="src\ECS_Base\System\SHSystemManager.cpp" />
|
||||
<ClCompile Include="src\Engine\SHEngine.cpp" />
|
||||
<ClCompile Include="src\Filesystem\SHFileSystem.cpp" />
|
||||
<ClCompile Include="src\FRC\SHFramerateController.cpp" />
|
||||
<ClCompile Include="src\Graphics\Buffers\SHVkBuffer.cpp" />
|
||||
<ClCompile Include="src\Graphics\Commands\SHVkCommandBuffer.cpp" />
|
||||
<ClCompile Include="src\Graphics\Commands\SHVkCommandPool.cpp" />
|
||||
|
|
|
@ -387,6 +387,7 @@
|
|||
<ClInclude Include="src\Tools\SHUtilities.h">
|
||||
<Filter>Tools</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\FRC\SHFramerateController.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\ECS_Base\Components\SHComponent.cpp">
|
||||
|
@ -591,5 +592,6 @@
|
|||
<ClCompile Include="src\Tools\SHLogger.cpp">
|
||||
<Filter>Tools</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\FRC\SHFramerateController.cpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,134 @@
|
|||
/*********************************************************************
|
||||
* \file SHFramerateController.cpp
|
||||
* \author Ryan Wang Nian Jing
|
||||
* \brief Definition for functions of the framerate controller
|
||||
* Handles changing of scenes and manages loop (timestep, etc.)
|
||||
*
|
||||
* \copyright Copyright (c) 2022 DigiPen Institute of Technology. Reproduction
|
||||
or disclosure of this file or its contents without the prior written
|
||||
consent of DigiPen Institute of Technology is prohibited.
|
||||
*********************************************************************/
|
||||
|
||||
#include <chrono>
|
||||
#include <cassert>
|
||||
#include <SHpch.h>
|
||||
#include "SHFramerateController.h"
|
||||
#include "../Tools/SHLogger.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//Init statics
|
||||
double SHFramerateController::fixedTimestep = 0.01;
|
||||
SHScene* SHFramerateController::previousScene = nullptr;
|
||||
SHScene* SHFramerateController::currentScene = nullptr;
|
||||
SHScene* SHFramerateController::nextScene = nullptr;
|
||||
bool SHFramerateController::toRestart = false;
|
||||
bool SHFramerateController::toQuit = false;
|
||||
|
||||
//Scene manager loop
|
||||
void SHFramerateController::Run(SHScene* firstScene)
|
||||
{
|
||||
if (firstScene == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Do not pass a nullptr as the firstScene");
|
||||
return;
|
||||
}
|
||||
|
||||
//Set quit and restart flags to false
|
||||
toQuit = false;
|
||||
toRestart = false;
|
||||
|
||||
//Set the first scene to run
|
||||
previousScene = firstScene;
|
||||
currentScene = firstScene;
|
||||
nextScene = firstScene;
|
||||
|
||||
while (!toQuit)
|
||||
{
|
||||
if (toRestart)
|
||||
{
|
||||
//Restart current scene
|
||||
currentScene = previousScene;
|
||||
nextScene = previousScene;
|
||||
toRestart = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Move to a new scene
|
||||
currentScene->Load();
|
||||
}
|
||||
|
||||
//Call init function of current scene
|
||||
currentScene->Init();
|
||||
|
||||
//Have an initial value
|
||||
//This frame time will fluctuate
|
||||
//SHOULD be larger than the fixed timestep
|
||||
//TODO this might need to be changed
|
||||
double variableLastFrameTime = fixedTimestep;
|
||||
|
||||
//Time accumulator for meshing between fixed and variable timesteps
|
||||
double accumulator = 0.0;
|
||||
|
||||
//Start state loop
|
||||
while (currentScene == nextScene && !toQuit && !toRestart)
|
||||
{
|
||||
//Use of new STL timing functions
|
||||
//https://en.cppreference.com/w/cpp/chrono
|
||||
std::chrono::duration<double> deltaTime;
|
||||
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
//Whittle down the accumulator by continuously simulating
|
||||
for (; accumulator > fixedTimestep; accumulator -= fixedTimestep)
|
||||
{
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
//TODO change to double
|
||||
currentScene->Update((float)fixedTimestep);
|
||||
}
|
||||
|
||||
//Interpolation
|
||||
//Manage the alpha value well
|
||||
//https://randomascii.wordpress.com/2012/02/13/dont-store-that-in-a-float/
|
||||
//Key points:
|
||||
//1) Any time you add or subtract floats of widely varying
|
||||
// magnitudes, you need to watch for loss of precision
|
||||
//2) Sometimes using double instead of float is the correct
|
||||
// solution, but often a more stable algorithm is more important
|
||||
//3) calcT() should probably use double (to give sufficient
|
||||
// precision after many hours of gameplay)
|
||||
|
||||
//TODO awaiting approval to use this
|
||||
//double alpha = accumulator / fixedTimestep;
|
||||
|
||||
//assert alpha does not go out of range
|
||||
|
||||
currentScene->Render();
|
||||
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
deltaTime = endTime - startTime;
|
||||
variableLastFrameTime = deltaTime.count();
|
||||
|
||||
//Increase accumulator
|
||||
accumulator += variableLastFrameTime;
|
||||
}
|
||||
|
||||
//Free once out of scene loop
|
||||
currentScene->Free();
|
||||
|
||||
//Check if not to restart state
|
||||
//If so, unload
|
||||
if (!toRestart) currentScene->Unload();
|
||||
|
||||
//Shift forward scenes
|
||||
previousScene = currentScene;
|
||||
currentScene = nextScene;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*********************************************************************
|
||||
* \file SHFramerateController.h
|
||||
* \author Ryan Wang Nian Jing
|
||||
* \brief Declaration for the framerate controller
|
||||
* Handles changing of scenes and manages loop (timestep, etc.)
|
||||
*
|
||||
* \copyright Copyright (c) 2022 DigiPen Institute of Technology. Reproduction
|
||||
or disclosure of this file or its contents without the prior written
|
||||
consent of DigiPen Institute of Technology is prohibited.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef SH_FRAMERATECONTROLLER_H
|
||||
#define SH_FRAMERATECONTROLLER_H
|
||||
#pragma once
|
||||
|
||||
#include "../Scene/SHScene.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHFramerateController
|
||||
{
|
||||
private:
|
||||
//scene pointers
|
||||
static SHScene* previousScene;
|
||||
static SHScene* currentScene;
|
||||
static SHScene* nextScene;
|
||||
|
||||
//Flags
|
||||
//Whether the flag has been raised for the game to be quit
|
||||
static bool toQuit;
|
||||
|
||||
//Whether the flag has been raised for the current scene to restart
|
||||
static bool toRestart;
|
||||
|
||||
public:
|
||||
//Fixed timestep value for physics. Default at 1/100th of a second.
|
||||
//Should be lower than the variable refresh rate
|
||||
static double fixedTimestep;
|
||||
|
||||
//Scene Manager Loop
|
||||
//This loop is vital to the game because it runs for as long as the game
|
||||
//runs. Before entering, initialise vital systems for game. After exiting,
|
||||
//free these vital systems before finishing the main() function and
|
||||
//terminating the game
|
||||
//Parameter of firstScene is what scene the game should start with
|
||||
static void Run(SHScene* firstScene);
|
||||
|
||||
//Set the flag to restart the current game scene
|
||||
static inline void RestartScene() { toRestart = true; }
|
||||
|
||||
//Set the flag to halt running of the scene manager and quit the game
|
||||
static inline void QuitGame() { toQuit = true; }
|
||||
|
||||
//Set the next scene to be excuted
|
||||
//This will tell the scene manager to
|
||||
//halt execution of the current scene and prepare
|
||||
//execution of the next
|
||||
static inline void SetNextScene(SHScene* const next) { nextScene = next; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue