obs-filters: Make mask/blend image center w/aspect by default

Fixes what is arguably the most annoying feature of the mask/blend
filter, the fact that the image always stretches to the entire source.
It now centers and preserves aspect ratio by default, with an option to
make it stretch and discard aspect ratio to make it operate as it did
before.
This commit is contained in:
jp9000
2016-01-22 05:34:02 -08:00
parent 423f5ea1fc
commit 4f782f2415
7 changed files with 128 additions and 36 deletions

View File

@@ -1,4 +1,5 @@
#include <obs-module.h>
#include <graphics/vec2.h>
#include <graphics/vec4.h>
#include <util/dstr.h>
@@ -6,11 +7,13 @@
#define SETTING_IMAGE_PATH "image_path"
#define SETTING_COLOR "color"
#define SETTING_OPACITY "opacity"
#define SETTING_STRETCH "stretch"
#define TEXT_TYPE obs_module_text("Type")
#define TEXT_IMAGE_PATH obs_module_text("Path")
#define TEXT_COLOR obs_module_text("Color")
#define TEXT_OPACITY obs_module_text("Opacity")
#define TEXT_STRETCH obs_module_text("StretchImage")
#define TEXT_PATH_IMAGES obs_module_text("BrowsePath.Images")
#define TEXT_PATH_ALL_FILES obs_module_text("BrowsePath.AllFiles")
@@ -20,6 +23,7 @@ struct mask_filter_data {
gs_texture_t *target;
struct vec4 color;
bool lock_aspect;
};
static const char *mask_filter_get_name(void *unused)
@@ -46,6 +50,7 @@ static void mask_filter_update(void *data, obs_data_t *settings)
gs_texture_destroy(filter->target);
filter->target = (path) ? gs_texture_create_from_file(path) : NULL;
filter->lock_aspect = !obs_data_get_bool(settings, SETTING_STRETCH);
effect_path = obs_module_file(effect_file);
gs_effect_destroy(filter->effect);
@@ -100,6 +105,7 @@ static obs_properties_t *mask_filter_properties(void *data)
OBS_PATH_FILE, filter_str.array, NULL);
obs_properties_add_color(props, SETTING_COLOR, TEXT_COLOR);
obs_properties_add_int(props, SETTING_OPACITY, TEXT_OPACITY, 0, 100, 1);
obs_properties_add_bool(props, SETTING_STRETCH, TEXT_STRETCH);
dstr_free(&filter_str);
@@ -132,13 +138,47 @@ static void mask_filter_destroy(void *data)
static void mask_filter_render(void *data, gs_effect_t *effect)
{
struct mask_filter_data *filter = data;
obs_source_t *target = obs_filter_get_target(filter->context);
gs_eparam_t *param;
struct vec2 add_val = {0};
struct vec2 mul_val = {1.0f, 1.0f};
if (!filter->target || !filter->effect) {
if (!target || !filter->target || !filter->effect) {
obs_source_skip_video_filter(filter->context);
return;
}
if (filter->lock_aspect) {
struct vec2 source_size;
struct vec2 mask_size;
struct vec2 mask_temp;
float source_aspect;
float mask_aspect;
bool size_to_x;
float fix;
source_size.x = (float)obs_source_get_base_width(target);
source_size.y = (float)obs_source_get_base_height(target);
mask_size.x = (float)gs_texture_get_width(filter->target);
mask_size.y = (float)gs_texture_get_height(filter->target);
source_aspect = source_size.x / source_size.y;
mask_aspect = mask_size.x / mask_size.y;
size_to_x = (source_aspect < mask_aspect);
fix = size_to_x ?
(source_size.x / mask_size.x) :
(source_size.y / mask_size.y);
vec2_mulf(&mask_size, &mask_size, fix);
vec2_div(&mul_val, &source_size, &mask_size);
vec2_mulf(&source_size, &source_size, 0.5f);
vec2_mulf(&mask_temp, &mask_size, 0.5f);
vec2_sub(&add_val, &source_size, &mask_temp);
vec2_neg(&add_val, &add_val);
vec2_div(&add_val, &add_val, &mask_size);
}
obs_source_process_filter_begin(filter->context, GS_RGBA,
OBS_ALLOW_DIRECT_RENDERING);
@@ -148,6 +188,12 @@ static void mask_filter_render(void *data, gs_effect_t *effect)
param = gs_effect_get_param_by_name(filter->effect, "color");
gs_effect_set_vec4(param, &filter->color);
param = gs_effect_get_param_by_name(filter->effect, "mul_val");
gs_effect_set_vec2(param, &mul_val);
param = gs_effect_get_param_by_name(filter->effect, "add_val");
gs_effect_set_vec2(param, &add_val);
obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
UNUSED_PARAMETER(effect);