From 93df9b50b80232cb82208fbd0b774463ddd4779f Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sat, 22 Dec 2018 22:07:33 +0100 Subject: [PATCH] filter-blur: Add Linear Box Blur and combine all effects Linear Box Blur abuses the fact that with Linear Sampling we can sample up to four adjacent texels at the same time and get a correct result for Box Blur back. Using this the total number of sample for Box Blur is reduced by n, making the total either n+1 (Even Radius) or n (Odd Radius). Additionally all blur effect files have been merged into a single blur.effect file to reduce the time required to change a single parameter name. New blur effects should be added as a new technique instead of as a new effect file. See Also: #21 Blur Quality --- CMakeLists.txt | 10 +- data/effects/bilateral-blur.effect | 95 ------------- data/effects/blur.effect | 207 +++++++++++++++++++++++++++++ data/effects/box-blur.effect | 61 --------- data/effects/gaussian-blur.effect | 68 ---------- data/effects/mip-mapper.effect | 49 ------- data/locale/en-US.ini | 3 +- source/filter-blur.cpp | 66 +++++---- source/filter-blur.h | 12 +- 9 files changed, 253 insertions(+), 318 deletions(-) delete mode 100644 data/effects/bilateral-blur.effect create mode 100644 data/effects/blur.effect delete mode 100644 data/effects/box-blur.effect delete mode 100644 data/effects/gaussian-blur.effect delete mode 100644 data/effects/mip-mapper.effect diff --git a/CMakeLists.txt b/CMakeLists.txt index 74e369d..e62d63f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,7 +184,7 @@ ElseIf(${PropertyPrefix}OBS_DOWNLOAD) ) INCLUDE("${libobs_SOURCE_DIR}/cmake/LibObs/LibObsConfig.cmake") Else() - Message(CRITICAL "Impossible case reached, very system stability.") + Message(CRITICAL "Impossible case reached, verify system stability.") Return() EndIf() @@ -195,15 +195,13 @@ SET(PROJECT_DATA_LOCALE "${PROJECT_SOURCE_DIR}/data/locale/en-US.ini" ) SET(PROJECT_DATA_EFFECTS - "${PROJECT_SOURCE_DIR}/data/effects/bilateral-blur.effect" - "${PROJECT_SOURCE_DIR}/data/effects/box-blur.effect" - "${PROJECT_SOURCE_DIR}/data/effects/gaussian-blur.effect" - "${PROJECT_SOURCE_DIR}/data/effects/displace.effect" + "${PROJECT_SOURCE_DIR}/data/effects/blur.effect" "${PROJECT_SOURCE_DIR}/data/effects/color-conversion.effect" + "${PROJECT_SOURCE_DIR}/data/effects/displace.effect" "${PROJECT_SOURCE_DIR}/data/effects/mask.effect" - "${PROJECT_SOURCE_DIR}/data/effects/mip-mapper.effect" "${PROJECT_SOURCE_DIR}/data/effects/mipgen.effect" "${PROJECT_SOURCE_DIR}/data/effects/sdf-generator.effect" + "${PROJECT_SOURCE_DIR}/data/effects/sdf-shadow.effect" ) SET(PROJECT_DATA_SHADERS # "${PROJECT_SOURCE_DIR}/data/shaders/name.effect" diff --git a/data/effects/bilateral-blur.effect b/data/effects/bilateral-blur.effect deleted file mode 100644 index 19d1541..0000000 --- a/data/effects/bilateral-blur.effect +++ /dev/null @@ -1,95 +0,0 @@ -// OBS Default -uniform float4x4 ViewProj; - -// Settings (Shared) -uniform texture2d u_image; -uniform float2 u_imageSize; -uniform float2 u_imageTexel; -uniform int u_radius; -uniform int u_diameter; -uniform float2 u_texelDelta; - -// Settings (Private) -uniform float bilateralSmoothing; -uniform float bilateralSharpness; - -sampler_state textureSampler { - Filter = Point; - AddressU = Clamp; - AddressV = Clamp; - MinLOD = 0; - MaxLOD = 0; -}; - -struct VertDataIn { - float4 pos : POSITION; - float2 uv : TEXCOORD0; -}; - -struct VertDataOut { - float4 pos : POSITION; - float2 uv : TEXCOORD0; -}; - -VertDataOut VSDefault(VertDataIn v_in) -{ - VertDataOut vert_out; - vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); - vert_out.uv = v_in.uv; - return vert_out; -} - -// Bilateral Blur -float Bilateral(float x, float sigma) { - return 0.39894 * exp(-0.5 * (x*x) / (sigma*sigma)) / sigma; -} - -float Bilateral3(float3 v, float sigma) { - // First part is Bilateral function (1.0 / (o * sqrt(2.0 * pivalue))) with o = 1 - return 0.39894 * exp(-0.5 * dot(v,v) / (sigma*sigma)) / sigma; -} - -float4 BlurFunc(float2 uv, float4 rgba) { - float2 uvOffset = float2(0, 0); - - float Z = 0.0; - float bZ = 1.0 / Bilateral(0.0, bilateralSharpness); - float3 color = float3(0, 0, 0); - for (int k = 1; k <= u_radius; k++) { - uvOffset += u_texelDelta; - - // Bilateral Kernel - float bKernel = Bilateral(abs(k), bilateralSmoothing); - bKernel *= bKernel; - float bZKernel = bZ * bKernel; - - // Sample Color - float3 l_p = u_image.SampleLevel(textureSampler, uv + uvOffset, 0).rgb; - float3 l_n = u_image.SampleLevel(textureSampler, uv - uvOffset, 0).rgb; - - // Bilateral Stuff - float l_factor_p = Bilateral3(l_p - rgba.rgb, bilateralSharpness) * bZKernel; - float l_factor_n = Bilateral3(l_n - rgba.rgb, bilateralSharpness) * bZKernel; - Z = Z + l_factor_p + l_factor_n; - - // Store Color - color += l_p * l_factor_p; - color += l_n * l_factor_n; - } - - return float4(color.rgb / Z, rgba.a); -} - -float4 PSBilateral(VertDataOut v_in) : TARGET { - float4 rgba = u_image.SampleLevel(textureSampler, v_in.uv, 0); - return BlurFunc(v_in.uv, rgba); -} - -technique Draw -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSBilateral(v_in); - } -} diff --git a/data/effects/blur.effect b/data/effects/blur.effect new file mode 100644 index 0000000..a8cf157 --- /dev/null +++ b/data/effects/blur.effect @@ -0,0 +1,207 @@ +// OBS Default +uniform float4x4 ViewProj; + +// Settings (Shared) +uniform texture2d u_image; +uniform float2 u_imageSize; +uniform float2 u_imageTexel; +uniform int u_radius; +uniform int u_diameter; +uniform float2 u_texelDelta; + +// Kernel Settings +//uniform float registerkernel[25]; +uniform texture2d kernel; +uniform float2 kernelTexel; + +// Bilateral Settings +uniform float bilateralSmoothing; +uniform float bilateralSharpness; + +// Data +sampler_state pointSampler { + Filter = Point; + AddressU = Clamp; + AddressV = Clamp; + MinLOD = 0; + MaxLOD = 0; +}; + +sampler_state linearSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; + MinLOD = 0; + MaxLOD = 0; +}; + +struct VertDataIn { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +struct VertDataOut { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertDataOut VSDefault(VertDataIn vtx) +{ + VertDataOut vert_out; + vert_out.pos = mul(float4(vtx.pos.xyz, 1.0), ViewProj); + vert_out.uv = vtx.uv; + return vert_out; +} + +/// Blur: Box +float4 PSBoxBlur(VertDataOut vtx) : TARGET { + float4 origin = u_image.SampleLevel(pointSampler, vtx.uv, 0); + + float4 final = origin; + for (int k = 1; k <= u_radius; k++) { + final += u_image.SampleLevel(pointSampler, vtx.uv + (u_texelDelta * k), 0); + final += u_image.SampleLevel(pointSampler, vtx.uv - (u_texelDelta * k), 0); + } + final /= u_diameter; + + return final; +} + +technique Box +{ + pass + { + vertex_shader = VSDefault(vtx); + pixel_shader = PSBoxBlur(vtx); + } +} + +/// Blur: Box (Linear Optimized) +// By abusing Linear sampling we can reduce the necessary samples, halving the total samples. +float4 PSBoxBlurLinear(VertDataOut vtx) : TARGET { + // Radius 4 (Even): + // [-4, -3, -2, -1, 0, +1, +2, +3, +4] + // ^-S-^ ^-S-^ S ^-S-^ ^-S-^ + // Total Samples: 5 (n+1) + + // Radius 3 (Odd): + // [-3, -2, -1, 0, +1, +2, +3] + // ^-S-^ ^-S-^ S ^-S-^ + // Total Samples: 4 (n) + + // Radius 2 (Even): + // [-2, -1, 0, +1, +2] + // ^-S-^ S ^-S-^ + + float4 final = float4(0, 0, 0, 0); + float2 halfTexelDelta = u_texelDelta / 2.0; + if (u_radius % 2 == 0) { + // Even Numbers require the origin sample in the middle. + float4 origin = u_image.SampleLevel(pointSampler, vtx.uv, 0); + final = origin; + for (int k = 1; k <= u_radius; k+=2) { + float2 offset = k * u_texelDelta + halfTexelDelta; + final += u_image.SampleLevel(linearSampler, vtx.uv + offset, 0) * 2; + final += u_image.SampleLevel(linearSampler, vtx.uv - offset, 0) * 2; + } + } else { + // Odd Numbers put the origin sample in another location. + float4 origin = u_image.SampleLevel(pointSampler, vtx.uv + u_texelDelta, 0); + float4 group = u_image.SampleLevel(linearSampler, vtx.uv - halfTexelDelta, 0); + final = origin + group * 2; + + for (int k = 2; k <= u_radius; k+=2) { + float2 offset = k * u_texelDelta + halfTexelDelta; + final += u_image.SampleLevel(linearSampler, vtx.uv + offset, 0) * 2; + final += u_image.SampleLevel(linearSampler, vtx.uv - offset, 0) * 2; + } + } + final /= u_diameter; + + return final; +} + +technique BoxLinear +{ + pass + { + vertex_shader = VSDefault(vtx); + pixel_shader = PSBoxBlurLinear(vtx); + } +} + +/// Blur: Gaussian +// ToDo: Switch to array Kernel instead of Texture kernel. +float4 PSGaussianBlur(VertDataOut vtx) : TARGET { + float2 uvOffset = float2(0, 0); + float4 final = u_image.SampleLevel(pointSampler, vtx.uv, 0) + * kernel.SampleLevel(pointSampler, (float2(0, u_radius - 1) * kernelTexel), 0).r; + for (int k = 1; k <= u_radius; k++) { + uvOffset += u_texelDelta; + float l_g = kernel.SampleLevel(pointSampler, (float2(k, u_radius - 1) * kernelTexel), 0).r; + float4 l_p = u_image.SampleLevel(pointSampler, vtx.uv + uvOffset, 0); + float4 l_n = u_image.SampleLevel(pointSampler, vtx.uv - uvOffset, 0); + final += (l_p + l_n) * l_g; + } + return final; +} + +technique Gaussian +{ + pass + { + vertex_shader = VSDefault(vtx); + pixel_shader = PSGaussianBlur(vtx); + } +} + +/// Blur: Bilateral +float Bilateral(float x, float sigma) { + return 0.39894 * exp(-0.5 * (x*x) / (sigma*sigma)) / sigma; +} + +float Bilateral3(float3 v, float sigma) { + // First part is Bilateral function (1.0 / (o * sqrt(2.0 * pivalue))) with o = 1 + return 0.39894 * exp(-0.5 * dot(v,v) / (sigma*sigma)) / sigma; +} + +float4 PSBilateralBlur(VertDataOut vtx) : TARGET { + float4 origin = u_image.SampleLevel(pointSampler, vtx.uv, 0); + float2 uvOffset = float2(0, 0); + + float Z = 0.0; + float bZ = 1.0 / Bilateral(0.0, bilateralSharpness); + float3 color = float3(0, 0, 0); + for (int k = 1; k <= u_radius; k++) { + uvOffset += u_texelDelta; + + // Bilateral Kernel + float bKernel = Bilateral(abs(k), bilateralSmoothing); + bKernel *= bKernel; + float bZKernel = bZ * bKernel; + + // Sample Color + float3 l_p = u_image.SampleLevel(pointSampler, vtx.uv + uvOffset, 0).rgb; + float3 l_n = u_image.SampleLevel(pointSampler, vtx.uv - uvOffset, 0).rgb; + + // Bilateral Stuff + float l_factor_p = Bilateral3(l_p - origin.rgb, bilateralSharpness) * bZKernel; + float l_factor_n = Bilateral3(l_n - origin.rgb, bilateralSharpness) * bZKernel; + Z = Z + l_factor_p + l_factor_n; + + // Store Color + color += l_p * l_factor_p; + color += l_n * l_factor_n; + } + + return float4(color.rgb / Z, origin.a); +} + +technique Bilateral +{ + pass + { + vertex_shader = VSDefault(vtx); + pixel_shader = PSBilateralBlur(vtx); + } +} diff --git a/data/effects/box-blur.effect b/data/effects/box-blur.effect deleted file mode 100644 index 45be7d1..0000000 --- a/data/effects/box-blur.effect +++ /dev/null @@ -1,61 +0,0 @@ -// Parameters -/// OBS -uniform float4x4 ViewProj; -/// Blur -uniform texture2d u_image; -uniform float2 u_imageSize; -uniform float2 u_imageTexel; -uniform int u_radius; -uniform int u_diameter; -uniform float2 u_texelDelta; - -// Data -sampler_state pointSampler { - Filter = Point; - AddressU = Clamp; - AddressV = Clamp; - MinLOD = 0; - MaxLOD = 0; -}; - -struct VertDataIn { - float4 pos : POSITION; - float2 uv : TEXCOORD0; -}; - -struct VertDataOut { - float4 pos : POSITION; - float2 uv : TEXCOORD0; -}; - -VertDataOut VSDefault(VertDataIn v_in) -{ - VertDataOut vert_out; - vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); - vert_out.uv = v_in.uv; - return vert_out; -} - -// Box Blur -float4 BlurFunc(float2 uv, float4 rgba) { - float4 final = rgba; - for (int k = 1; k <= u_radius; k++) { - final += u_image.SampleLevel(pointSampler, uv + (u_texelDelta * k), 0); - final += u_image.SampleLevel(pointSampler, uv - (u_texelDelta * k), 0); - } - return final / u_diameter; -} - -float4 PSBox(VertDataOut v_in) : TARGET { - float4 rgba = u_image.SampleLevel(pointSampler, v_in.uv, 0); - return BlurFunc(v_in.uv, rgba); -} - -technique Draw -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSBox(v_in); - } -} diff --git a/data/effects/gaussian-blur.effect b/data/effects/gaussian-blur.effect deleted file mode 100644 index 58196f2..0000000 --- a/data/effects/gaussian-blur.effect +++ /dev/null @@ -1,68 +0,0 @@ -// OBS Default -uniform float4x4 ViewProj; - -// Settings (Shared) -uniform texture2d u_image; -uniform float2 u_imageSize; -uniform float2 u_imageTexel; -uniform int u_radius; -uniform int u_diameter; -uniform float2 u_texelDelta; - -// Settings (Private) -//uniform float registerkernel[25]; -uniform texture2d kernel; -uniform float2 kernelTexel; - -sampler_state textureSampler { - Filter = Point; - AddressU = Clamp; - AddressV = Clamp; - MinLOD = 0; - MaxLOD = 0; -}; - -struct VertDataIn { - float4 pos : POSITION; - float2 uv : TEXCOORD0; -}; - -struct VertDataOut { - float4 pos : POSITION; - float2 uv : TEXCOORD0; -}; - -VertDataOut VSDefault(VertDataIn v_in) -{ - VertDataOut vert_out; - vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); - vert_out.uv = v_in.uv; - return vert_out; -} - -float4 BlurFunc(float2 uv, float4 rgba) { - float2 uvOffset = float2(0, 0); - float4 final = rgba * kernel.SampleLevel(textureSampler, (float2(0, u_radius - 1) * kernelTexel), 0).r; - for (int k = 1; k <= u_radius; k++) { - uvOffset += u_texelDelta; - float l_g = kernel.SampleLevel(textureSampler, (float2(k, u_radius - 1) * kernelTexel), 0).r; - float4 l_p = u_image.SampleLevel(textureSampler, uv + uvOffset, 0); - float4 l_n = u_image.SampleLevel(textureSampler, uv - uvOffset, 0); - final += (l_p + l_n) * l_g; - } - return final; -} - -float4 PSGaussian(VertDataOut v_in) : TARGET { - float4 rgba = u_image.SampleLevel(textureSampler, v_in.uv, 0); - return BlurFunc(v_in.uv, rgba); -} - -technique Draw -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSGaussian(v_in); - } -} diff --git a/data/effects/mip-mapper.effect b/data/effects/mip-mapper.effect deleted file mode 100644 index 13efe8c..0000000 --- a/data/effects/mip-mapper.effect +++ /dev/null @@ -1,49 +0,0 @@ -uniform matrix4 ViewProj; - -uniform texture2d image; -uniform float2 imageTexel; -uniform int layer; - -sampler_state textureSampler { - Filter = Point; - AddressU = Clamp; - AddressV = Clamp; -}; - -struct VertDataIn { - float4 pos : POSITION; - float2 uv : TEXCOORD0; -}; - -struct VertDataOut { - float4 pos : POSITION; - float2 uv : TEXCOORD0; -}; - -VertDataOut VSDefault(VertDataIn v_in) -{ - VertDataOut vert_out; - vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); - vert_out.uv = v_in.uv; - return vert_out; -} - -float4 PSAverage(VertDataOut v_in) : TARGET -{ - float4 rgba = 0; - for (float x = -1; x <= 1; x++) { - for (float y = -1; y <= 1; y++) { - rgba += image.Sample(textureSampler, v_in.uv + vec2(x,y) * imageTexel + imageTexel); - } - } - return rgba / 9.0; -} - -technique Draw -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSAverage(v_in); - } -} diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 7fb072b..b0672ad 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -28,8 +28,9 @@ CustomShader.Texture.Type.Source="Source" # Filter - Blur Filter.Blur="Blur" Filter.Blur.Type="Type" -Filter.Blur.Type.Description="The type of blur to apply:\n- 'Box' smoothes pixels equally.\n- 'Gaussian' applies a gaussian curve to the smoothed pixels.\n- 'Bilateral' is an edge detection variant of 'Gaussian'." +Filter.Blur.Type.Description="The type of blur to apply:\n- 'Box' smoothes pixels equally.\n- 'Box Linear' uses linear sampling to reduce the GPU usage, sacrificing minimal quality.\n- 'Gaussian' applies a gaussian curve to the smoothed pixels.\n- 'Bilateral' is an edge detection variant of 'Gaussian'." Filter.Blur.Type.Box="Box" +Filter.Blur.Type.BoxLinear="Box Linear" Filter.Blur.Type.Gaussian="Gaussian" Filter.Blur.Type.Bilateral="Bilateral" Filter.Blur.Size="Size (Pixel)" diff --git a/source/filter-blur.cpp b/source/filter-blur.cpp index d500d03..e9b4e96 100644 --- a/source/filter-blur.cpp +++ b/source/filter-blur.cpp @@ -39,6 +39,7 @@ extern "C" { #define P_TYPE "Filter.Blur.Type" #define P_TYPE_BOX "Filter.Blur.Type.Box" +#define P_TYPE_BOXLINEAR "Filter.Blur.Type.BoxLinear" #define P_TYPE_GAUSSIAN "Filter.Blur.Type.Gaussian" #define P_TYPE_BILATERAL "Filter.Blur.Type.Bilateral" #define P_SIZE "Filter.Blur.Size" @@ -137,8 +138,8 @@ bool filter::blur::blur_instance::apply_gaussian_param() return true; } -bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptr effect, gs_texture_t* original_texture, - gs_texture_t* blurred_texture) +bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptr effect, + gs_texture_t* original_texture, gs_texture_t* blurred_texture) { if (effect->has_parameter("image_orig")) { effect->get_parameter("image_orig").set_texture(original_texture); @@ -203,7 +204,7 @@ bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptrenum_scenes([this, p](obs_scene_t* scene) { struct data { - blur_instance* self; + blur_instance* self; obs_property_t* prop; std::string parent_name; }; @@ -394,9 +396,10 @@ obs_properties_t* filter::blur::blur_instance::get_properties() void filter::blur::blur_instance::update(obs_data_t* settings) { - type = (blur::type)obs_data_get_int(settings, P_TYPE); - blur_effect = blur_factory::get()->get_effect(type); - size = (uint64_t)obs_data_get_int(settings, P_SIZE); + type = (blur::type)obs_data_get_int(settings, P_TYPE); + blur_effect = blur_factory::get()->get_effect(type); + blur_technique = blur_factory::get()->get_technique(type); + size = (uint64_t)obs_data_get_int(settings, P_SIZE); // bilateral blur bilateral_smoothing = obs_data_get_double(settings, P_BILATERAL_SMOOTHING) / 100.0; @@ -620,8 +623,6 @@ void filter::blur::blur_instance::video_render(gs_effect_t* effect) std::make_tuple("Vertical", vertical_rendertarget, 0.0f, 1.0f / baseH), }; - std::string pass = "Draw"; - for (auto v : kvs) { const char* name = std::get<0>(v); gs_texrender_t* rt = std::get<1>(v); @@ -649,7 +650,7 @@ void filter::blur::blur_instance::video_render(gs_effect_t* effect) gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0); // Render - while (gs_effect_loop(blur_effect->get_object(), pass.c_str())) { + while (gs_effect_loop(this->blur_effect->get_object(), this->blur_technique.c_str())) { gs_draw_sprite(intermediate, 0, baseW, baseH); } @@ -812,27 +813,9 @@ void filter::blur::blur_factory::on_list_fill() obs_enter_graphics(); { - char* file = obs_module_file("effects/box-blur.effect"); + char* file = obs_module_file("effects/blur.effect"); try { - effects.insert_or_assign(type::Box, std::make_shared(file)); - } catch (std::runtime_error ex) { - P_LOG_ERROR(" Loading effect '%s' failed with error(s): %s", file, ex.what()); - } - bfree(file); - } - { - char* file = obs_module_file("effects/gaussian-blur.effect"); - try { - effects.insert_or_assign(type::Gaussian, std::make_shared(file)); - } catch (std::runtime_error ex) { - P_LOG_ERROR(" Loading effect '%s' failed with error(s): %s", file, ex.what()); - } - bfree(file); - } - { - char* file = obs_module_file("effects/bilateral-blur.effect"); - try { - effects.insert_or_assign(type::Bilateral, std::make_shared(file)); + blur_effect = std::make_shared(file); } catch (std::runtime_error ex) { P_LOG_ERROR(" Loading effect '%s' failed with error(s): %s", file, ex.what()); } @@ -864,7 +847,7 @@ void filter::blur::blur_factory::on_list_fill() void filter::blur::blur_factory::on_list_empty() { obs_enter_graphics(); - effects.clear(); + blur_effect.reset(); kernels.clear(); color_converter_effect.reset(); mask_effect.reset(); @@ -1013,7 +996,7 @@ void filter::blur::blur_factory::video_render(void* inptr, gs_effect_t* effect) void filter::blur::blur_factory::scene_create_handler(void* ptr, calldata_t* data) { filter::blur::blur_factory* self = reinterpret_cast(ptr); - obs_source_t* source = nullptr; + obs_source_t* source = nullptr; calldata_get_ptr(data, "source", &source); obs_scene_t* scene = obs_scene_from_source(source); if (scene) { @@ -1024,7 +1007,7 @@ void filter::blur::blur_factory::scene_create_handler(void* ptr, calldata_t* dat void filter::blur::blur_factory::scene_destroy_handler(void* ptr, calldata_t* data) { filter::blur::blur_factory* self = reinterpret_cast(ptr); - obs_source_t* source = nullptr; + obs_source_t* source = nullptr; calldata_get_ptr(data, "source", &source); obs_scene_t* scene = obs_scene_from_source(source); if (scene) { @@ -1034,7 +1017,22 @@ void filter::blur::blur_factory::scene_destroy_handler(void* ptr, calldata_t* da std::shared_ptr filter::blur::blur_factory::get_effect(filter::blur::type type) { - return effects.at(type); + return blur_effect; +} + +std::string filter::blur::blur_factory::get_technique(filter::blur::type type) +{ + switch (type) { + case type::Box: + return "Box"; + case type::BoxLinear: + return "BoxLinear"; + case type::Gaussian: + return "Gaussian"; + case type::Bilateral: + return "Bilateral"; + } + return ""; } std::shared_ptr filter::blur::blur_factory::get_color_converter_effect() diff --git a/source/filter-blur.h b/source/filter-blur.h index fd9e52b..28a36da 100644 --- a/source/filter-blur.h +++ b/source/filter-blur.h @@ -42,6 +42,7 @@ namespace filter { namespace blur { enum type : int64_t { Box, + BoxLinear, Gaussian, Bilateral, }; @@ -61,6 +62,7 @@ namespace filter { // blur std::shared_ptr blur_effect; + std::string blur_technique; filter::blur::type type; uint64_t size; @@ -134,11 +136,11 @@ namespace filter { class blur_factory { obs_source_info source_info; - std::list sources; + std::list sources; std::shared_ptr color_converter_effect; std::shared_ptr mask_effect; - std::map> effects; + std::shared_ptr blur_effect; std::map> kernels; std::map scenes; @@ -177,6 +179,8 @@ namespace filter { public: std::shared_ptr get_effect(filter::blur::type type); + std::string get_technique(filter::blur::type type); + std::shared_ptr get_color_converter_effect(); std::shared_ptr get_mask_effect(); @@ -188,8 +192,8 @@ namespace filter { void enum_scenes(std::function fnc); public: // Singleton - static void initialize(); - static void finalize(); + static void initialize(); + static void finalize(); static blur_factory* get(); };