kopia lustrzana https://github.com/jameshball/osci-render
Add reflection/glow for vector display
rodzic
538662a971
commit
8c139112cd
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 6.3 KiB |
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 931 KiB |
|
|
@ -0,0 +1,33 @@
|
|||
std::string glowFragmentShader = R"(
|
||||
|
||||
uniform sampler2D uTexture0;
|
||||
uniform vec2 uOffset;
|
||||
uniform vec2 uScale;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vec2 texCoord = (vTexCoord - 0.5) / uScale + uOffset + 0.5;
|
||||
|
||||
vec2 reflectionLinePos1 = (texCoord - 0.5) / 0.875 + 0.5;
|
||||
vec2 reflectionLinePos2 = (texCoord - 0.5) / 1.125 + 0.5;
|
||||
vec2 reflectionLinePos3 = (texCoord - 0.5) / 1.375 + 0.5;
|
||||
vec2 reflectionLinePos4 = (texCoord - 0.5) / 1.625 + 0.5;
|
||||
vec2 reflectionLinePos5 = (texCoord - 0.5) / 1.875 + 0.5;
|
||||
|
||||
vec2 distVec = (texCoord - 0.5);
|
||||
float dist = dot(distVec, distVec);
|
||||
float decay = 1.0 - dist;
|
||||
|
||||
vec4 sum = vec4(0.0);
|
||||
sum += texture2D(uTexture0, reflectionLinePos1);
|
||||
sum += texture2D(uTexture0, reflectionLinePos2);
|
||||
sum += texture2D(uTexture0, reflectionLinePos3);
|
||||
sum += texture2D(uTexture0, reflectionLinePos4);
|
||||
sum += texture2D(uTexture0, reflectionLinePos5);
|
||||
sum *= 3.0 * pow(decay, 4.0);
|
||||
|
||||
gl_FragColor = sum;
|
||||
gl_FragColor.a = 1.0;
|
||||
}
|
||||
|
||||
)";
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
std::string glowVertexShader = R"(
|
||||
|
||||
attribute vec2 aPos;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aPos, 0.0, 1.0);
|
||||
vTexCoord = (0.5*aPos+0.5);
|
||||
}
|
||||
|
||||
)";
|
||||
|
|
@ -4,6 +4,8 @@ uniform sampler2D uTexture0; //line
|
|||
uniform sampler2D uTexture1; //tight glow
|
||||
uniform sampler2D uTexture2; //big glow
|
||||
uniform sampler2D uTexture3; //screen
|
||||
uniform sampler2D uTexture4; //reflection
|
||||
uniform sampler2D uTexture5; //screen glow
|
||||
uniform float uExposure;
|
||||
uniform float uSaturation;
|
||||
uniform float uNoise;
|
||||
|
|
@ -43,6 +45,13 @@ void main() {
|
|||
vec4 screen = texture2D(uTexture3, vTexCoord);
|
||||
vec4 tightGlow = texture2D(uTexture1, linePos);
|
||||
vec4 scatter = texture2D(uTexture2, linePos) + (1.0 - uRealScreen) * max(uAmbient - 0.35, 0.0);
|
||||
|
||||
if (uRealScreen > 0.5) {
|
||||
vec4 reflection = texture2D(uTexture4, vTexCoord);
|
||||
vec4 screenGlow = texture2D(uTexture5, vTexCoord);
|
||||
scatter += screenGlow * reflection * max(1.0 - uAmbient, 0.0);
|
||||
}
|
||||
|
||||
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);
|
||||
float tlight = 1.0-pow(2.0, -uExposure*light);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include "BlurVertexShader.glsl"
|
||||
#include "WideBlurFragmentShader.glsl"
|
||||
#include "WideBlurVertexShader.glsl"
|
||||
#include "GlowFragmentShader.glsl"
|
||||
#include "GlowVertexShader.glsl"
|
||||
#include "LineFragmentShader.glsl"
|
||||
#include "LineVertexShader.glsl"
|
||||
#include "OutputFragmentShader.glsl"
|
||||
|
|
@ -359,7 +361,7 @@ void VisualiserComponent::initialiseSharedTexture() {
|
|||
sharedTextureSender->setSharedTextureId(renderTexture.id);
|
||||
sharedTextureSender->setDrawFunction([this] {
|
||||
setShader(texturedShader.get());
|
||||
drawTexture(renderTexture);
|
||||
drawTexture({renderTexture});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -416,6 +418,11 @@ void VisualiserComponent::newOpenGLContextCreated() {
|
|||
wideBlurShader->addFragmentShader(wideBlurFragmentShader);
|
||||
wideBlurShader->link();
|
||||
|
||||
glowShader = std::make_unique<juce::OpenGLShaderProgram>(openGLContext);
|
||||
glowShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(glowVertexShader));
|
||||
glowShader->addFragmentShader(glowFragmentShader);
|
||||
glowShader->link();
|
||||
|
||||
glGenBuffers(1, &vertexBuffer);
|
||||
glGenBuffers(1, &quadIndexBuffer);
|
||||
glGenBuffers(1, &vertexIndexBuffer);
|
||||
|
|
@ -437,12 +444,16 @@ 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();
|
||||
reflectionOpenGLTexture.release();
|
||||
|
||||
simpleShader.reset();
|
||||
texturedShader.reset();
|
||||
blurShader.reset();
|
||||
wideBlurShader.reset();
|
||||
glowShader.reset();
|
||||
lineShader.reset();
|
||||
outputShader.reset();
|
||||
}
|
||||
|
|
@ -494,7 +505,7 @@ void VisualiserComponent::renderOpenGL() {
|
|||
// render texture to screen
|
||||
activateTargetTexture(std::nullopt);
|
||||
setShader(texturedShader.get());
|
||||
drawTexture(renderTexture);
|
||||
drawTexture({renderTexture});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -568,8 +579,10 @@ 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();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind
|
||||
|
|
@ -683,31 +696,17 @@ void VisualiserComponent::setShader(juce::OpenGLShaderProgram* program) {
|
|||
program->use();
|
||||
}
|
||||
|
||||
void VisualiserComponent::drawTexture(std::optional<Texture> texture0, std::optional<Texture> texture1, std::optional<Texture> texture2, std::optional<Texture> texture3) {
|
||||
void VisualiserComponent::drawTexture(std::vector<std::optional<Texture>> textures) {
|
||||
using namespace juce::gl;
|
||||
|
||||
glEnableVertexAttribArray(glGetAttribLocation(currentShader->getProgramID(), "aPos"));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture0.value().id);
|
||||
currentShader->setUniform("uTexture0", 0);
|
||||
|
||||
if (texture1.has_value()) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, texture1.value().id);
|
||||
currentShader->setUniform("uTexture1", 1);
|
||||
}
|
||||
|
||||
if (texture2.has_value()) {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, texture2.value().id);
|
||||
currentShader->setUniform("uTexture2", 2);
|
||||
}
|
||||
|
||||
if (texture3.has_value()) {
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, texture3.value().id);
|
||||
currentShader->setUniform("uTexture3", 3);
|
||||
for (int i = 0; i < textures.size(); ++i) {
|
||||
if (textures[i].has_value()) {
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i].value().id);
|
||||
currentShader->setUniform(("uTexture" + juce::String(i)).toStdString().c_str(), i);
|
||||
}
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
|
|
@ -822,35 +821,53 @@ void VisualiserComponent::drawCRT() {
|
|||
activateTargetTexture(blur1Texture);
|
||||
setShader(texturedShader.get());
|
||||
texturedShader->setUniform("uResizeForCanvas", lineTexture.width / 1024.0f);
|
||||
drawTexture(lineTexture);
|
||||
drawTexture({lineTexture});
|
||||
|
||||
//horizontal blur 256x256
|
||||
//horizontal blur 512x512
|
||||
activateTargetTexture(blur2Texture);
|
||||
setShader(blurShader.get());
|
||||
blurShader->setUniform("uOffset", 1.0f / 512.0f, 0.0f);
|
||||
drawTexture(blur1Texture);
|
||||
drawTexture({blur1Texture});
|
||||
|
||||
//vertical blur 256x256
|
||||
//vertical blur 512x512
|
||||
activateTargetTexture(blur1Texture);
|
||||
blurShader->setUniform("uOffset", 0.0f, 1.0f / 512.0f);
|
||||
drawTexture(blur2Texture);
|
||||
drawTexture({blur2Texture});
|
||||
|
||||
//preserve blur1 for later
|
||||
activateTargetTexture(blur3Texture);
|
||||
setShader(texturedShader.get());
|
||||
texturedShader->setUniform("uResizeForCanvas", 1.0f);
|
||||
drawTexture(blur1Texture);
|
||||
drawTexture({blur1Texture});
|
||||
|
||||
//horizontal blur 128x128
|
||||
activateTargetTexture(blur4Texture);
|
||||
setShader(wideBlurShader.get());
|
||||
wideBlurShader->setUniform("uOffset", 1.0f / 128.0f, 0.0f);
|
||||
drawTexture(blur3Texture);
|
||||
drawTexture({blur3Texture});
|
||||
|
||||
//vertical blur 128x128
|
||||
activateTargetTexture(blur3Texture);
|
||||
wideBlurShader->setUniform("uOffset", 0.0f, 1.0f / 128.0f);
|
||||
drawTexture(blur4Texture);
|
||||
drawTexture({blur4Texture});
|
||||
|
||||
// create glow texture
|
||||
activateTargetTexture(glowTexture);
|
||||
setShader(glowShader.get());
|
||||
setOffsetAndScale(glowShader.get());
|
||||
drawTexture({blur3Texture});
|
||||
|
||||
// blur the glow texture to blend it nicely. blur3Texture and blur1Texture are reserved, so we can't use them
|
||||
// horizontal 512x512
|
||||
activateTargetTexture(blur2Texture);
|
||||
setShader(wideBlurShader.get());
|
||||
wideBlurShader->setUniform("uOffset", 1.0f / 512.0f, 0.0f);
|
||||
drawTexture({glowTexture});
|
||||
|
||||
// vertical 512x512
|
||||
activateTargetTexture(glowTexture);
|
||||
wideBlurShader->setUniform("uOffset", 0.0f, 1.0f / 512.0f);
|
||||
drawTexture({blur2Texture});
|
||||
|
||||
activateTargetTexture(renderTexture);
|
||||
setShader(outputShader.get());
|
||||
|
|
@ -866,7 +883,7 @@ void VisualiserComponent::drawCRT() {
|
|||
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);
|
||||
drawTexture({lineTexture, blur1Texture, blur3Texture, screenTexture, reflectionTexture, glowTexture});
|
||||
}
|
||||
|
||||
void VisualiserComponent::setOffsetAndScale(juce::OpenGLShaderProgram* shader) {
|
||||
|
|
@ -882,10 +899,23 @@ void VisualiserComponent::setOffsetAndScale(juce::OpenGLShaderProgram* shader) {
|
|||
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::createReflectionTexture() {
|
||||
using namespace juce::gl;
|
||||
|
||||
if (settings.getScreenType() == ScreenType::VectorDisplay) {
|
||||
reflectionOpenGLTexture.loadImage(vectorDisplayReflectionImage);
|
||||
} else {
|
||||
reflectionOpenGLTexture.loadImage(emptyReflectionImage);
|
||||
}
|
||||
|
||||
Texture texture = { reflectionOpenGLTexture.getTextureID(), reflectionOpenGLTexture.getWidth(), reflectionOpenGLTexture.getHeight() };
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
Texture VisualiserComponent::createScreenTexture() {
|
||||
using namespace juce::gl;
|
||||
|
||||
|
|
@ -1000,6 +1030,7 @@ void VisualiserComponent::renderScope(const std::vector<float>& xPoints, const s
|
|||
|
||||
if (screenType != settings.getScreenType()) {
|
||||
screenType = settings.getScreenType();
|
||||
reflectionTexture = createReflectionTexture();
|
||||
screenTexture = createScreenTexture();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,13 +168,18 @@ private:
|
|||
Texture blur2Texture;
|
||||
Texture blur3Texture;
|
||||
Texture blur4Texture;
|
||||
Texture glowTexture;
|
||||
Texture renderTexture;
|
||||
juce::OpenGLTexture screenOpenGLTexture;
|
||||
juce::OpenGLTexture reflectionOpenGLTexture;
|
||||
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 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 vectorDisplayReflectionImage = juce::ImageFileFormat::loadFrom(BinaryData::vector_display_reflection_jpg, BinaryData::vector_display_reflection_jpgSize);
|
||||
|
||||
OsciPoint REAL_SCREEN_OFFSET = { 0.02, -0.15 };
|
||||
OsciPoint REAL_SCREEN_SCALE = { 0.6 };
|
||||
|
||||
|
|
@ -183,12 +188,14 @@ private:
|
|||
float VECTOR_DISPLAY_FISH_EYE = 0.5;
|
||||
|
||||
Texture screenTexture;
|
||||
Texture reflectionTexture;
|
||||
std::optional<Texture> targetTexture = std::nullopt;
|
||||
|
||||
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;
|
||||
|
|
@ -214,7 +221,7 @@ private:
|
|||
void saveTextureToQOI(Texture texture, const juce::File& file);
|
||||
void activateTargetTexture(std::optional<Texture> texture);
|
||||
void setShader(juce::OpenGLShaderProgram* program);
|
||||
void drawTexture(std::optional<Texture> texture0, std::optional<Texture> texture1 = std::nullopt, std::optional<Texture> texture2 = std::nullopt, std::optional<Texture> texture3 = std::nullopt);
|
||||
void drawTexture(std::vector<std::optional<Texture>> textures);
|
||||
void setAdditiveBlending();
|
||||
void setNormalBlending();
|
||||
void drawLine(const std::vector<float>& xPoints, const std::vector<float>& yPoints, const std::vector<float>& zPoints);
|
||||
|
|
@ -227,6 +234,7 @@ private:
|
|||
int renderAudioFile(juce::File& sourceAudio, int method = 1, int width = 1024, int height = 1024);
|
||||
|
||||
Texture createScreenTexture();
|
||||
Texture createReflectionTexture();
|
||||
|
||||
juce::File audioFile;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,14 @@
|
|||
</GROUP>
|
||||
<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="RgmiPU" name="no_reflection.jpg" compile="0" resource="1"
|
||||
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="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"
|
||||
resource="1" file="Resources/oscilloscope/vector_display_reflection.jpg"/>
|
||||
</GROUP>
|
||||
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
|
||||
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>
|
||||
|
|
@ -606,6 +610,10 @@
|
|||
file="Source/visualiser/BlurFragmentShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="c59gvD" name="BlurVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/BlurVertexShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="dma1IP" name="GlowFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/GlowFragmentShader.glsl"/>
|
||||
<FILE id="ytSpvX" name="GlowVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/GlowVertexShader.glsl"/>
|
||||
<FILE id="WZFPXF" name="LineFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/LineFragmentShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="iS2Ipw" name="LineVertexShader.glsl" compile="0" resource="0"
|
||||
|
|
|
|||
|
|
@ -22,10 +22,14 @@
|
|||
</GROUP>
|
||||
<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="ZgcesA" name="no_reflection.jpg" compile="0" resource="1"
|
||||
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="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"
|
||||
resource="1" file="Resources/oscilloscope/vector_display_reflection.jpg"/>
|
||||
</GROUP>
|
||||
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
|
||||
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue