From d87f6b74f31a9d48720b587f7a06d6073219ca3e Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Fri, 10 Jun 2022 00:04:56 +0200 Subject: [PATCH] Fixed Shader Editor menu and behavior Only Clones with ImageFilter of custom type are linked to UI for ShaderEditor. New menu to try presets of shader code. Link to ShaderToy website. --- ImageFilter.cpp | 36 ++++--------- UserInterfaceManager.cpp | 85 ++++++++++++++++++++++-------- rsc/shaders/filters/bloom.glsl | 2 +- rsc/shaders/filters/bokeh.glsl | 2 +- rsc/shaders/filters/dithering.glsl | 6 +-- rsc/shaders/filters/fisheye.glsl | 5 +- rsc/shaders/filters/pixelate.glsl | 4 +- rsc/shaders/filters/stippling.glsl | 4 +- rsc/shaders/filters/talk.glsl | 2 +- 9 files changed, 85 insertions(+), 61 deletions(-) diff --git a/ImageFilter.cpp b/ImageFilter.cpp index 3658682..f8249e8 100644 --- a/ImageFilter.cpp +++ b/ImageFilter.cpp @@ -63,42 +63,28 @@ std::string fragmentFooter = "void main() {\n" " mainImage( FragColor, texcoord.xy * iResolution.xy );\n" "}\n"; -//std::string fragmentFooter = "void main() {\n" -// " iChannelResolution[0] = vec3(textureSize(iChannel0, 0), 0.f);\n" -// " iChannelResolution[1] = vec3(textureSize(iChannel1, 0), 0.f);\n" -// " vec4 texcoord = iTransform * vec4(vertexUV.x, vertexUV.y, 0.0, 1.0);\n" -// " vec4 filtered;\n" -// " mainImage( filtered, texcoord.xy * iChannelResolution[0].xy );\n" -// " vec3 RGB = filtered.rgb * vertexColor.rgb * color.rgb;\n" -// " float maskIntensity = dot(texture(iChannel1, vertexUV).rgb, vec3(1.0/3.0));\n" -// " float A = clamp(filtered.a * vertexColor.a * color.a * maskIntensity, 0.0, 1.0);\n" -// " FragColor = vec4(RGB * A, A);\n" -// "} \n"; - - std::list< FilteringProgram > FilteringProgram::presets = { FilteringProgram(), FilteringProgram("Bilateral","shaders/filters/bilinear.glsl", "", { }), - FilteringProgram("Pixelate", "shaders/filters/pixelate.glsl", "", { { "Size", 0.5}, { "Sharpen", 0.5} }), - FilteringProgram("Bloom", "shaders/filters/bloom.glsl", "", { { "Intensity", 0.5} }), - FilteringProgram("Bokeh", "shaders/filters/bokeh.glsl", "", { { "Radius", 1.0} }), - FilteringProgram("Chalk", "shaders/filters/talk.glsl", "", { { "Factor", 1.0} }), - FilteringProgram("Stippling","shaders/filters/stippling.glsl", "", { { "Factor", 0.5} }), - FilteringProgram("Dithering","shaders/filters/dithering.glsl", "", { { "Factor", 0.5} }), - FilteringProgram("Fisheye", "shaders/filters/fisheye.glsl", "", { { "Factor", 0.35} }), + FilteringProgram("Pixelate", "shaders/filters/pixelate.glsl", "", { }), + FilteringProgram("Bloom", "shaders/filters/bloom.glsl", "", { }), + FilteringProgram("Bokeh", "shaders/filters/bokeh.glsl", "", { }), + FilteringProgram("Talk", "shaders/filters/talk.glsl", "", { }), + FilteringProgram("Stippling","shaders/filters/stippling.glsl", "", { }), + FilteringProgram("Dithering","shaders/filters/dithering.glsl", "", { }), + FilteringProgram("Fisheye", "shaders/filters/fisheye.glsl", "", { }) }; - std::string FilteringProgram::getFilterCodeInputs() { static std::string filterHeaderHelp = "vec3 iResolution; // viewport resolution (in pixels)\n" "float iTime; // shader playback time (in seconds)\n" "float iTimeDelta; // render time (in seconds)\n" "int iFrame; // shader playback frame\n" - "vec3 iChannelResolution[2]; // input channel resolution (in pixels)\n" - "sampler2D iChannel0; // input channel (texture).\n" - "sampler2D iChannel1; // input channel (mask).\n" + "vec3 iChannelResolution[2]; // input channels resolution (in pixels)\n" + "sampler2D iChannel0; // input channel 0 (texture).\n" + "sampler2D iChannel1; // input channel 1 (texture).\n" "vec4 iDate; // (year, month, day, time in seconds)"; return filterHeaderHelp; } @@ -114,7 +100,7 @@ std::string FilteringProgram::getFilterCodeDefault() /// //// //////////////////////////////////////// -FilteringProgram::FilteringProgram() : name_("None"), code_({"shaders/filters/default.glsl",""}), two_pass_filter_(false) +FilteringProgram::FilteringProgram() : name_("Default"), code_({"shaders/filters/default.glsl",""}), two_pass_filter_(false) { } diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 2d2c28d..e2bd3f5 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -5329,6 +5329,7 @@ void ShaderEditor::refresh(CloneSource *cs) filters_.erase(current_); current_ = nullptr; } + } void ShaderEditor::Render() @@ -5353,35 +5354,49 @@ void ShaderEditor::Render() Settings::application.widget.shader_editor = false; if (ImGui::BeginMenu(IMGUI_TITLE_SHADEREDITOR)) { - if (ImGui::MenuItem( ICON_FA_SYNC " Reload")) { + if (ImGui::MenuItem( ICON_FA_SYNC " Reload", nullptr, nullptr, current_ != nullptr)) { if ( current_ != nullptr ) filters_.erase(current_); + // force reload current_ = nullptr; } + // Menu section for presets + if (ImGui::BeginMenu( ICON_FA_SCROLL " Example code", current_ != nullptr)) + { + for (auto p = FilteringProgram::presets.begin(); p != FilteringProgram::presets.end(); ++p){ + + if (ImGui::MenuItem( p->name().c_str() )) { + ImageFilter *i = dynamic_cast( current_->filter() ); + // if we can access the code of inside the image filter + if (i) { + // change the filter of the current image filter + // => this triggers compilation of shader + compilation_ = new std::promise(); + i->setProgram( *p, compilation_ ); + compilation_return_ = compilation_->get_future(); + // inform status + status_ = "Building..."; + // force reload + current_ = nullptr; + } + } + + } + + ImGui::EndMenu(); + } + + if (ImGui::MenuItem( ICON_FA_EXTERNAL_LINK_ALT " Browse shadertoy.com")) { + SystemToolkit::open("https://www.shadertoy.com/"); + } + // Enable/Disable editor options ImGui::Separator(); - ImGui::MenuItem( ICON_FA_UNDERLINE " Show Shader Inputs", nullptr, &show_shader_inputs_); - if (ImGui::MenuItem( ICON_FA_LONG_ARROW_ALT_RIGHT " Show whitespace", nullptr, &ws)) + ImGui::MenuItem( ICON_FA_UNDERLINE " Show Shader Inputs", nullptr, &show_shader_inputs_); + if (ImGui::MenuItem( ICON_FA_LONG_ARROW_ALT_RIGHT " Show whitespace", nullptr, &ws)) _editor.SetShowWhitespaces(ws); - // Edit menu - ImGui::Separator(); - if (ImGui::MenuItem( MENU_UNDO, SHORTCUT_UNDO, nullptr, !ro && _editor.CanUndo())) - _editor.Undo(); - if (ImGui::MenuItem( MENU_REDO, SHORTCUT_REDO, nullptr, !ro && _editor.CanRedo())) - _editor.Redo(); - if (ImGui::MenuItem( MENU_COPY, SHORTCUT_COPY, nullptr, _editor.HasSelection())) - _editor.Copy(); - if (ImGui::MenuItem( MENU_CUT, SHORTCUT_CUT, nullptr, !ro && _editor.HasSelection())) - _editor.Cut(); - if (ImGui::MenuItem( MENU_DELETE, SHORTCUT_DELETE, nullptr, !ro && _editor.HasSelection())) - _editor.Delete(); - if (ImGui::MenuItem( MENU_PASTE, SHORTCUT_PASTE, nullptr, !ro && ImGui::GetClipboardText() != nullptr)) - _editor.Paste(); - if (ImGui::MenuItem( MENU_SELECTALL, SHORTCUT_SELECTALL, nullptr, _editor.GetText().size() > 1 )) - _editor.SetSelection(TextEditor::Coordinates(), TextEditor::Coordinates(_editor.GetTotalLines(), 0)); - // output manager menu ImGui::Separator(); bool pinned = Settings::application.widget.shader_editor_view == Settings::application.current_view; @@ -5398,6 +5413,28 @@ void ShaderEditor::Render() ImGui::EndMenu(); } + // Edit menu + if (ImGui::BeginMenu( "Edit", current_ != nullptr ) ) { + + if (ImGui::MenuItem( MENU_UNDO, SHORTCUT_UNDO, nullptr, !ro && _editor.CanUndo())) + _editor.Undo(); + if (ImGui::MenuItem( MENU_REDO, SHORTCUT_REDO, nullptr, !ro && _editor.CanRedo())) + _editor.Redo(); + if (ImGui::MenuItem( MENU_COPY, SHORTCUT_COPY, nullptr, _editor.HasSelection())) + _editor.Copy(); + if (ImGui::MenuItem( MENU_CUT, SHORTCUT_CUT, nullptr, !ro && _editor.HasSelection())) + _editor.Cut(); + if (ImGui::MenuItem( MENU_DELETE, SHORTCUT_DELETE, nullptr, !ro && _editor.HasSelection())) + _editor.Delete(); + if (ImGui::MenuItem( MENU_PASTE, SHORTCUT_PASTE, nullptr, !ro && ImGui::GetClipboardText() != nullptr)) + _editor.Paste(); + if (ImGui::MenuItem( MENU_SELECTALL, SHORTCUT_SELECTALL, nullptr, _editor.GetText().size() > 1 )) + _editor.SetSelection(TextEditor::Coordinates(), TextEditor::Coordinates(_editor.GetTotalLines(), 0)); + + ImGui::EndMenu(); + } + + // Build action menu if (ImGui::MenuItem( ICON_FA_HAMMER " Build", nullptr, nullptr, current_ != nullptr )) { // the UI has ref to code for this clone @@ -5488,11 +5525,13 @@ void ShaderEditor::Render() filters_[c] = i->program(); } } - else - status_ = "No shader"; + else { + status_ = "-"; + c = nullptr; + } } else - status_ = "No shader"; + status_ = "-"; } else status_ = "-"; diff --git a/rsc/shaders/filters/bloom.glsl b/rsc/shaders/filters/bloom.glsl index 94f9dec..f3a974c 100644 --- a/rsc/shaders/filters/bloom.glsl +++ b/rsc/shaders/filters/bloom.glsl @@ -1,5 +1,5 @@ // from https://www.shadertoy.com/view/Ms2Xz3 -uniform float Intensity; +float Intensity = 0.6; vec4 BlurColor (in vec2 Coord, in sampler2D Tex, in float MipBias) { diff --git a/rsc/shaders/filters/bokeh.glsl b/rsc/shaders/filters/bokeh.glsl index 7787f2b..ea61301 100644 --- a/rsc/shaders/filters/bokeh.glsl +++ b/rsc/shaders/filters/bokeh.glsl @@ -6,7 +6,7 @@ #define GOLDEN_ANGLE 2.39996323 #define ITERATIONS 60 -uniform float Radius; +float Radius = 0.3; mat2 rot = mat2(cos(GOLDEN_ANGLE), sin(GOLDEN_ANGLE), -sin(GOLDEN_ANGLE), cos(GOLDEN_ANGLE)); diff --git a/rsc/shaders/filters/dithering.glsl b/rsc/shaders/filters/dithering.glsl index 49b3cf7..b4f8734 100644 --- a/rsc/shaders/filters/dithering.glsl +++ b/rsc/shaders/filters/dithering.glsl @@ -1,4 +1,4 @@ -uniform float Factor; +float Factor = 0.5; const float mult = 1.0 / 17.0; const mat4 adjustments = (mat4( @@ -34,8 +34,8 @@ float adjustFrag( float val, vec2 coord ) { void mainImage( out vec4 fragColor, in vec2 fragCoord ) { - vec2 uv = fragCoord.xy / iResolution.xy; - vec4 videoColor = texture(iChannel0, uv); + vec2 uv = fragCoord.xy / iResolution.xy; + vec4 videoColor = texture(iChannel0, uv); float vidLum = getLuminance(videoColor); vidLum = adjustFrag(vidLum, fragCoord.xy); diff --git a/rsc/shaders/filters/fisheye.glsl b/rsc/shaders/filters/fisheye.glsl index 271a30b..f49a6b0 100644 --- a/rsc/shaders/filters/fisheye.glsl +++ b/rsc/shaders/filters/fisheye.glsl @@ -1,6 +1,6 @@ // from https://www.shadertoy.com/view/4s2GRR // Inspired by http://stackoverflow.com/questions/6030814/add-fisheye-effect-to-images-at-runtime-using-opengl-es -uniform float Factor; +float Factor = 0.4; void mainImage( out vec4 fragColor, in vec2 fragCoord ) { @@ -26,6 +26,5 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord ) else uv = p;//no effect for power = 1.0 // Second part of cheat for round effect, not elliptical - vec3 col = texture(iChannel0, vec2(uv.x, uv.y * prop)).xyz; - fragColor = vec4(col, 1.0); + fragColor = texture(iChannel0, vec2(uv.x, uv.y * prop)); } diff --git a/rsc/shaders/filters/pixelate.glsl b/rsc/shaders/filters/pixelate.glsl index 077dd91..44da75e 100644 --- a/rsc/shaders/filters/pixelate.glsl +++ b/rsc/shaders/filters/pixelate.glsl @@ -1,5 +1,5 @@ -uniform float Size; -uniform float Sharpen; +float Size = 0.5; +float Sharpen = 0.5; const mat3 G = mat3( 0.0625, 0.125, 0.0625, 0.125, 0.25, 0.125, 0.0625, 0.125, 0.0625); diff --git a/rsc/shaders/filters/stippling.glsl b/rsc/shaders/filters/stippling.glsl index 0477b04..fd242a6 100644 --- a/rsc/shaders/filters/stippling.glsl +++ b/rsc/shaders/filters/stippling.glsl @@ -1,4 +1,4 @@ -uniform float Factor; +float Factor = 0.3; #define SEED1 -0.5775604999999985 #define SEED2 6.440483302499992 @@ -49,5 +49,5 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord ) float c = mask(uv); c = float( f > mix( 0.6 * c, 1.4 * c, Factor) ); - fragColor = vec4(c, c, c, 1.0); + fragColor = vec4(c, c, c, texture(iChannel0, fragCoord.xy / iResolution.xy).a ); } diff --git a/rsc/shaders/filters/talk.glsl b/rsc/shaders/filters/talk.glsl index e5b37a8..6e91515 100644 --- a/rsc/shaders/filters/talk.glsl +++ b/rsc/shaders/filters/talk.glsl @@ -1,7 +1,7 @@ // From https://www.shadertoy.com/view/XdfcWN // Created by inigo quilez - iq/2014 // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. -uniform float Factor; +float Factor = 0.5; vec2 hash( vec2 p ) { p = 2.0 * vec2(dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)));