Skip to content

Commit

Permalink
Introduce smooth transitions between views. ACHTUNG: Need to rebuild …
Browse files Browse the repository at this point in the history
…as assets were modified.
  • Loading branch information
scheerchristian committed May 4, 2024
1 parent 2182cd7 commit c92bf0a
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 153 deletions.
34 changes: 18 additions & 16 deletions assets/openGLShaderPrograms/blob-5.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ uniform float iTime;
uniform float iModelMix;
uniform float iAudioLevel1;
uniform float iAudioLevel2;
uniform float iFadeValue;
out vec4 fragColor;

vec2 calcKnobPosUV(vec2 knobPos, vec2 uv, float aspect) {
Expand Down Expand Up @@ -90,27 +91,27 @@ vec3 colorCircle(float circle, float circleEdge, float audioLevel, vec2 coordDis
colorCircle = vec3(circle*0.1f, circle*0.3f, circle);
colorCircle = colorCircle*0.8 + colorCircle*(vec3(audioLevel));
colorCircleEdge = vec3(0.321*circleEdge, 0.17*circleEdge, circleEdge*0.9);

// pulse the color
colorCircle.b = colorCircle.b - noiseFloat(coordDistorted*0.3f, time*0.2f)*0.3f;
colorCircleEdge.r = colorCircleEdge.r + colorCircleEdge.r * noiseFloat(coordDistorted*0.6f, time)*1.5f;
colorCircle.r = colorCircle.r + colorCircle.r * (noiseFloat(coordDistorted*0.23, time)*0.22);
colorCircle.g = colorCircle.g - colorCircle.g * noiseFloat(coordDistorted*0.3f, time+0.5f);
}

else if (index == 1) {
// initial colorset
colorCircle = vec3(circle, circle*0.3f, circle*0.5f);
colorCircle = colorCircle*0.8 + colorCircle*(vec3(audioLevel));
colorCircleEdge = vec3(circleEdge*0.9f, circleEdge*0.17f, circleEdge*0.321f);

// pulse the color
colorCircle.r = colorCircle.r - noiseFloat(coordDistorted*0.3f, time*0.2f)*0.3f;
colorCircleEdge.b = colorCircleEdge.b + colorCircleEdge.b * noiseFloat(coordDistorted*0.6f, time)*1.5f;
colorCircle.b = colorCircle.b + colorCircle.b * (noiseFloat(coordDistorted*0.23, time)*0.5f);
colorCircle.g = colorCircle.g - colorCircle.g * noiseFloat(coordDistorted*0.3f, time+0.5f);
}

// add both colors
return colorCircle + colorCircleEdge;
}
Expand All @@ -128,48 +129,49 @@ void main()

float displayScaleFactor = iDisplayScaleFactor;
vec2 resolution = iResolution.xy * displayScaleFactor;

// Shift the coordinates, since the OpenGl component is bigger than the XY-Pad
// make the zero point at the left/button corner of the XY-Pad (dont forget the displayScaleFactor!)
// Also keep in mind Juce counts from the top left corner and openGL from buttom left
fragCoord = vec2(fragCoord.x - (120*displayScaleFactor), fragCoord.y - (54*displayScaleFactor));

// center origin point
vec2 coord = fragCoord/resolution.xy * 2.f - 1.f;

// Adjust to Aspect Ratio
float aspect = resolution.x / resolution.y;
coord.x *= aspect;

vec2 coord_1 = calcKnobPosUV(knobPos1, coord, aspect);
vec2 coord_2 = calcKnobPosUV(knobPos2, coord, aspect);

// calculate radius for both models
float[2] radius = calculateRadius(modelMix);

// Distort coordinate systems
vec2 coordDistorted_1 = coord_1 + noiseCoord(coord_1, iTime) * 0.1;
vec2 coordDistorted_2 = coord_2 + noiseCoord(coord_2, iTime) * 0.1;

// Calculate inner circle
float circle_1 = circle(coordDistorted_1, radius[0]);
float circle_2 = circle(coordDistorted_2, radius[1]);

