Make preset transitions use TimeKeeper instead of the system clock

This commit is contained in:
Kai Blaschke
2024-06-09 13:04:01 +02:00
parent 2914d85ec3
commit f94f99d888
3 changed files with 29 additions and 19 deletions

View File

@ -150,7 +150,7 @@ void ProjectM::RenderFrame(uint32_t targetFramebufferObject /*= 0*/)
if (m_transition != nullptr && m_transitioningPreset != nullptr)
{
if (m_transition->IsDone())
if (m_transition->IsDone(m_timeKeeper->GetFrameTime()))
{
m_activePreset = std::move(m_transitioningPreset);
m_transitioningPreset.reset();
@ -170,7 +170,7 @@ void ProjectM::RenderFrame(uint32_t targetFramebufferObject /*= 0*/)
if (m_transition != nullptr && m_transitioningPreset != nullptr)
{
m_transition->Draw(*m_activePreset, *m_transitioningPreset, renderContext, audioData);
m_transition->Draw(*m_activePreset, *m_transitioningPreset, renderContext, audioData, m_timeKeeper->GetFrameTime());
}
else
{
@ -254,7 +254,7 @@ void ProjectM::StartPresetTransition(std::unique_ptr<Preset>&& preset, bool hard
{
m_transitioningPreset = std::move(preset);
m_timeKeeper->StartSmoothing();
m_transition = std::make_unique<Renderer::PresetTransition>(m_transitionShaderManager->RandomTransition(), m_softCutDuration);
m_transition = std::make_unique<Renderer::PresetTransition>(m_transitionShaderManager->RandomTransition(), m_softCutDuration, m_timeKeeper->GetFrameTime());
}
}

View File

@ -11,9 +11,10 @@ namespace Renderer {
constexpr double PI = 3.14159265358979323846;
PresetTransition::PresetTransition(const std::shared_ptr<Shader>& transitionShader, double durationSeconds)
PresetTransition::PresetTransition(const std::shared_ptr<Shader>& transitionShader, double durationSeconds, double transitionStartTime)
: m_transitionShader(transitionShader)
, m_durationSeconds(durationSeconds)
, m_transitionStartTime(transitionStartTime)
{
std::mt19937 rand32(m_randomDevice());
m_staticRandomValues = {rand32(), rand32(), rand32(), rand32()};
@ -33,19 +34,18 @@ void PresetTransition::InitVertexAttrib()
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points.data(), GL_STATIC_DRAW);
}
auto PresetTransition::IsDone() const -> bool
auto PresetTransition::IsDone(double currentFrameTime) const -> bool
{
const auto secondsSinceStart = std::chrono::duration<double>(std::chrono::system_clock::now() - m_transitionStartTime).count();
const auto secondsSinceStart = currentFrameTime - m_transitionStartTime;
return m_durationSeconds <= 0.0 || secondsSinceStart >= m_durationSeconds;
}
void PresetTransition::Draw(const Preset& oldPreset,
const Preset& newPreset,
const RenderContext& context,
const libprojectM::Audio::FrameAudioData& audioData)
const libprojectM::Audio::FrameAudioData& audioData,
double currentFrameTime)
{
using namespace std::chrono_literals;
if (m_transitionShader == nullptr)
{
return;
@ -54,7 +54,7 @@ void PresetTransition::Draw(const Preset& oldPreset,
std::mt19937 rand32(m_randomDevice());
// Calculate progress values
const auto secondsSinceStart = std::chrono::duration<double>(std::chrono::system_clock::now() - m_transitionStartTime).count();
const auto secondsSinceStart = currentFrameTime - m_transitionStartTime;
// If duration is zero,
double linearProgress{1.0};
@ -81,7 +81,7 @@ void PresetTransition::Draw(const Preset& oldPreset,
m_durationSeconds});
m_transitionShader->SetUniformFloat2("timeParams", {secondsSinceStart,
std::chrono::duration<float>(std::chrono::system_clock::now() - m_lastFrameTime).count()});
currentFrameTime - m_lastFrameTime});
m_transitionShader->SetUniformInt4("iRandStatic", m_staticRandomValues);
@ -130,7 +130,7 @@ void PresetTransition::Draw(const Preset& oldPreset,
Shader::Unbind();
// Update last frame time.
m_lastFrameTime = std::chrono::system_clock::now();
m_lastFrameTime = currentFrameTime;
}
} // namespace Renderer

View File

@ -8,7 +8,6 @@
#include <glm/glm.hpp>
#include <chrono>
#include <random>
namespace libprojectM {
@ -22,15 +21,24 @@ class PresetTransition : public RenderItem
public:
PresetTransition() = delete;
explicit PresetTransition(const std::shared_ptr<Shader>& transitionShader, double durationSeconds);
/**
* Constructor.
* @param transitionShader The transition shader program.
* @param durationSeconds Transition duration in seconds.
* @param transitionStartTime The time in seconds since start of projectM.
*/
explicit PresetTransition(const std::shared_ptr<Shader>& transitionShader,
double durationSeconds,
double transitionStartTime);
void InitVertexAttrib() override;
/**
* @brief Returns true if the transition is done.
* @param currentFrameTime The time in seconds since start of the current frame.
* @return false if the transition is still in progress, true if it's done.
*/
auto IsDone() const -> bool;
auto IsDone(double currentFrameTime) const -> bool;
/**
* @brief Updates the transition variables and renders the shader quad to the current FBO.
@ -38,11 +46,13 @@ public:
* @param newPreset A reference to the new (fading in) preset.
* @param context The rendering context used to render the presets.
* @param audioData Current audio data and beat detection values.
* @param currentFrameTime The time in seconds since start of the current frame.
*/
void Draw(const Preset& oldPreset,
const Preset& newPreset,
const RenderContext& context,
const libprojectM::Audio::FrameAudioData& audioData);
const libprojectM::Audio::FrameAudioData& audioData,
double currentFrameTime);
private:
std::vector<std::string> m_noiseTextureNames{"noise_lq",
@ -59,9 +69,9 @@ private:
std::shared_ptr<Shader> m_transitionShader; //!< The compiled shader used for this transition.
std::shared_ptr<Sampler> m_presetSampler{std::make_shared<Sampler>(GL_CLAMP_TO_EDGE, GL_LINEAR)}; //!< Sampler for preset textures. Uses bilinear interpolation and no repeat.
double m_durationSeconds{3.0}; //!< Transition duration in seconds.
std::chrono::time_point<std::chrono::system_clock> m_transitionStartTime{std::chrono::system_clock::now()}; //!< Start time of this transition. Duration is measured from this point.
std::chrono::time_point<std::chrono::system_clock> m_lastFrameTime{std::chrono::system_clock::now()}; //!< Time when the previous frame was rendered.
double m_durationSeconds{3.0}; //!< Transition duration in seconds.
double m_transitionStartTime{}; //!< Start time of this transition. Duration is measured from this point.
double m_lastFrameTime{}; //!< Time when the previous frame was rendered.
glm::ivec4 m_staticRandomValues{}; //!< Four random integers, remaining static during the whole transition.