FRC implemented #18

Merged
mushgunAX merged 1 commits from SP3-19-frame-rate-controller into main 2022-09-15 11:34:53 +08:00
4 changed files with 200 additions and 0 deletions

View File

@ -117,6 +117,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" />
@ -201,6 +202,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" />

View File

@ -382,6 +382,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">
@ -583,5 +584,6 @@
<ClCompile Include="src\Tools\SHLogger.cpp">
<Filter>Tools</Filter>
</ClCompile>
<ClCompile Include="src\FRC\SHFramerateController.cpp" />
</ItemGroup>
</Project>

View File

@ -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;
}
}
}

View File

@ -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