// Calculate outer circle
float circleEdge_1 = circleEdge(coordDistorted_1, circle_1, radius[0]);
float circleEdge_2 = circleEdge(coordDistorted_2, circle_2, radius[1]);

// Color circles
vec3 colorCircle_1 = colorCircle(circle_1, circleEdge_1, audioLevel_1, coordDistorted_1, time, 0);
vec3 colorCircle_2 = colorCircle(circle_2, circleEdge_2, audioLevel_2, coordDistorted_2, time + 14.f, 1);

// Add both circles together
vec3 color = vec3(max((colorCircle_1 + colorCircle_2), 0.));
color = min(color, 1.);

// adding Background
color = iBackgroundColor + color;

color = iBackgroundColor + (color * iFadeValue);


// for calibration
// if (fragCoord.x / displayScaleFactor < 500.f && fragCoord.x >= 0.f) {
// if (fragCoord.y / displayScaleFactor < 500.f && fragCoord.y >= 0.f) {
Expand Down
Binary file modified assets/pictures/signal_flow_control.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
229 changes: 114 additions & 115 deletions assets/svg/signal_flow_control.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 31 additions & 11 deletions source/PluginEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor (AudioPluginAud
{
if (newState)
{
advancedParameterControl.setVisible(true);
parameterControl.setVisible(false);
transientViewer.setVisible(false);
componentAnimator->fadeIn(&advancedParameterControl, fadeTime);
componentAnimator->fadeOut(&parameterControl, fadeTime);
componentAnimator->fadeOut(&transientViewer, fadeTime);
}
else
{
advancedParameterControl.setVisible(false);
parameterControl.setVisible(true);
transientViewer.setVisible(true);
componentAnimator->fadeOut(&advancedParameterControl, fadeTime);
componentAnimator->fadeIn(&parameterControl, fadeTime);
componentAnimator->fadeIn(&transientViewer, fadeTime);
}
};

Expand Down Expand Up @@ -59,7 +59,7 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor (AudioPluginAud
openGLBackground->externalModelLoaded(modelID, modelName);
};

//setResizable(false, false);
setResizable(false, false);
// dirty work around to make the blobs appear correctly from the beginning
auto fadeParam = parameters.getParameter(PluginParameters::FADE_ID.getParamID());
auto fadeStatus = fadeParam->getValue();
Expand All @@ -76,13 +76,32 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor (AudioPluginAud

headerComponent.onScyloneButtonClick = [this](bool newState)
{
transientViewer.setVisible(!newState);
parameterControl.setVisible(!newState);
headerComponent.detailButton.setEnabled(!newState);
if (newState) {
componentAnimator->fadeOut(&transientViewer, fadeTime);
if (headerComponent.detailButton.getToggleState()) {
componentAnimator->fadeOut(&advancedParameterControl, fadeTime);
}
else {
componentAnimator->fadeOut(&parameterControl, fadeTime);
}
}
else {
if (headerComponent.detailButton.getToggleState()) {
componentAnimator->fadeIn(&advancedParameterControl, fadeTime);
}
else {
componentAnimator->fadeIn(&parameterControl, fadeTime);
componentAnimator->fadeIn(&transientViewer, fadeTime);
}
}

openGLBackground->showSignalFlowChart(newState);
resized();
repaint();

headerComponent.detailButton.setEnabled(!newState);
};

componentAnimator = std::make_unique<juce::ComponentAnimator>();
}

AudioPluginAudioProcessorEditor::~AudioPluginAudioProcessorEditor()
Expand Down Expand Up @@ -119,6 +138,7 @@ void AudioPluginAudioProcessorEditor::resized()
if (openGLBackground->isSignalFlowChartVisible()) {
auto window = getLocalBounds();
window.removeFromTop(headerSection.getHeight() + 20);
window.removeFromBottom(footerComponent.getHeight() + 20);
openGLBackground->setBounds(window);
}
else
Expand Down
3 changes: 3 additions & 0 deletions source/PluginEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,8 @@ class AudioPluginAudioProcessorEditor : public juce::AudioProcessorEditor, priv
juce::Component** parameterControlComponents;
juce::Component** advancedParameterControlComponents;
juce::Component** headerComponents;

std::unique_ptr<juce::ComponentAnimator> componentAnimator;
int fadeTime = 200;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginAudioProcessorEditor)
};
59 changes: 50 additions & 9 deletions source/ui/CustomComponents/OpenGLBackground/OpenGLBackground.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ OpenGLBackground::OpenGLBackground(juce::AudioProcessorValueTreeState& parameter
labels.sharp.setComponentID("sharp");
labels.smooth.setComponentID("smooth");
labels.attack.setComponentID("attack");

componentAnimator = std::make_unique<juce::ComponentAnimator>();
}

OpenGLBackground::~OpenGLBackground()
Expand Down Expand Up @@ -99,7 +101,7 @@ void OpenGLBackground::openGLContextClosing()
void OpenGLBackground::renderOpenGL()
{
jassert (juce::OpenGLHelpers::isContextActive());

// Scale viewport
const float renderingScale = (float) openGLContext.getRenderingScale();
juce::gl::glViewport (0, 0, juce::roundToInt (renderingScale * getWidth()), juce::roundToInt (renderingScale * getHeight()));
Expand Down Expand Up @@ -132,6 +134,8 @@ void OpenGLBackground::renderOpenGL()
openGLContext.extensions.glBindVertexArray (VAO);
juce::gl::glDrawArrays (juce::gl::GL_TRIANGLES, 0, (int) vertices.size());
openGLContext.extensions.glBindVertexArray (0);

if (fadeValue) fadeValue->set(fadeValue_juce);
}

// JUCE Component Callbacks ====================================================
Expand Down Expand Up @@ -184,7 +188,7 @@ void OpenGLBackground::compileOpenGLShaderProgram()
knobPos2.disconnectFromShaderProgram();
audioLevel1.disconnectFromShaderProgram();
audioLevel2.disconnectFromShaderProgram();

fadeValue.disconnectFromShaderProgram();
shaderProgram.reset (shaderProgramAttempt.release());

resolution.connectToShaderProgram (openGLContext, *shaderProgram);
Expand All @@ -196,6 +200,7 @@ void OpenGLBackground::compileOpenGLShaderProgram()
knobPos2.connectToShaderProgram(openGLContext, *shaderProgram);
audioLevel1.connectToShaderProgram(openGLContext, *shaderProgram);
audioLevel2.connectToShaderProgram(openGLContext, *shaderProgram);
fadeValue.connectToShaderProgram(openGLContext, *shaderProgram);

openGLStatusText = "GLSL: v" + juce::String (juce::OpenGLShaderProgram::getLanguageVersion(), 2);

