Skip to content

Commit

Permalink
Make preset transitions use TimeKeeper instead of the system clock
Browse files Browse the repository at this point in the history
  • Loading branch information
kblaschke committed Jun 9, 2024
1 parent 2914d85 commit f94f99d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
6 changes: 3 additions & 3 deletions src/libprojectM/ProjectM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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
{
Expand Down Expand Up @@ -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());
}
}

Expand Down
18 changes: 9 additions & 9 deletions src/libprojectM/Renderer/PresetTransition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()};
Expand All @@ -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;
Expand All @@ -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};
Expand All @@ -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);

Expand Down Expand Up @@ -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
Expand Down
24 changes: 17 additions & 7 deletions src/libprojectM/Renderer/PresetTransition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#include <glm/glm.hpp>

#include <chrono>
#include <random>

namespace libprojectM {
Expand All @@ -22,27 +21,38 @@ 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.
* @param oldPreset A reference to the old (fading out) preset.
* @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",
Expand All @@ -59,9 +69,9 @@ class PresetTransition : public RenderItem
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.

Expand Down

0 comments on commit f94f99d

Please sign in to comment.