Add reflection for real oscilloscope and add compilation option for sosci features

pre-release-3
James H Ball 2024-12-30 11:55:45 +00:00
rodzic 8c139112cd
commit b2ef14cd1b
9 zmienionych plików z 135 dodań i 65 usunięć

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 33 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 931 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 64 KiB

Wyświetl plik

@ -76,7 +76,9 @@ CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String app
tooltipDropShadow.setOwner(&tooltipWindow);
#if SOSCI_FEATURES
SharedTextureManager::getInstance()->initGL();
#endif
}
void CommonPluginEditor::initialiseMenuBar(juce::MenuBarModel& menuBarModel) {

Wyświetl plik

@ -29,7 +29,6 @@ float erf(float x) {
return s - s / (x * x);
}
void main() {
// fish eye distortion
vec2 uv = vTexCoord - vec2(0.5);

Wyświetl plik

@ -50,7 +50,8 @@ VisualiserComponent::VisualiserComponent(juce::File& lastOpenedDirectory, juce::
}
addAndMakeVisible(settingsButton);
settingsButton.setTooltip("Opens the visualiser settings window.");
//if (visualiserOnly) {
#if SOSCI_FEATURES
addAndMakeVisible(sharedTextureButton);
sharedTextureButton.setTooltip("Toggles sending the oscilloscope's visuals to a Syphon/Spout receiver.");
sharedTextureButton.onClick = [this] {
@ -64,7 +65,7 @@ VisualiserComponent::VisualiserComponent(juce::File& lastOpenedDirectory, juce::
}, false);
}
};
//}
#endif
fullScreenButton.onClick = [this]() {
enableFullScreen();
@ -299,9 +300,9 @@ void VisualiserComponent::resized() {
popOutButton.setBounds(buttons.removeFromRight(30));
}
settingsButton.setBounds(buttons.removeFromRight(30));
//if (visualiserOnly) {
#if SOSCI_FEATURES
sharedTextureButton.setBounds(buttons.removeFromRight(30));
//}
#endif
record.setBounds(buttons.removeFromRight(25));
if (record.getToggleState()) {
stopwatch.setVisible(true);
@ -318,9 +319,11 @@ void VisualiserComponent::resized() {
}
void VisualiserComponent::popoutWindow() {
#if SOSCI_FEATURES
if (sharedTextureButton.getToggleState()) {
sharedTextureButton.triggerClick();
}
#endif
setRecording(false);
auto visualiser = new VisualiserComponent(lastOpenedDirectory, ffmpegFile, haltRecording, threadManager, settings, recordingParameters, this);
visualiser->settings.setLookAndFeel(&getLookAndFeel());
@ -355,6 +358,7 @@ void VisualiserComponent::childUpdated() {
}
}
#if SOSCI_FEATURES
void VisualiserComponent::initialiseSharedTexture() {
sharedTextureSender = SharedTextureManager::getInstance()->addSender("osci-render - " + juce::String(juce::Time::getCurrentTime().toMilliseconds()), renderTexture.width, renderTexture.height);
sharedTextureSender->initGL();
@ -374,6 +378,7 @@ void VisualiserComponent::closeSharedTexture() {
}
}
#endif
void VisualiserComponent::newOpenGLContextCreated() {
using namespace juce::gl;
@ -418,10 +423,12 @@ void VisualiserComponent::newOpenGLContextCreated() {
wideBlurShader->addFragmentShader(wideBlurFragmentShader);
wideBlurShader->link();
#if SOSCI_FEATURES
glowShader = std::make_unique<juce::OpenGLShaderProgram>(openGLContext);
glowShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(glowVertexShader));
glowShader->addFragmentShader(glowFragmentShader);
glowShader->link();
#endif
glGenBuffers(1, &vertexBuffer);
glGenBuffers(1, &quadIndexBuffer);
@ -433,7 +440,9 @@ void VisualiserComponent::newOpenGLContextCreated() {
void VisualiserComponent::openGLContextClosing() {
using namespace juce::gl;
#if SOSCI_FEATURES
closeSharedTexture();
#endif
glDeleteBuffers(1, &quadIndexBuffer);
glDeleteBuffers(1, &vertexIndexBuffer);
@ -444,16 +453,19 @@ void VisualiserComponent::openGLContextClosing() {
glDeleteTextures(1, &blur2Texture.id);
glDeleteTextures(1, &blur3Texture.id);
glDeleteTextures(1, &blur4Texture.id);
glDeleteTextures(1, &glowTexture.id);
glDeleteTextures(1, &renderTexture.id);
screenOpenGLTexture.release();
#if SOSCI_FEATURES
glDeleteTextures(1, &glowTexture.id);
reflectionOpenGLTexture.release();
glowShader.reset();
#endif
simpleShader.reset();
texturedShader.reset();
blurShader.reset();
wideBlurShader.reset();
glowShader.reset();
lineShader.reset();
outputShader.reset();
}
@ -479,11 +491,11 @@ void VisualiserComponent::renderOpenGL() {
renderScope(xSamples, ySamples, zSamples);
}
//if (parent == nullptr) {
#if SOSCI_FEATURES
if (sharedTextureSender != nullptr) {
sharedTextureSender->renderGL();
}
//}
#endif
if (record.getToggleState()) {
if (recordingVideo) {
@ -579,12 +591,15 @@ void VisualiserComponent::setupTextures() {
blur2Texture = makeTexture(512, 512);
blur3Texture = makeTexture(128, 128);
blur4Texture = makeTexture(128, 128);
glowTexture = makeTexture(512, 512);
renderTexture = makeTexture(1024, 1024);
reflectionTexture = createReflectionTexture();
screenTexture = createScreenTexture();
#if SOSCI_FEATURES
glowTexture = makeTexture(512, 512);
reflectionTexture = createReflectionTexture();
#endif
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind
}
@ -781,11 +796,12 @@ void VisualiserComponent::drawLine(const std::vector<float>& xPoints, const std:
lineShader->setUniform("uFadeAmount", fadeAmount);
lineShader->setUniform("uNEdges", (GLfloat) nEdges);
lineShader->setUniform("uScreenType", (GLfloat) screenType);
lineShader->setUniform("uFishEye", screenType == ScreenType::VectorDisplay ? VECTOR_DISPLAY_FISH_EYE : 0.0f);
setOffsetAndScale(lineShader.get());
#if SOSCI_FEATURES
lineShader->setUniform("uScreenType", (GLfloat) screenType);
lineShader->setUniform("uFishEye", screenType == ScreenType::VectorDisplay ? VECTOR_DISPLAY_FISH_EYE : 0.0f);
#endif
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
int nEdgesThisTime = xPoints.size() - 1;
@ -851,6 +867,8 @@ void VisualiserComponent::drawCRT() {
wideBlurShader->setUniform("uOffset", 0.0f, 1.0f / 128.0f);
drawTexture({blur4Texture});
#if SOSCI_FEATURES
if (settings.parameters.screenType->isRealisticDisplay()) {
// create glow texture
activateTargetTexture(glowTexture);
setShader(glowShader.get());
@ -868,6 +886,8 @@ void VisualiserComponent::drawCRT() {
activateTargetTexture(glowTexture);
wideBlurShader->setUniform("uOffset", 0.0f, 1.0f / 512.0f);
drawTexture({blur2Texture});
}
#endif
activateTargetTexture(renderTexture);
setShader(outputShader.get());
@ -877,36 +897,50 @@ void VisualiserComponent::drawCRT() {
outputShader->setUniform("uTime", time);
outputShader->setUniform("uGlow", (float) settings.getGlow());
outputShader->setUniform("uAmbient", (float) settings.getAmbient());
outputShader->setUniform("uFishEye", screenType == ScreenType::VectorDisplay ? VECTOR_DISPLAY_FISH_EYE : 0.0f);
setOffsetAndScale(outputShader.get());
#if SOSCI_FEATURES
outputShader->setUniform("uFishEye", screenType == ScreenType::VectorDisplay ? VECTOR_DISPLAY_FISH_EYE : 0.0f);
outputShader->setUniform("uRealScreen", settings.parameters.screenType->isRealisticDisplay() ? 1.0f : 0.0f);
#endif
outputShader->setUniform("uResizeForCanvas", lineTexture.width / 1024.0f);
juce::Colour colour = juce::Colour::fromHSV(settings.getHue() / 360.0f, 1.0, 1.0, 1.0);
outputShader->setUniform("uColour", colour.getFloatRed(), colour.getFloatGreen(), colour.getFloatBlue());
drawTexture({lineTexture, blur1Texture, blur3Texture, screenTexture, reflectionTexture, glowTexture});
drawTexture({
lineTexture,
blur1Texture,
blur3Texture,
screenTexture,
#if SOSCI_FEATURES
reflectionTexture,
glowTexture,
#endif
});
}
void VisualiserComponent::setOffsetAndScale(juce::OpenGLShaderProgram* shader) {
OsciPoint offset;
OsciPoint scale;
OsciPoint scale = { 1.0f };
#if SOSCI_FEATURES
if (settings.getScreenType() == ScreenType::Real) {
offset = REAL_SCREEN_OFFSET;
scale = REAL_SCREEN_SCALE;
} else if (settings.getScreenType() == ScreenType::VectorDisplay) {
offset = VECTOR_DISPLAY_OFFSET;
scale = VECTOR_DISPLAY_SCALE;
} else {
scale = { 1.0f };
}
#endif
shader->setUniform("uOffset", (float) offset.x, (float) offset.y);
shader->setUniform("uScale", (float) scale.x, (float) scale.y);
}
#if SOSCI_FEATURES
Texture VisualiserComponent::createReflectionTexture() {
using namespace juce::gl;
if (settings.getScreenType() == ScreenType::VectorDisplay) {
reflectionOpenGLTexture.loadImage(vectorDisplayReflectionImage);
} else if (settings.getScreenType() == ScreenType::Real) {
reflectionOpenGLTexture.loadImage(oscilloscopeReflectionImage);
} else {
reflectionOpenGLTexture.loadImage(emptyReflectionImage);
}
@ -915,16 +949,19 @@ Texture VisualiserComponent::createReflectionTexture() {
return texture;
}
#endif
Texture VisualiserComponent::createScreenTexture() {
using namespace juce::gl;
if (screenType == ScreenType::Smudged || screenType == ScreenType::SmudgedGraticule) {
screenOpenGLTexture.loadImage(screenTextureImage);
#if SOSCI_FEATURES
} else if (screenType == ScreenType::Real) {
screenOpenGLTexture.loadImage(oscilloscopeImage);
} else if (screenType == ScreenType::VectorDisplay) {
screenOpenGLTexture.loadImage(vectorDisplayImage);
#endif
} else {
screenOpenGLTexture.loadImage(emptyScreenImage);
}
@ -1011,7 +1048,11 @@ void VisualiserComponent::checkGLErrors(const juce::String& location) {
void VisualiserComponent::paint(juce::Graphics& g) {
#if SOSCI_FEATURES
g.setColour(settings.getScreenType() == ScreenType::Real ? Colours::dark : Colours::veryDark);
#else
g.setColour(Colours::veryDark);
#endif
g.fillRect(buttonRow);
if (!active) {
// draw a translucent overlay
@ -1030,7 +1071,9 @@ void VisualiserComponent::renderScope(const std::vector<float>& xPoints, const s
if (screenType != settings.getScreenType()) {
screenType = settings.getScreenType();
#if SOSCI_FEATURES
reflectionTexture = createReflectionTexture();
#endif
screenTexture = createScreenTexture();
}

Wyświetl plik

@ -75,12 +75,14 @@ private:
SvgButton fullScreenButton{ "fullScreen", BinaryData::fullscreen_svg, juce::Colours::white, juce::Colours::white };
SvgButton popOutButton{ "popOut", BinaryData::open_in_new_svg, juce::Colours::white, juce::Colours::white };
SvgButton settingsButton{ "settings", BinaryData::cog_svg, juce::Colours::white, juce::Colours::white };
#if SOSCI_FEATURES
SvgButton sharedTextureButton{ "sharedTexture", BinaryData::spout_svg, juce::Colours::white, juce::Colours::red };
SharedTextureSender* sharedTextureSender = nullptr;
#endif
std::function<void(FullScreenMode)> fullScreenCallback;
SharedTextureSender* sharedTextureSender = nullptr;
VisualiserSettings& settings;
RecordingParameters& recordingParameters;
bool recordingAudio = false;
@ -170,14 +172,19 @@ private:
Texture blur4Texture;
Texture glowTexture;
Texture renderTexture;
Texture screenTexture;
juce::OpenGLTexture screenOpenGLTexture;
juce::OpenGLTexture reflectionOpenGLTexture;
std::optional<Texture> targetTexture = std::nullopt;
juce::Image screenTextureImage = juce::ImageFileFormat::loadFrom(BinaryData::noise_jpg, BinaryData::noise_jpgSize);
juce::Image emptyScreenImage = juce::ImageFileFormat::loadFrom(BinaryData::empty_jpg, BinaryData::empty_jpgSize);
#if SOSCI_FEATURES
juce::Image oscilloscopeImage = juce::ImageFileFormat::loadFrom(BinaryData::real_jpg, BinaryData::real_jpgSize);
juce::Image vectorDisplayImage = juce::ImageFileFormat::loadFrom(BinaryData::vector_display_jpg, BinaryData::vector_display_jpgSize);
juce::Image emptyReflectionImage = juce::ImageFileFormat::loadFrom(BinaryData::no_reflection_jpg, BinaryData::no_reflection_jpgSize);
juce::Image oscilloscopeReflectionImage = juce::ImageFileFormat::loadFrom(BinaryData::real_reflection_jpg, BinaryData::real_reflection_jpgSize);
juce::Image vectorDisplayReflectionImage = juce::ImageFileFormat::loadFrom(BinaryData::vector_display_reflection_jpg, BinaryData::vector_display_reflection_jpgSize);
OsciPoint REAL_SCREEN_OFFSET = { 0.02, -0.15 };
@ -187,15 +194,16 @@ private:
OsciPoint VECTOR_DISPLAY_SCALE = { 0.6 };
float VECTOR_DISPLAY_FISH_EYE = 0.5;
Texture screenTexture;
juce::OpenGLTexture reflectionOpenGLTexture;
Texture reflectionTexture;
std::optional<Texture> targetTexture = std::nullopt;
std::unique_ptr<juce::OpenGLShaderProgram> glowShader;
#endif
std::unique_ptr<juce::OpenGLShaderProgram> simpleShader;
std::unique_ptr<juce::OpenGLShaderProgram> texturedShader;
std::unique_ptr<juce::OpenGLShaderProgram> blurShader;
std::unique_ptr<juce::OpenGLShaderProgram> wideBlurShader;
std::unique_ptr<juce::OpenGLShaderProgram> glowShader;
std::unique_ptr<juce::OpenGLShaderProgram> lineShader;
std::unique_ptr<juce::OpenGLShaderProgram> outputShader;
juce::OpenGLShaderProgram* currentShader;
@ -211,8 +219,10 @@ private:
chowdsp::ResamplingTypes::LanczosResampler<2048, 8> zResampler;
void setOffsetAndScale(juce::OpenGLShaderProgram* shader);
#if SOSCI_FEATURES
void initialiseSharedTexture();
void closeSharedTexture();
#endif
Texture makeTexture(int width, int height);
void setupArrays(int num_points);
void setupTextures();

Wyświetl plik

@ -14,13 +14,18 @@ enum class ScreenType : int {
Graticule = 2,
Smudged = 3,
SmudgedGraticule = 4,
#if SOSCI_FEATURES
Real = 5,
VectorDisplay = 6,
MAX = 6,
#else
MAX = 4,
#endif
};
class ScreenTypeParameter : public IntParameter {
public:
ScreenTypeParameter(juce::String name, juce::String id, int versionHint, ScreenType value) : IntParameter(name, id, versionHint, (int) value, 1, 6) {}
ScreenTypeParameter(juce::String name, juce::String id, int versionHint, ScreenType value) : IntParameter(name, id, versionHint, (int) value, 1, (int)ScreenType::MAX) {}
juce::String getText(float value, int maximumStringLength = 100) const override {
switch ((ScreenType)(int)getUnnormalisedValue(value)) {
@ -32,10 +37,12 @@ public:
return "Smudged";
case ScreenType::SmudgedGraticule:
return "Smudged Graticule";
#if SOSCI_FEATURES
case ScreenType::Real:
return "Real Oscilloscope";
case ScreenType::VectorDisplay:
return "Vector Display";
#endif
default:
return "Unknown";
}
@ -51,10 +58,12 @@ public:
unnormalisedValue = (int)ScreenType::Smudged;
} else if (text == "Smudged Graticule") {
unnormalisedValue = (int)ScreenType::SmudgedGraticule;
#if SOSCI_FEATURES
} else if (text == "Real Oscilloscope") {
unnormalisedValue = (int)ScreenType::Real;
} else if (text == "Vector Display") {
unnormalisedValue = (int)ScreenType::VectorDisplay;
#endif
} else {
unnormalisedValue = (int)ScreenType::Empty;
}
@ -69,10 +78,12 @@ public:
setValueNotifyingHost(getValueForText(xml->getStringAttribute("screenType")));
}
#if SOSCI_FEATURES
bool isRealisticDisplay() {
ScreenType type = (ScreenType)(int)getValueUnnormalised();
return type == ScreenType::Real || type == ScreenType::VectorDisplay;
}
#endif
};
class VisualiserParameters {

Wyświetl plik

@ -5,7 +5,7 @@
pluginManufacturer="jameshball" aaxIdentifier="sh.ball.oscirender"
cppLanguageStandard="20" projectLineFeed="&#10;" headerPath="./include"
version="2.3.0" companyName="James H Ball" companyWebsite="https://osci-render.com"
companyEmail="james@ball.sh" defines="NOMINMAX=1&#10;INTERNET_FLAG_NO_AUTO_REDIRECT=0"
companyEmail="james@ball.sh" defines="NOMINMAX=1&#10;INTERNET_FLAG_NO_AUTO_REDIRECT=0&#10;SOSCI_FEATURES=0"
pluginAUMainType="'aumf'" postExportShellCommandPosix="%%1%%/ci/remove_embed_frameworks.sh %%1%%/Builds/MacOSX/osci-render.xcodeproj/project.pbxproj osci-render">
<MAINGROUP id="j5Ge2T" name="osci-render">
<GROUP id="{5ABCED88-0059-A7AF-9596-DBF91DDB0292}" name="Resources">
@ -37,6 +37,8 @@
file="Resources/oscilloscope/no_reflection.jpg"/>
<FILE id="dNtZYs" name="noise.jpg" compile="0" resource="1" file="Resources/oscilloscope/noise.jpg"/>
<FILE id="FyEDbA" name="real.jpg" compile="0" resource="1" file="Resources/oscilloscope/real.jpg"/>
<FILE id="v8E6y9" name="real_reflection.jpg" compile="0" resource="1"
file="Resources/oscilloscope/real_reflection.jpg"/>
<FILE id="QrCP4w" name="vector_display.jpg" compile="0" resource="1"
file="Resources/oscilloscope/vector_display.jpg"/>
<FILE id="s3VNsJ" name="vector_display_reflection.jpg" compile="0"

Wyświetl plik

@ -5,8 +5,9 @@
aaxIdentifier="sh.ball.sosci" cppLanguageStandard="20" projectLineFeed="&#10;"
headerPath="./include" version="1.0.0" companyName="James H Ball"
companyWebsite="https://osci-render.com" companyEmail="james@ball.sh"
defines="NOMINMAX=1&#10;INTERNET_FLAG_NO_AUTO_REDIRECT=0" pluginManufacturerCode="Jhba"
pluginCode="Sosc" pluginAUMainType="'aufx'" postExportShellCommandPosix="%%1%%/ci/remove_embed_frameworks.sh %%1%%/Builds/sosci/MacOSX/sosci.xcodeproj/project.pbxproj sosci">
defines="NOMINMAX=1&#10;INTERNET_FLAG_NO_AUTO_REDIRECT=0&#10;SOSCI_FEATURES=1"
pluginManufacturerCode="Jhba" pluginCode="Sosc" pluginAUMainType="'aufx'"
postExportShellCommandPosix="%%1%%/ci/remove_embed_frameworks.sh %%1%%/Builds/sosci/MacOSX/sosci.xcodeproj/project.pbxproj sosci">
<MAINGROUP id="j5Ge2T" name="sosci">
<GROUP id="{5ABCED88-0059-A7AF-9596-DBF91DDB0292}" name="Resources">
<GROUP id="{1C0FC3AA-01F6-8768-381C-200ED18AB5F2}" name="fonts">
@ -26,6 +27,8 @@
file="Resources/oscilloscope/no_reflection.jpg"/>
<FILE id="dNtZYs" name="noise.jpg" compile="0" resource="1" file="Resources/oscilloscope/noise.jpg"/>
<FILE id="xxXx4Q" name="real.jpg" compile="0" resource="1" file="Resources/oscilloscope/real.jpg"/>
<FILE id="nuEXXn" name="real_reflection.jpg" compile="0" resource="1"
file="Resources/oscilloscope/real_reflection.jpg"/>
<FILE id="bdQp0Q" name="vector_display.jpg" compile="0" resource="1"
file="Resources/oscilloscope/vector_display.jpg"/>
<FILE id="XojumY" name="vector_display_reflection.jpg" compile="0"