Expand Down Expand Up @@ -228,7 +233,6 @@ void OpenGLBackground::xyModelMixChanged(float newModelMix) {

void OpenGLBackground::SetJuceLabels()
{

auto font = CustomFontLookAndFeel::getCustomFont().withHeight(19.0f);

labels.sharp.setText("Sharp", juce::dontSendNotification);
Expand Down Expand Up @@ -261,16 +265,53 @@ XYPad* OpenGLBackground::getXYPad() {
}

void OpenGLBackground::showSignalFlowChart(bool newState) {
signalFlowChart->setVisible(newState);
xyPad.setVisible(!newState);
labels.attack.setVisible(!newState);
labels.smooth.setVisible(!newState);
labels.sharp.setVisible(!newState);
labels.sustain.setVisible(!newState);

if (newState) {
componentAnimator->fadeOut(&xyPad, fadeTime);
componentAnimator->fadeOut(&labels.attack, fadeTime);
componentAnimator->fadeOut(&labels.smooth, fadeTime);
componentAnimator->fadeOut(&labels.sharp, fadeTime);
componentAnimator->fadeOut(&labels.sustain, fadeTime);
areBlobsVisible = false;
startTimer(fadeBlobTimmerRate);
componentAnimator->fadeIn(signalFlowChart.get(), fadeTime*10);
}
else {
componentAnimator->fadeIn(&xyPad, fadeTime);
componentAnimator->fadeIn(&labels.attack, fadeTime);
componentAnimator->fadeIn(&labels.smooth, fadeTime);
componentAnimator->fadeIn(&labels.sharp, fadeTime);
componentAnimator->fadeIn(&labels.sustain, fadeTime);
areBlobsVisible = true;
startTimer(fadeBlobTimmerRate);
componentAnimator->fadeOut(signalFlowChart.get(), fadeTime*10);
}
repaint();
}

bool OpenGLBackground::isSignalFlowChartVisible() {
return signalFlowChart->isVisible();
}

void OpenGLBackground::timerCallback() {
float increment = (float)fadeTime / ((float(fadeBlobTimmerRate)*100));

timerCounter += 1;
if (timerCounter * fadeBlobTimmerRate > fadeTime)
{
stopTimer();
timerCounter = 0;
if (areBlobsVisible) {
fadeValue_juce = 1.f;
}
else
fadeValue_juce = 0.f;
}
else {
if (areBlobsVisible)
fadeValue_juce += increment;
else
fadeValue_juce -= increment;
}
}

15 changes: 14 additions & 1 deletion source/ui/CustomComponents/OpenGLBackground/OpenGLBackground.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ struct KnobPos {
*/
class OpenGLBackground : public juce::Component,
private juce::OpenGLRenderer,
private juce::AsyncUpdater
private juce::AsyncUpdater,
public juce::Timer
{
public:

Expand Down Expand Up @@ -70,6 +71,9 @@ private juce::AsyncUpdater

void showSignalFlowChart(bool newState);
bool isSignalFlowChartVisible();

void timerCallback() override;

private:

/** Attempts to compile the OpenGL program at runtime and setup OpenGL variables. */
Expand All @@ -88,6 +92,7 @@ private juce::AsyncUpdater
OpenGLUtil::UniformWrapper modelMix {"iModelMix"};
OpenGLUtil::UniformWrapper audioLevel1 {"iAudioLevel1"};
OpenGLUtil::UniformWrapper audioLevel2 {"iAudioLevel2"};
OpenGLUtil::UniformWrapper fadeValue {"iFadeValue"};
// Fade aus ValueTreeState
// On Off pro source

Expand All @@ -99,6 +104,7 @@ private juce::AsyncUpdater
juce::Colour backgroundColor_juce;
float audioLevel1_juce;
float audioLevel2_juce;
float fadeValue_juce = 1.f;
AudioPluginAudioProcessor& processorRef;

// GUI overlay status text
Expand All @@ -118,6 +124,13 @@ private juce::AsyncUpdater
void SetJuceLabels();
CustomFontLookAndFeel customFontLookAndFeel;
std::unique_ptr<juce::Drawable> signalFlowChart = juce::Drawable::createFromImageData(BinaryData::signal_flow_control_png, BinaryData::signal_flow_control_pngSize);
std::unique_ptr<juce::ComponentAnimator> componentAnimator;

int fadeTime = 200;

bool areBlobsVisible = true;
int timerCounter = 0;
int fadeBlobTimmerRate = 20; //ms

};

1 change: 0 additions & 1 deletion source/ui/CustomComponents/XYPad/XYPad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ void XYPad::mouseExit(const juce::MouseEvent&)

void XYPad::setArrowAndButtonsVisible(bool newState, int buttonNumber)
{
int fadeTime = 300;

if (buttonNumber == 1)
{
Expand Down
2 changes: 2 additions & 0 deletions source/ui/CustomComponents/XYPad/XYPad.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ class XYPad : public juce::Component, public juce::Timer, private juce::AudioPro

void setArrowAndButtonsVisible(bool newState, int buttonNumber);
int timerCounter = 0;
int fadeTime = 200;


std::unique_ptr<juce::ComponentAnimator> componentAnimator;

Expand Down

0 comments on commit c92bf0a

Please sign in to comment.