kopia lustrzana https://github.com/jameshball/osci-render
Add vector display screen type
rodzic
12c755c697
commit
538662a971
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 56 KiB |
|
@ -7,8 +7,10 @@ std::string lineFragmentShader = R"(
|
||||||
|
|
||||||
uniform float uSize;
|
uniform float uSize;
|
||||||
uniform float uIntensity;
|
uniform float uIntensity;
|
||||||
uniform float uOffset;
|
uniform vec2 uOffset;
|
||||||
uniform float uScale;
|
uniform vec2 uScale;
|
||||||
|
uniform float uScreenType;
|
||||||
|
uniform float uFishEye;
|
||||||
uniform sampler2D uScreen;
|
uniform sampler2D uScreen;
|
||||||
varying float vSize;
|
varying float vSize;
|
||||||
varying vec4 uvl;
|
varying vec4 uvl;
|
||||||
|
@ -29,7 +31,15 @@ float erf(float x) {
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 texCoord = (vTexCoord - 0.5) / uScale + 0.5 + uOffset;
|
// fish eye distortion
|
||||||
|
vec2 uv = vTexCoord - vec2(0.5);
|
||||||
|
float uva = atan(uv.x, uv.y);
|
||||||
|
float uvd = sqrt(dot(uv, uv));
|
||||||
|
uvd = uvd * (1.0 - uFishEye * uvd * uvd);
|
||||||
|
vec2 texCoord = vec2(0.5) + vec2(sin(uva), cos(uva)) * uvd;
|
||||||
|
|
||||||
|
texCoord = (texCoord - uOffset - 0.5) * uScale + 0.5;
|
||||||
|
|
||||||
float len = uvl.z;
|
float len = uvl.z;
|
||||||
vec2 xy = uvl.xy;
|
vec2 xy = uvl.xy;
|
||||||
float brightness;
|
float brightness;
|
||||||
|
@ -45,6 +55,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
brightness *= uvl.w;
|
brightness *= uvl.w;
|
||||||
|
|
||||||
gl_FragColor = 2.0 * texture2D(uScreen, texCoord) * brightness;
|
gl_FragColor = 2.0 * texture2D(uScreen, texCoord) * brightness;
|
||||||
gl_FragColor.a = 1.0;
|
gl_FragColor.a = 1.0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ uniform float uNoise;
|
||||||
uniform float uTime;
|
uniform float uTime;
|
||||||
uniform float uGlow;
|
uniform float uGlow;
|
||||||
uniform float uAmbient;
|
uniform float uAmbient;
|
||||||
|
uniform float uFishEye;
|
||||||
uniform float uRealScreen;
|
uniform float uRealScreen;
|
||||||
uniform vec2 uOffset;
|
uniform vec2 uOffset;
|
||||||
uniform vec2 uScale;
|
uniform vec2 uScale;
|
||||||
|
@ -29,11 +30,19 @@ float noise(in vec2 uv, in float time) {
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 linePos = (vTexCoordCanvas - 0.5) / uScale + 0.5 + uOffset;
|
vec2 linePos = (vTexCoordCanvas - 0.5) / uScale + 0.5 + uOffset;
|
||||||
|
|
||||||
|
// fish eye distortion
|
||||||
|
vec2 uv = linePos - vec2(0.5);
|
||||||
|
float uva = atan(uv.x, uv.y);
|
||||||
|
float uvd = sqrt(dot(uv, uv));
|
||||||
|
uvd = uvd * (1.0 + uFishEye * uvd * uvd);
|
||||||
|
linePos = vec2(0.5) + vec2(sin(uva), cos(uva)) * uvd;
|
||||||
|
|
||||||
vec4 line = texture2D(uTexture0, linePos);
|
vec4 line = texture2D(uTexture0, linePos);
|
||||||
// r components have grid; g components do not.
|
// r components have grid; g components do not.
|
||||||
vec4 screen = texture2D(uTexture3, vTexCoord);
|
vec4 screen = texture2D(uTexture3, vTexCoord);
|
||||||
vec4 tightGlow = texture2D(uTexture1, linePos);
|
vec4 tightGlow = texture2D(uTexture1, linePos);
|
||||||
vec4 scatter = texture2D(uTexture2, linePos) + (1.0 - uRealScreen) * max(uAmbient - 0.45, 0.0);
|
vec4 scatter = texture2D(uTexture2, linePos) + (1.0 - uRealScreen) * max(uAmbient - 0.35, 0.0);
|
||||||
float light = line.r + uGlow * 1.5 * screen.g * screen.g * tightGlow.r;
|
float light = line.r + uGlow * 1.5 * screen.g * screen.g * tightGlow.r;
|
||||||
light += uGlow * 0.3 * scatter.g * (2.0 + 1.0 * screen.g + 0.5 * screen.r);
|
light += uGlow * 0.3 * scatter.g * (2.0 + 1.0 * screen.g + 0.5 * screen.r);
|
||||||
float tlight = 1.0-pow(2.0, -uExposure*light);
|
float tlight = 1.0-pow(2.0, -uExposure*light);
|
||||||
|
|
|
@ -783,10 +783,10 @@ void VisualiserComponent::drawLine(const std::vector<float>& xPoints, const std:
|
||||||
lineShader->setUniform("uFadeAmount", fadeAmount);
|
lineShader->setUniform("uFadeAmount", fadeAmount);
|
||||||
lineShader->setUniform("uNEdges", (GLfloat) nEdges);
|
lineShader->setUniform("uNEdges", (GLfloat) nEdges);
|
||||||
|
|
||||||
OsciPoint offset = settings.getScreenType() == ScreenType::Real ? REAL_SCREEN_OFFSET : OsciPoint();
|
lineShader->setUniform("uScreenType", (GLfloat) screenType);
|
||||||
OsciPoint scale = settings.getScreenType() == ScreenType::Real ? REAL_SCREEN_SCALE : OsciPoint(1);
|
lineShader->setUniform("uFishEye", screenType == ScreenType::VectorDisplay ? VECTOR_DISPLAY_FISH_EYE : 0.0f);
|
||||||
lineShader->setUniform("uOffset", (float) offset.x, (float) offset.y);
|
setOffsetAndScale(lineShader.get());
|
||||||
lineShader->setUniform("uScale", (float) scale.x, (float) scale.y);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
|
||||||
int nEdgesThisTime = xPoints.size() - 1;
|
int nEdgesThisTime = xPoints.size() - 1;
|
||||||
|
@ -860,17 +860,32 @@ void VisualiserComponent::drawCRT() {
|
||||||
outputShader->setUniform("uTime", time);
|
outputShader->setUniform("uTime", time);
|
||||||
outputShader->setUniform("uGlow", (float) settings.getGlow());
|
outputShader->setUniform("uGlow", (float) settings.getGlow());
|
||||||
outputShader->setUniform("uAmbient", (float) settings.getAmbient());
|
outputShader->setUniform("uAmbient", (float) settings.getAmbient());
|
||||||
OsciPoint offset = settings.getScreenType() == ScreenType::Real ? REAL_SCREEN_OFFSET : OsciPoint();
|
outputShader->setUniform("uFishEye", screenType == ScreenType::VectorDisplay ? VECTOR_DISPLAY_FISH_EYE : 0.0f);
|
||||||
OsciPoint scale = settings.getScreenType() == ScreenType::Real ? REAL_SCREEN_SCALE : OsciPoint(1);
|
setOffsetAndScale(outputShader.get());
|
||||||
outputShader->setUniform("uOffset", (float) offset.x, (float) offset.y);
|
outputShader->setUniform("uRealScreen", settings.parameters.screenType->isRealisticDisplay() ? 1.0f : 0.0f);
|
||||||
outputShader->setUniform("uScale", (float) scale.x, (float) scale.y);
|
|
||||||
outputShader->setUniform("uRealScreen", settings.getScreenType() == ScreenType::Real ? 1.0f : 0.0f);
|
|
||||||
outputShader->setUniform("uResizeForCanvas", lineTexture.width / 1024.0f);
|
outputShader->setUniform("uResizeForCanvas", lineTexture.width / 1024.0f);
|
||||||
juce::Colour colour = juce::Colour::fromHSV(settings.getHue() / 360.0f, 1.0, 1.0, 1.0);
|
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());
|
outputShader->setUniform("uColour", colour.getFloatRed(), colour.getFloatGreen(), colour.getFloatBlue());
|
||||||
drawTexture(lineTexture, blur1Texture, blur3Texture, screenTexture);
|
drawTexture(lineTexture, blur1Texture, blur3Texture, screenTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VisualiserComponent::setOffsetAndScale(juce::OpenGLShaderProgram* shader) {
|
||||||
|
OsciPoint offset;
|
||||||
|
OsciPoint scale;
|
||||||
|
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 };
|
||||||
|
}
|
||||||
|
shader->setUniform("uOffset", (float) offset.x, (float) offset.y);
|
||||||
|
checkGLErrors("test 4");
|
||||||
|
shader->setUniform("uScale", (float) scale.x, (float) scale.y);
|
||||||
|
}
|
||||||
|
|
||||||
Texture VisualiserComponent::createScreenTexture() {
|
Texture VisualiserComponent::createScreenTexture() {
|
||||||
using namespace juce::gl;
|
using namespace juce::gl;
|
||||||
|
|
||||||
|
@ -878,6 +893,8 @@ Texture VisualiserComponent::createScreenTexture() {
|
||||||
screenOpenGLTexture.loadImage(screenTextureImage);
|
screenOpenGLTexture.loadImage(screenTextureImage);
|
||||||
} else if (screenType == ScreenType::Real) {
|
} else if (screenType == ScreenType::Real) {
|
||||||
screenOpenGLTexture.loadImage(oscilloscopeImage);
|
screenOpenGLTexture.loadImage(oscilloscopeImage);
|
||||||
|
} else if (screenType == ScreenType::VectorDisplay) {
|
||||||
|
screenOpenGLTexture.loadImage(vectorDisplayImage);
|
||||||
} else {
|
} else {
|
||||||
screenOpenGLTexture.loadImage(emptyScreenImage);
|
screenOpenGLTexture.loadImage(emptyScreenImage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,10 +173,15 @@ private:
|
||||||
juce::Image screenTextureImage = juce::ImageFileFormat::loadFrom(BinaryData::noise_jpg, BinaryData::noise_jpgSize);
|
juce::Image screenTextureImage = juce::ImageFileFormat::loadFrom(BinaryData::noise_jpg, BinaryData::noise_jpgSize);
|
||||||
juce::Image emptyScreenImage = juce::ImageFileFormat::loadFrom(BinaryData::empty_jpg, BinaryData::empty_jpgSize);
|
juce::Image emptyScreenImage = juce::ImageFileFormat::loadFrom(BinaryData::empty_jpg, BinaryData::empty_jpgSize);
|
||||||
juce::Image oscilloscopeImage = juce::ImageFileFormat::loadFrom(BinaryData::real_jpg, BinaryData::real_jpgSize);
|
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);
|
||||||
|
|
||||||
OsciPoint REAL_SCREEN_OFFSET = { 0.02, -0.15 };
|
OsciPoint REAL_SCREEN_OFFSET = { 0.02, -0.15 };
|
||||||
OsciPoint REAL_SCREEN_SCALE = { 0.6 };
|
OsciPoint REAL_SCREEN_SCALE = { 0.6 };
|
||||||
|
|
||||||
|
OsciPoint VECTOR_DISPLAY_OFFSET = { 0.075, -0.045 };
|
||||||
|
OsciPoint VECTOR_DISPLAY_SCALE = { 0.6 };
|
||||||
|
float VECTOR_DISPLAY_FISH_EYE = 0.5;
|
||||||
|
|
||||||
Texture screenTexture;
|
Texture screenTexture;
|
||||||
std::optional<Texture> targetTexture = std::nullopt;
|
std::optional<Texture> targetTexture = std::nullopt;
|
||||||
|
|
||||||
|
@ -198,6 +203,7 @@ private:
|
||||||
chowdsp::ResamplingTypes::LanczosResampler<2048, 8> yResampler;
|
chowdsp::ResamplingTypes::LanczosResampler<2048, 8> yResampler;
|
||||||
chowdsp::ResamplingTypes::LanczosResampler<2048, 8> zResampler;
|
chowdsp::ResamplingTypes::LanczosResampler<2048, 8> zResampler;
|
||||||
|
|
||||||
|
void setOffsetAndScale(juce::OpenGLShaderProgram* shader);
|
||||||
void initialiseSharedTexture();
|
void initialiseSharedTexture();
|
||||||
void closeSharedTexture();
|
void closeSharedTexture();
|
||||||
Texture makeTexture(int width, int height);
|
Texture makeTexture(int width, int height);
|
||||||
|
|
|
@ -14,12 +14,13 @@ enum class ScreenType : int {
|
||||||
Graticule = 2,
|
Graticule = 2,
|
||||||
Smudged = 3,
|
Smudged = 3,
|
||||||
SmudgedGraticule = 4,
|
SmudgedGraticule = 4,
|
||||||
Real = 5
|
Real = 5,
|
||||||
|
VectorDisplay = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScreenTypeParameter : public IntParameter {
|
class ScreenTypeParameter : public IntParameter {
|
||||||
public:
|
public:
|
||||||
ScreenTypeParameter(juce::String name, juce::String id, int versionHint, ScreenType value) : IntParameter(name, id, versionHint, (int) value, 1, 5) {}
|
ScreenTypeParameter(juce::String name, juce::String id, int versionHint, ScreenType value) : IntParameter(name, id, versionHint, (int) value, 1, 6) {}
|
||||||
|
|
||||||
juce::String getText(float value, int maximumStringLength = 100) const override {
|
juce::String getText(float value, int maximumStringLength = 100) const override {
|
||||||
switch ((ScreenType)(int)getUnnormalisedValue(value)) {
|
switch ((ScreenType)(int)getUnnormalisedValue(value)) {
|
||||||
|
@ -33,6 +34,8 @@ public:
|
||||||
return "Smudged Graticule";
|
return "Smudged Graticule";
|
||||||
case ScreenType::Real:
|
case ScreenType::Real:
|
||||||
return "Real Oscilloscope";
|
return "Real Oscilloscope";
|
||||||
|
case ScreenType::VectorDisplay:
|
||||||
|
return "Vector Display";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
@ -50,6 +53,8 @@ public:
|
||||||
unnormalisedValue = (int)ScreenType::SmudgedGraticule;
|
unnormalisedValue = (int)ScreenType::SmudgedGraticule;
|
||||||
} else if (text == "Real Oscilloscope") {
|
} else if (text == "Real Oscilloscope") {
|
||||||
unnormalisedValue = (int)ScreenType::Real;
|
unnormalisedValue = (int)ScreenType::Real;
|
||||||
|
} else if (text == "Vector Display") {
|
||||||
|
unnormalisedValue = (int)ScreenType::VectorDisplay;
|
||||||
} else {
|
} else {
|
||||||
unnormalisedValue = (int)ScreenType::Empty;
|
unnormalisedValue = (int)ScreenType::Empty;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +68,11 @@ public:
|
||||||
void load(juce::XmlElement* xml) {
|
void load(juce::XmlElement* xml) {
|
||||||
setValueNotifyingHost(getValueForText(xml->getStringAttribute("screenType")));
|
setValueNotifyingHost(getValueForText(xml->getStringAttribute("screenType")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isRealisticDisplay() {
|
||||||
|
ScreenType type = (ScreenType)(int)getValueUnnormalised();
|
||||||
|
return type == ScreenType::Real || type == ScreenType::VectorDisplay;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VisualiserParameters {
|
class VisualiserParameters {
|
||||||
|
@ -133,7 +143,7 @@ public:
|
||||||
"Ambient Light",
|
"Ambient Light",
|
||||||
"Controls how much ambient light is added to the oscilloscope display.",
|
"Controls how much ambient light is added to the oscilloscope display.",
|
||||||
"ambient",
|
"ambient",
|
||||||
VERSION_HINT, 0.8, 0.0, 5.0
|
VERSION_HINT, 0.7, 0.0, 5.0
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
std::shared_ptr<Effect> smoothEffect = std::make_shared<Effect>(
|
std::shared_ptr<Effect> smoothEffect = std::make_shared<Effect>(
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
<FILE id="qpPhpN" name="empty.jpg" compile="0" resource="1" file="Resources/oscilloscope/empty.jpg"/>
|
<FILE id="qpPhpN" name="empty.jpg" compile="0" resource="1" file="Resources/oscilloscope/empty.jpg"/>
|
||||||
<FILE id="dNtZYs" name="noise.jpg" compile="0" resource="1" file="Resources/oscilloscope/noise.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="FyEDbA" name="real.jpg" compile="0" resource="1" file="Resources/oscilloscope/real.jpg"/>
|
||||||
|
<FILE id="QrCP4w" name="vector_display.jpg" compile="0" resource="1"
|
||||||
|
file="Resources/oscilloscope/vector_display.jpg"/>
|
||||||
</GROUP>
|
</GROUP>
|
||||||
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
|
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
|
||||||
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>
|
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
<GROUP id="{F3C16D02-63B4-E3DA-7498-901173C37D6C}" name="oscilloscope">
|
<GROUP id="{F3C16D02-63B4-E3DA-7498-901173C37D6C}" name="oscilloscope">
|
||||||
<FILE id="qpPhpN" name="empty.jpg" compile="0" resource="1" file="Resources/oscilloscope/empty.jpg"/>
|
<FILE id="qpPhpN" name="empty.jpg" compile="0" resource="1" file="Resources/oscilloscope/empty.jpg"/>
|
||||||
<FILE id="dNtZYs" name="noise.jpg" compile="0" resource="1" file="Resources/oscilloscope/noise.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="bdQp0Q" name="vector_display.jpg" compile="0" resource="1"
|
||||||
|
file="Resources/oscilloscope/vector_display.jpg"/>
|
||||||
</GROUP>
|
</GROUP>
|
||||||
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
|
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
|
||||||
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>
|
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>
|
||||||
|
|
Ładowanie…
Reference in New Issue