From 4b781c7b04f754ef9986ddf6608bb3f7034374a5 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sun, 3 Jan 2016 17:20:15 -0800 Subject: [PATCH] obs-transitions: Implement fade transition A basic fade transition that fades to/from a source via a simple cross fade. --- plugins/CMakeLists.txt | 1 + plugins/obs-transitions/CMakeLists.txt | 13 +++ .../data/fade_transition.effect | 39 +++++++ plugins/obs-transitions/data/locale/en-US.ini | 1 + plugins/obs-transitions/obs-transitions.c | 13 +++ plugins/obs-transitions/transition-fade.c | 100 ++++++++++++++++++ 6 files changed, 167 insertions(+) create mode 100644 plugins/obs-transitions/CMakeLists.txt create mode 100644 plugins/obs-transitions/data/fade_transition.effect create mode 100644 plugins/obs-transitions/data/locale/en-US.ini create mode 100644 plugins/obs-transitions/obs-transitions.c create mode 100644 plugins/obs-transitions/transition-fade.c diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index f11052281..4e80a6346 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -35,5 +35,6 @@ add_subdirectory(obs-libfdk) add_subdirectory(obs-ffmpeg) add_subdirectory(obs-outputs) add_subdirectory(obs-filters) +add_subdirectory(obs-transitions) add_subdirectory(rtmp-services) add_subdirectory(text-freetype2) diff --git a/plugins/obs-transitions/CMakeLists.txt b/plugins/obs-transitions/CMakeLists.txt new file mode 100644 index 000000000..059ea1899 --- /dev/null +++ b/plugins/obs-transitions/CMakeLists.txt @@ -0,0 +1,13 @@ +project(obs-transitions) + +set(obs-transitions_SOURCES + obs-transitions.c + transition-fade.c + ) + +add_library(obs-transitions MODULE + ${obs-transitions_SOURCES}) +target_link_libraries(obs-transitions + libobs) + +install_obs_plugin_with_data(obs-transitions data) diff --git a/plugins/obs-transitions/data/fade_transition.effect b/plugins/obs-transitions/data/fade_transition.effect new file mode 100644 index 000000000..f728f3afe --- /dev/null +++ b/plugins/obs-transitions/data/fade_transition.effect @@ -0,0 +1,39 @@ +uniform float4x4 ViewProj; +uniform texture2d tex_a; +uniform texture2d tex_b; +uniform float fade_val; + +sampler_state textureSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct VertData { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertData VSDefault(VertData v_in) +{ + VertData vert_out; + vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = v_in.uv; + return vert_out; +} + +float4 PSFade(VertData v_in) : TARGET +{ + float4 a_val = tex_a.Sample(textureSampler, v_in.uv); + float4 b_val = tex_b.Sample(textureSampler, v_in.uv); + return lerp(a_val, b_val, fade_val); +} + +technique Fade +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSFade(v_in); + } +} diff --git a/plugins/obs-transitions/data/locale/en-US.ini b/plugins/obs-transitions/data/locale/en-US.ini new file mode 100644 index 000000000..42b4c6856 --- /dev/null +++ b/plugins/obs-transitions/data/locale/en-US.ini @@ -0,0 +1 @@ +FadeTransition="Fade" diff --git a/plugins/obs-transitions/obs-transitions.c b/plugins/obs-transitions/obs-transitions.c new file mode 100644 index 000000000..a9ba6c0fb --- /dev/null +++ b/plugins/obs-transitions/obs-transitions.c @@ -0,0 +1,13 @@ +#include + +OBS_DECLARE_MODULE() + +OBS_MODULE_USE_DEFAULT_LOCALE("obs-transitions", "en-US") + +extern struct obs_source_info fade_transition; + +bool obs_module_load(void) +{ + obs_register_source(&fade_transition); + return true; +} diff --git a/plugins/obs-transitions/transition-fade.c b/plugins/obs-transitions/transition-fade.c new file mode 100644 index 000000000..c9d1ea07d --- /dev/null +++ b/plugins/obs-transitions/transition-fade.c @@ -0,0 +1,100 @@ +#include + +struct fade_info { + obs_source_t *source; + + gs_effect_t *effect; + gs_eparam_t *a_param; + gs_eparam_t *b_param; + gs_eparam_t *fade_param; +}; + +static const char *fade_get_name(void *type_data) +{ + UNUSED_PARAMETER(type_data); + return obs_module_text("FadeTransition"); +} + +void *fade_create(obs_data_t *settings, obs_source_t *source) +{ + struct fade_info *fade; + char *file = obs_module_file("fade_transition.effect"); + gs_effect_t *effect; + + obs_enter_graphics(); + effect = gs_effect_create_from_file(file, NULL); + obs_leave_graphics(); + bfree(file); + + if (!effect) { + blog(LOG_ERROR, "Could not find fade_transition.effect"); + return NULL; + } + + fade = bmalloc(sizeof(*fade)); + fade->source = source; + fade->effect = effect; + fade->a_param = gs_effect_get_param_by_name(effect, "tex_a"); + fade->b_param = gs_effect_get_param_by_name(effect, "tex_b"); + fade->fade_param = gs_effect_get_param_by_name(effect, "fade_val"); + + UNUSED_PARAMETER(settings); + return fade; +} + +void fade_destroy(void *data) +{ + struct fade_info *fade = data; + bfree(fade); +} + +static void fade_callback(void *data, gs_texture_t *a, gs_texture_t *b, float t, + uint32_t cx, uint32_t cy) +{ + struct fade_info *fade = data; + + gs_effect_set_texture(fade->a_param, a); + gs_effect_set_texture(fade->b_param, b); + gs_effect_set_float(fade->fade_param, t); + + while (gs_effect_loop(fade->effect, "Fade")) + gs_draw_sprite(NULL, 0, cx, cy); +} + +void fade_video_render(void *data, gs_effect_t *effect) +{ + struct fade_info *fade = data; + obs_transition_video_render(fade->source, fade_callback); + UNUSED_PARAMETER(effect); +} + +static float mix_a(void *data, float t) +{ + UNUSED_PARAMETER(data); + return 1.0f - t; +} + +static float mix_b(void *data, float t) +{ + UNUSED_PARAMETER(data); + return t; +} + +bool fade_audio_render(void *data, uint64_t *ts_out, + struct obs_source_audio_mix *audio, uint32_t mixers, + size_t channels, size_t sample_rate) +{ + struct fade_info *fade = data; + return obs_transition_audio_render(fade->source, ts_out, + audio, mixers, channels, sample_rate, mix_a, mix_b); +} + +struct obs_source_info fade_transition = { + .id = "fade_transition", + .type = OBS_SOURCE_TYPE_TRANSITION, + .get_name = fade_get_name, + .create = fade_create, + .destroy = fade_destroy, + .video_render = fade_video_render, + .audio_render = fade_audio_render +};