diff --git a/data/shaders/circle-mask.effect b/data/shaders/circle-mask.effect index a9daa41..15eaa70 100644 --- a/data/shaders/circle-mask.effect +++ b/data/shaders/circle-mask.effect @@ -55,7 +55,7 @@ float4 alphaImage(VertData v_in) : TARGET float d = SDF(dist, radius); d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -71,24 +71,18 @@ float4 alphaFrameCheckImage(VertData v_in) : TARGET sample_uv.y >= 0.0f && sample_uv.y <= 1.0f ? 1.0f : 0.0f; d = feather_amount > 0.0f ? smoothstep(alpha_zero * alpha_scale, feather_amount, -d + feather_amount) : clamp(-d, alpha_zero * alpha_scale, 1.0f); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } float4 adjustmentsImage(VertData v_in) : TARGET { - //float2 coord = v_in.uv * uv_size; - //float2 dist = coord - mask_position; - //float2 sample_dist = float2(dist.x * cos_theta - dist.y * sin_theta, dist.x * sin_theta + dist.y * cos_theta); - //float d = SDF(sample_dist, float2(width, height), corner_radius) + feather_shift; - //d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d) : saturate(-d); - float2 coord = v_in.uv * uv_size; float2 dist = coord - mask_position; float d = SDF(dist, radius); d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); float4 color_adj_min = adjustments( color, min_brightness, diff --git a/data/shaders/ellipse-mask.effect b/data/shaders/ellipse-mask.effect index 6f0575d..98765f3 100644 --- a/data/shaders/ellipse-mask.effect +++ b/data/shaders/ellipse-mask.effect @@ -95,7 +95,7 @@ float4 alphaImage(VertData v_in) : TARGET float d = SDF(sample_dist, ellipse); d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -112,7 +112,7 @@ float4 alphaFrameCheckImage(VertData v_in) : TARGET sample_uv.y >= 0.0f && sample_uv.y <= 1.0f ? 1.0f : 0.0f; d = feather_amount > 0.0f ? smoothstep(alpha_zero * alpha_scale, feather_amount, -d + feather_amount) : clamp(-d, alpha_zero * alpha_scale, 1.0f); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -125,7 +125,7 @@ float4 adjustmentsImage(VertData v_in) : TARGET float d = SDF(sample_dist, ellipse); d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); float4 color_adj_min = adjustments( color, min_brightness, diff --git a/data/shaders/gradient-mask.effect b/data/shaders/gradient-mask.effect index 618ec47..0a34f76 100644 --- a/data/shaders/gradient-mask.effect +++ b/data/shaders/gradient-mask.effect @@ -51,7 +51,7 @@ float4 mainAlphaImage(VertData v_in) : TARGET ); float alpha = saturate((coord_p.x - position + width / 2.0f) / width); - float4 col = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 col = image.Sample(textureSampler, v_in.uv); return float4(col.rgb, col.a * (invert ? 1.0f - alpha : alpha)); } @@ -70,7 +70,7 @@ float4 mainAdjustmentsImage(VertData v_in) : TARGET float scale = saturate((coord_p.x - position + width / 2.0f) / width); scale = invert ? 1.0f - scale : scale; - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); color = adjustments( color, @@ -98,7 +98,7 @@ float4 debugAlphaImage(VertData v_in) : TARGET float alpha = saturate((coord_p.x - position + width / 2.0f) / width); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); if (coord_p.x - position > -(width / 2.0f + 2.0f) && coord_p.x - position < -(width / 2.0f)) { return float4(0.0f, 1.0f, 0.0f, 1.0f); @@ -131,7 +131,7 @@ float4 debugAdjustmentsImage(VertData v_in) : TARGET float scale = saturate((coord_p.x - position + width / 2.0f) / width); scale = invert ? 1.0f - scale : scale; - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); if (coord_p.x - position > -(width / 2.0f + 2.0f) && coord_p.x - position < -(width / 2.0f)) { return float4(0.0f, 1.0f, 0.0f, 1.0f); diff --git a/data/shaders/heart-mask.effect b/data/shaders/heart-mask.effect index 93487a4..8d395c8 100644 --- a/data/shaders/heart-mask.effect +++ b/data/shaders/heart-mask.effect @@ -73,7 +73,7 @@ float4 alphaImage(VertData v_in) : TARGET float d = SDF(sample_dist) - corner_radius; d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -90,7 +90,7 @@ float4 alphaFrameCheckImage(VertData v_in) : TARGET sample_uv.y >= 0.0f && sample_uv.y <= 1.0f ? 1.0f : 0.0f; d = feather_amount > 0.0f ? smoothstep(alpha_zero * alpha_scale, feather_amount, -d + feather_amount) : clamp(-d, alpha_zero * alpha_scale, 1.0f); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -102,7 +102,7 @@ float4 adjustmentsImage(VertData v_in) : TARGET float d = SDF(sample_dist) - corner_radius; d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); float4 color_adj_min = adjustments( color, min_brightness, diff --git a/data/shaders/polygon-mask.effect b/data/shaders/polygon-mask.effect index 27db053..159f0e7 100644 --- a/data/shaders/polygon-mask.effect +++ b/data/shaders/polygon-mask.effect @@ -68,7 +68,7 @@ float4 alphaImage(VertData v_in) : TARGET float d = SDF(sample_dist, num_sides, radius) - corner_radius; d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -85,7 +85,7 @@ float4 alphaFrameCheckImage(VertData v_in) : TARGET sample_uv.y >= 0.0f && sample_uv.y <= 1.0f ? 1.0f : 0.0f; d = feather_amount > 0.0f ? smoothstep(alpha_zero * alpha_scale, feather_amount, -d + feather_amount) : clamp(-d, alpha_zero * alpha_scale, 1.0f); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -96,7 +96,7 @@ float4 adjustmentsImage(VertData v_in) : TARGET float2 sample_dist = float2(dist.x * cos_rot - dist.y * sin_rot, dist.x * sin_rot + dist.y * cos_rot); float d = SDF(sample_dist, num_sides, radius) - corner_radius; d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); float4 color_adj_min = adjustments( color, min_brightness, diff --git a/data/shaders/rectangular-mask.effect b/data/shaders/rectangular-mask.effect index 3c13249..1aba0bc 100644 --- a/data/shaders/rectangular-mask.effect +++ b/data/shaders/rectangular-mask.effect @@ -75,7 +75,7 @@ float4 alphaImage(VertData v_in) : TARGET float d = SDF(sample_dist, float2(width, height), corner_radius); d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -92,7 +92,7 @@ float4 alphaFrameCheckImage(VertData v_in) : TARGET sample_uv.y >= 0.0f && sample_uv.y <= 1.0f ? 1.0f : 0.0f; d = feather_amount > 0.0f ? smoothstep(alpha_zero * alpha_scale, feather_amount, -d + feather_amount) : clamp(-d, alpha_zero * alpha_scale, 1.0f); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -103,7 +103,7 @@ float4 adjustmentsImage(VertData v_in) : TARGET float2 sample_dist = float2(dist.x * cos_theta - dist.y * sin_theta, dist.x * sin_theta + dist.y * cos_theta); float d = SDF(sample_dist, float2(width, height), corner_radius) + feather_shift; d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); float4 color_adj_min = adjustments( color, min_brightness, diff --git a/data/shaders/render_output.effect b/data/shaders/render_output.effect new file mode 100644 index 0000000..6684de8 --- /dev/null +++ b/data/shaders/render_output.effect @@ -0,0 +1,49 @@ +uniform float4x4 ViewProj; +uniform texture2d image; +uniform texture2d output_image; + +sampler_state textureSampler{ + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; + MinLOD = 0; + MaxLOD = 0; +}; + +struct VertData +{ + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertData mainTransform(VertData v_in) +{ + v_in.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); + return v_in; +} + +float srgb_nonlinear_to_linear_channel(float u) +{ + return (u <= 0.04045) ? (u / 12.92) : pow((u + 0.055) / 1.055, 2.4); +} + +float3 srgb_nonlinear_to_linear(float3 v) +{ + return float3(srgb_nonlinear_to_linear_channel(v.r), srgb_nonlinear_to_linear_channel(v.g), srgb_nonlinear_to_linear_channel(v.b)); +} + +float4 mainImage(VertData v_in) : TARGET +{ + float4 px = output_image.Sample(textureSampler, v_in.uv); + px.xyz = srgb_nonlinear_to_linear(px.xyz); + return px; +} + +technique Draw +{ + pass + { + vertex_shader = mainTransform(v_in); + pixel_shader = mainImage(v_in); + } +} diff --git a/data/shaders/source-mask.effect b/data/shaders/source-mask.effect index 588e1fa..d6b8871 100644 --- a/data/shaders/source-mask.effect +++ b/data/shaders/source-mask.effect @@ -43,18 +43,18 @@ VertData mainTransform(VertData v_in) float4 alphaImage(VertData v_in) : TARGET { - float4 mask = pmrgba_to_rgba(source_image.Sample(textureSampler, v_in.uv)); + float4 mask = source_image.Sample(textureSampler, v_in.uv); float alpha = multiplier * (mask.r * channel_multipliers.r + mask.g * channel_multipliers.g + mask.b * channel_multipliers.b + mask.a * channel_multipliers.a); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); return float4(color.rgb, color.a * (invert ? 1.0 - alpha : alpha)); } float4 adjustmentsImage(VertData v_in) : TARGET { - float4 mask = pmrgba_to_rgba(source_image.Sample(textureSampler, v_in.uv)); + float4 mask = source_image.Sample(textureSampler, v_in.uv); float scale = multiplier * (mask.r * channel_multipliers.r + mask.g * channel_multipliers.g + mask.b * channel_multipliers.b + mask.a * channel_multipliers.a); scale = invert ? 1.0 - scale : scale; - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); color = adjustments( color, lerp(min_brightness, max_brightness, scale), @@ -67,20 +67,20 @@ float4 adjustmentsImage(VertData v_in) : TARGET float4 alphaThresholdImage(VertData v_in) : TARGET { - float4 mask = pmrgba_to_rgba(source_image.Sample(textureSampler, v_in.uv)); + float4 mask = source_image.Sample(textureSampler, v_in.uv); float alpha = multiplier * (mask.r * channel_multipliers.r + mask.g * channel_multipliers.g + mask.b * channel_multipliers.b + mask.a * channel_multipliers.a); alpha = step(threshold_value, alpha); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); return float4(color.rgb, color.a * (invert ? 1.0 - alpha : alpha)); } float4 adjustmentsThresholdImage(VertData v_in) : TARGET { - float4 mask = pmrgba_to_rgba(source_image.Sample(textureSampler, v_in.uv)); + float4 mask = source_image.Sample(textureSampler, v_in.uv); float scale = multiplier * (mask.r * channel_multipliers.r + mask.g * channel_multipliers.g + mask.b * channel_multipliers.b + mask.a * channel_multipliers.a); scale = step(threshold_value, scale); scale = invert ? 1.0 - scale : scale; - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); color = adjustments( color, lerp(min_brightness, max_brightness, scale), @@ -93,20 +93,20 @@ float4 adjustmentsThresholdImage(VertData v_in) : TARGET float4 alphaRangeImage(VertData v_in) : TARGET { - float4 mask = pmrgba_to_rgba(source_image.Sample(textureSampler, v_in.uv)); + float4 mask = source_image.Sample(textureSampler, v_in.uv); float alpha = multiplier * (mask.r * channel_multipliers.r + mask.g * channel_multipliers.g + mask.b * channel_multipliers.b + mask.a * channel_multipliers.a); alpha = smoothstep(range_min, range_max, alpha); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); return float4(color.rgb, color.a * (invert ? 1.0 - alpha : alpha)); } float4 adjustmentsRangeImage(VertData v_in) : TARGET { - float4 mask = pmrgba_to_rgba(source_image.Sample(textureSampler, v_in.uv)); + float4 mask = source_image.Sample(textureSampler, v_in.uv); float scale = multiplier * (mask.r * channel_multipliers.r + mask.g * channel_multipliers.g + mask.b * channel_multipliers.b + mask.a * channel_multipliers.a); scale = smoothstep(range_min, range_max, scale); scale = invert ? 1.0 - scale : scale; - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); color = adjustments( color, lerp(min_brightness, max_brightness, scale), diff --git a/data/shaders/star-mask.effect b/data/shaders/star-mask.effect index 801406d..503f729 100644 --- a/data/shaders/star-mask.effect +++ b/data/shaders/star-mask.effect @@ -74,7 +74,7 @@ float4 alphaImage(VertData v_in) : TARGET float d = SDF(sample_dist, radius) - corner_radius; d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -91,7 +91,7 @@ float4 alphaFrameCheckImage(VertData v_in) : TARGET sample_uv.y >= 0.0f && sample_uv.y <= 1.0f ? 1.0f : 0.0f; d = feather_amount > 0.0f ? smoothstep(alpha_zero * alpha_scale, feather_amount, -d + feather_amount) : clamp(-d, alpha_zero * alpha_scale, 1.0f); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size)); + float4 color = image.Sample(textureSampler, (mask_position + dist / zoom / global_scale) / uv_size); return float4(color.rgb, color.a * d); } @@ -103,7 +103,7 @@ float4 adjustmentsImage(VertData v_in) : TARGET float d = SDF(dist, radius) - corner_radius; d = feather_amount > 0.0f ? smoothstep(0.0f, feather_amount, -d + feather_amount) : saturate(-d); - float4 color = pmrgba_to_rgba(image.Sample(textureSampler, v_in.uv)); + float4 color = image.Sample(textureSampler, v_in.uv); float4 color_adj_min = adjustments( color, min_brightness, diff --git a/src/advanced-masks-filter.c b/src/advanced-masks-filter.c index cd2f452..842e76d 100644 --- a/src/advanced-masks-filter.c +++ b/src/advanced-masks-filter.c @@ -38,12 +38,15 @@ static void *advanced_masks_create(obs_data_t *settings, obs_source_t *source) create_or_reset_texrender(filter->base->input_texrender); filter->base->output_texrender = create_or_reset_texrender(filter->base->output_texrender); + filter->base->param_output_image = NULL; filter->base->rendered = false; filter->base->rendering = false; filter->color_adj_data = bzalloc(sizeof(color_adjustments_data_t)); + load_output_effect(filter); obs_source_update(source, settings); + return filter; } @@ -63,6 +66,9 @@ static void advanced_masks_destroy(void *data) if (filter->base->output_texrender) { gs_texrender_destroy(filter->base->output_texrender); } + if (filter->base->output_effect) { + gs_effect_destroy(filter->base->output_effect); + } obs_leave_graphics(); bfree(filter->base); @@ -136,6 +142,10 @@ static void advanced_masks_video_render(void *data, gs_effect_t *effect) // Call a rendering functioner, e.g.: render_mask(filter); + //gs_texrender_t *tmp = filter->base->output_texrender; + //filter->base->output_texrender = filter->base->input_texrender; + //filter->base->input_texrender = tmp; + // 3. Draw result (filter->output_texrender) to source draw_output(filter); filter->base->rendered = true; @@ -345,41 +355,127 @@ static void advanced_masks_defaults(obs_data_t *settings) mask_source_defaults(settings); } +//static void get_input_source(advanced_masks_data_t *filter) +//{ +// gs_effect_t *pass_through = obs_get_base_effect(OBS_EFFECT_DEFAULT); +// +// filter->base->input_texrender = +// create_or_reset_texrender(filter->base->input_texrender); +// if (obs_source_process_filter_begin(filter->context, GS_RGBA, +// OBS_ALLOW_DIRECT_RENDERING) && +// gs_texrender_begin(filter->base->input_texrender, +// filter->base->width, filter->base->height)) { +// +// set_blending_parameters(); +// gs_ortho(0.0f, (float)filter->base->width, 0.0f, +// (float)filter->base->height, -100.0f, 100.0f); +// obs_source_process_filter_end(filter->context, pass_through, +// filter->base->width, +// filter->base->height); +// gs_texrender_end(filter->base->input_texrender); +// gs_blend_state_pop(); +// filter->base->input_texture_generated = true; +// } +//} + static void get_input_source(advanced_masks_data_t *filter) { + // Use the OBS default effect file as our effect. gs_effect_t *pass_through = obs_get_base_effect(OBS_EFFECT_DEFAULT); + // Set up our color space info. + const enum gs_color_space preferred_spaces[] = { + GS_CS_SRGB, + GS_CS_SRGB_16F, + GS_CS_709_EXTENDED, + }; + + const enum gs_color_space source_space = obs_source_get_color_space( + obs_filter_get_target(filter->context), + OBS_COUNTOF(preferred_spaces), preferred_spaces); + + const enum gs_color_format format = + gs_get_format_from_space(source_space); + + // Set up our input_texrender to catch the output texture. filter->base->input_texrender = create_or_reset_texrender(filter->base->input_texrender); - if (obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING) && - gs_texrender_begin(filter->base->input_texrender, - filter->base->width, filter->base->height)) { + + // Start the rendering process with our correct color space params, + // And set up your texrender to recieve the created texture. + if (obs_source_process_filter_begin_with_color_space( + filter->context, format, source_space, + OBS_ALLOW_DIRECT_RENDERING) && + gs_texrender_begin(filter->base->input_texrender, filter->base->width, + filter->base->height)) { set_blending_parameters(); gs_ortho(0.0f, (float)filter->base->width, 0.0f, (float)filter->base->height, -100.0f, 100.0f); - obs_source_process_filter_end(filter->context, pass_through, - filter->base->width, - filter->base->height); + // The incoming source is pre-multiplied alpha, so use the + // OBS default effect "DrawAlphaDivide" technique to convert + // the colors back into non-pre-multiplied space. + obs_source_process_filter_tech_end(filter->context, + pass_through, filter->base->width, + filter->base->height, + "DrawAlphaDivide"); gs_texrender_end(filter->base->input_texrender); gs_blend_state_pop(); filter->base->input_texture_generated = true; } } +//static void draw_output(advanced_masks_data_t *filter) +//{ +// gs_texture_t *texture = +// gs_texrender_get_texture(filter->base->output_texrender); +// gs_effect_t *pass_through = obs_get_base_effect(OBS_EFFECT_DEFAULT); +// gs_eparam_t *param = gs_effect_get_param_by_name(pass_through, "image"); +// gs_effect_set_texture(param, texture); +// uint32_t width = gs_texture_get_width(texture); +// uint32_t height = gs_texture_get_height(texture); +// while (gs_effect_loop(pass_through, "Draw")) { +// gs_draw_sprite(texture, 0, width, height); +// } +//} + static void draw_output(advanced_masks_data_t *filter) { + const enum gs_color_space preferred_spaces[] = { + GS_CS_SRGB, + GS_CS_SRGB_16F, + GS_CS_709_EXTENDED, + }; + + const enum gs_color_space source_space = obs_source_get_color_space( + obs_filter_get_target(filter->context), + OBS_COUNTOF(preferred_spaces), preferred_spaces); + + const enum gs_color_format format = + gs_get_format_from_space(source_space); + + if (!obs_source_process_filter_begin_with_color_space( + filter->context, format, source_space, + OBS_ALLOW_DIRECT_RENDERING)) { + return; + } + gs_texture_t *texture = gs_texrender_get_texture(filter->base->output_texrender); - gs_effect_t *pass_through = obs_get_base_effect(OBS_EFFECT_DEFAULT); - gs_eparam_t *param = gs_effect_get_param_by_name(pass_through, "image"); - gs_effect_set_texture(param, texture); - uint32_t width = gs_texture_get_width(texture); - uint32_t height = gs_texture_get_height(texture); - while (gs_effect_loop(pass_through, "Draw")) { - gs_draw_sprite(texture, 0, width, height); + gs_effect_t *pass_through = filter->base->output_effect; + + if (filter->base->param_output_image) { + gs_effect_set_texture(filter->base->param_output_image, texture); } + + gs_blend_state_push(); + gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + + obs_source_process_filter_end(filter->context, pass_through, + filter->base->width, + filter->base->height); + gs_blend_state_pop(); } static void advanced_masks_render_filter(advanced_masks_data_t *filter) @@ -388,3 +484,48 @@ static void advanced_masks_render_filter(advanced_masks_data_t *filter) filter->base->output_texrender = filter->base->input_texrender; filter->base->input_texrender = tmp; } + +static void load_output_effect(advanced_masks_data_t *filter) +{ + if (filter->base->output_effect != NULL) { + obs_enter_graphics(); + gs_effect_destroy(filter->base->output_effect); + filter->base->output_effect = NULL; + obs_leave_graphics(); + } + + char *shader_text = NULL; + struct dstr filename = {0}; + dstr_cat(&filename, obs_get_module_data_path(obs_current_module())); + dstr_cat(&filename, "/shaders/render_output.effect"); + shader_text = load_shader_from_file(filename.array); + char *errors = NULL; + dstr_free(&filename); + + obs_enter_graphics(); + filter->base->output_effect = + gs_effect_create(shader_text, NULL, &errors); + obs_leave_graphics(); + + bfree(shader_text); + if (filter->base->output_effect == NULL) { + blog(LOG_WARNING, + "[obs-composite-blur] Unable to load output.effect file. Errors:\n%s", + (errors == NULL || strlen(errors) == 0 ? "(None)" + : errors)); + bfree(errors); + } else { + size_t effect_count = + gs_effect_get_num_params(filter->base->output_effect); + for (size_t effect_index = 0; effect_index < effect_count; + effect_index++) { + gs_eparam_t *param = gs_effect_get_param_by_idx( + filter->base->output_effect, effect_index); + struct gs_effect_param_info info; + gs_effect_get_param_info(param, &info); + if (strcmp(info.name, "output_image") == 0) { + filter->base->param_output_image = param; + } + } + } +} diff --git a/src/advanced-masks-filter.h b/src/advanced-masks-filter.h index c91cd1f..245cf35 100644 --- a/src/advanced-masks-filter.h +++ b/src/advanced-masks-filter.h @@ -30,3 +30,4 @@ static bool setting_mask_adjustment_modified(obs_properties_t *props, static bool setting_mask_type_modified(void *data, obs_properties_t *props, obs_property_t *p, obs_data_t *settings); +static void load_output_effect(advanced_masks_data_t *filter); diff --git a/src/base-filter.h b/src/base-filter.h index fadcbb7..c556572 100644 --- a/src/base-filter.h +++ b/src/base-filter.h @@ -28,6 +28,8 @@ struct base_filter_data { gs_texrender_t *input_texrender; bool output_rendered; gs_texrender_t *output_texrender; + gs_effect_t *output_effect; + gs_eparam_t *param_output_image; bool rendered; bool rendering; diff --git a/src/color-adjustments.c b/src/color-adjustments.c index 7f73b26..124635e 100644 --- a/src/color-adjustments.c +++ b/src/color-adjustments.c @@ -126,8 +126,8 @@ static bool setting_mask_adjustment_modified(obs_properties_t *props, void color_adjustments_defaults(obs_data_t* settings) { obs_data_set_default_bool(settings, "brightness", false); - obs_data_set_default_double(settings, "min_brightness_value", -1.0); - obs_data_set_default_double(settings, "max_brightness_value", 1.0); + obs_data_set_default_double(settings, "min_brightness_value", 0.0); + obs_data_set_default_double(settings, "max_brightness_value", 0.2); obs_data_set_default_bool(settings, "contrast", false); obs_data_set_default_double(settings, "min_contrast_value", 0.0); obs_data_set_default_double(settings, "max_contrast_value", 1.0);