mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-11 06:15:05 +00:00
filter-*, source-*: Fix rendering of filters and duplication of sources
This commit is contained in:
parent
1c7fd1495c
commit
16347beb87
7 changed files with 211 additions and 206 deletions
|
@ -547,6 +547,7 @@ filter::blur::blur_factory::blur_factory()
|
||||||
_info.type = OBS_SOURCE_TYPE_FILTER;
|
_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
_info.output_flags = OBS_SOURCE_VIDEO;
|
_info.output_flags = OBS_SOURCE_VIDEO;
|
||||||
|
|
||||||
|
set_resolution_enabled(false);
|
||||||
finish_setup();
|
finish_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,6 @@ filter::color_grade::color_grade_instance::~color_grade_instance() {}
|
||||||
filter::color_grade::color_grade_instance::color_grade_instance(obs_data_t* data, obs_source_t* self)
|
filter::color_grade::color_grade_instance::color_grade_instance(obs_data_t* data, obs_source_t* self)
|
||||||
: obs::source_instance(data, self)
|
: obs::source_instance(data, self)
|
||||||
{
|
{
|
||||||
update(data);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
char* file = obs_module_file("effects/color-grade.effect");
|
char* file = obs_module_file("effects/color-grade.effect");
|
||||||
if (file) {
|
if (file) {
|
||||||
|
@ -110,6 +108,8 @@ filter::color_grade::color_grade_instance::color_grade_instance(obs_data_t* data
|
||||||
}
|
}
|
||||||
_tex_grade = _rt_grade->get_texture();
|
_tex_grade = _rt_grade->get_texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t fix_gamma_value(double_t v)
|
float_t fix_gamma_value(double_t v)
|
||||||
|
@ -261,6 +261,7 @@ filter::color_grade::color_grade_factory::color_grade_factory()
|
||||||
_info.type = OBS_SOURCE_TYPE_FILTER;
|
_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
_info.output_flags = OBS_SOURCE_VIDEO;
|
_info.output_flags = OBS_SOURCE_VIDEO;
|
||||||
|
|
||||||
|
set_resolution_enabled(false);
|
||||||
finish_setup();
|
finish_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ filter::displacement::displacement_instance::displacement_instance(obs_data_t* d
|
||||||
}
|
}
|
||||||
|
|
||||||
_effect = gs::effect::create(effect);
|
_effect = gs::effect::create(effect);
|
||||||
|
|
||||||
|
update(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
filter::displacement::displacement_instance::~displacement_instance()
|
filter::displacement::displacement_instance::~displacement_instance()
|
||||||
|
@ -127,6 +129,7 @@ filter::displacement::displacement_factory::displacement_factory()
|
||||||
_info.type = OBS_SOURCE_TYPE_FILTER;
|
_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
_info.output_flags = OBS_SOURCE_VIDEO;
|
_info.output_flags = OBS_SOURCE_VIDEO;
|
||||||
|
|
||||||
|
set_resolution_enabled(false);
|
||||||
finish_setup();
|
finish_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,21 +53,21 @@ filter::dynamic_mask::dynamic_mask_instance::dynamic_mask_instance(obs_data_t* s
|
||||||
: obs::source_instance(settings, self), _have_filter_texture(false), _have_input_texture(false),
|
: obs::source_instance(settings, self), _have_filter_texture(false), _have_input_texture(false),
|
||||||
_have_final_texture(false), _precalc(), _effect()
|
_have_final_texture(false), _precalc(), _effect()
|
||||||
{
|
{
|
||||||
this->_filter_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_filter_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
this->_final_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_final_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
|
|
||||||
{
|
{
|
||||||
char* file = obs_module_file("effects/channel-mask.effect");
|
char* file = obs_module_file("effects/channel-mask.effect");
|
||||||
try {
|
try {
|
||||||
this->_effect = gs::effect::create(file);
|
_effect = gs::effect::create(file);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
P_LOG_ERROR("Loading channel mask effect failed with error(s):\n%s", ex.what());
|
P_LOG_ERROR("Loading channel mask effect failed with error(s):\n%s", ex.what());
|
||||||
}
|
}
|
||||||
assert(this->_effect != nullptr);
|
assert(_effect != nullptr);
|
||||||
bfree(file);
|
bfree(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->update(settings);
|
update(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
filter::dynamic_mask::dynamic_mask_instance::~dynamic_mask_instance() {}
|
filter::dynamic_mask::dynamic_mask_instance::~dynamic_mask_instance() {}
|
||||||
|
@ -76,49 +76,49 @@ void filter::dynamic_mask::dynamic_mask_instance::update(obs_data_t* settings)
|
||||||
{
|
{
|
||||||
// Update source.
|
// Update source.
|
||||||
try {
|
try {
|
||||||
this->_input = std::make_shared<obs::source>(obs_data_get_string(settings, ST_INPUT));
|
_input = std::make_shared<obs::source>(obs_data_get_string(settings, ST_INPUT));
|
||||||
this->_input_capture = std::make_shared<gfx::source_texture>(this->_input, _self);
|
_input_capture = std::make_shared<gfx::source_texture>(_input, _self);
|
||||||
this->_input->events.rename += std::bind(&filter::dynamic_mask::dynamic_mask_instance::input_renamed, this,
|
_input->events.rename += std::bind(&filter::dynamic_mask::dynamic_mask_instance::input_renamed, this,
|
||||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
this->_input.reset();
|
_input.reset();
|
||||||
this->_input_capture.reset();
|
_input_capture.reset();
|
||||||
this->_input_texture.reset();
|
_input_texture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update data store
|
// Update data store
|
||||||
for (auto kv1 : channel_translations) {
|
for (auto kv1 : channel_translations) {
|
||||||
auto found = this->_channels.find(kv1.first);
|
auto found = _channels.find(kv1.first);
|
||||||
if (found == this->_channels.end()) {
|
if (found == _channels.end()) {
|
||||||
this->_channels.insert({kv1.first, channel_data()});
|
_channels.insert({kv1.first, channel_data()});
|
||||||
found = this->_channels.find(kv1.first);
|
found = _channels.find(kv1.first);
|
||||||
if (found == this->_channels.end()) {
|
if (found == _channels.end()) {
|
||||||
assert(found != this->_channels.end());
|
assert(found != _channels.end());
|
||||||
throw std::runtime_error("Unable to insert element into data _store.");
|
throw std::runtime_error("Unable to insert element into data _store.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string chv_key = std::string(ST_CHANNEL_VALUE) + "." + kv1.second;
|
std::string chv_key = std::string(ST_CHANNEL_VALUE) + "." + kv1.second;
|
||||||
found->second.value = static_cast<float_t>(obs_data_get_double(settings, chv_key.c_str()));
|
found->second.value = static_cast<float_t>(obs_data_get_double(settings, chv_key.c_str()));
|
||||||
this->_precalc.base.ptr[static_cast<size_t>(kv1.first)] = found->second.value;
|
_precalc.base.ptr[static_cast<size_t>(kv1.first)] = found->second.value;
|
||||||
|
|
||||||
std::string chm_key = std::string(ST_CHANNEL_MULTIPLIER) + "." + kv1.second;
|
std::string chm_key = std::string(ST_CHANNEL_MULTIPLIER) + "." + kv1.second;
|
||||||
found->second.scale = static_cast<float_t>(obs_data_get_double(settings, chm_key.c_str()));
|
found->second.scale = static_cast<float_t>(obs_data_get_double(settings, chm_key.c_str()));
|
||||||
this->_precalc.scale.ptr[static_cast<size_t>(kv1.first)] = found->second.scale;
|
_precalc.scale.ptr[static_cast<size_t>(kv1.first)] = found->second.scale;
|
||||||
|
|
||||||
vec4* ch = &_precalc.matrix.x;
|
vec4* ch = &_precalc.matrix.x;
|
||||||
switch (kv1.first) {
|
switch (kv1.first) {
|
||||||
case channel::Red:
|
case channel::Red:
|
||||||
ch = &this->_precalc.matrix.x;
|
ch = &_precalc.matrix.x;
|
||||||
break;
|
break;
|
||||||
case channel::Green:
|
case channel::Green:
|
||||||
ch = &this->_precalc.matrix.y;
|
ch = &_precalc.matrix.y;
|
||||||
break;
|
break;
|
||||||
case channel::Blue:
|
case channel::Blue:
|
||||||
ch = &this->_precalc.matrix.z;
|
ch = &_precalc.matrix.z;
|
||||||
break;
|
break;
|
||||||
case channel::Alpha:
|
case channel::Alpha:
|
||||||
ch = &this->_precalc.matrix.t;
|
ch = &_precalc.matrix.t;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -140,17 +140,17 @@ void filter::dynamic_mask::dynamic_mask_instance::load(obs_data_t* settings)
|
||||||
|
|
||||||
void filter::dynamic_mask::dynamic_mask_instance::save(obs_data_t* settings)
|
void filter::dynamic_mask::dynamic_mask_instance::save(obs_data_t* settings)
|
||||||
{
|
{
|
||||||
if (this->_input) {
|
if (_input) {
|
||||||
obs_data_set_string(settings, ST_INPUT, obs_source_get_name(this->_input->get()));
|
obs_data_set_string(settings, ST_INPUT, obs_source_get_name(_input->get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto kv1 : channel_translations) {
|
for (auto kv1 : channel_translations) {
|
||||||
auto found = this->_channels.find(kv1.first);
|
auto found = _channels.find(kv1.first);
|
||||||
if (found == this->_channels.end()) {
|
if (found == _channels.end()) {
|
||||||
this->_channels.insert({kv1.first, channel_data()});
|
_channels.insert({kv1.first, channel_data()});
|
||||||
found = this->_channels.find(kv1.first);
|
found = _channels.find(kv1.first);
|
||||||
if (found == this->_channels.end()) {
|
if (found == _channels.end()) {
|
||||||
assert(found != this->_channels.end());
|
assert(found != _channels.end());
|
||||||
throw std::runtime_error("Unable to insert element into data _store.");
|
throw std::runtime_error("Unable to insert element into data _store.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,8 +212,8 @@ void filter::dynamic_mask::dynamic_mask_instance::video_tick(float)
|
||||||
|
|
||||||
void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_effect)
|
void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_effect)
|
||||||
{
|
{
|
||||||
obs_source_t* parent = obs_filter_get_parent(this->_self);
|
obs_source_t* parent = obs_filter_get_parent(_self);
|
||||||
obs_source_t* target = obs_filter_get_target(this->_self);
|
obs_source_t* target = obs_filter_get_target(_self);
|
||||||
uint32_t width = obs_source_get_base_width(target);
|
uint32_t width = obs_source_get_base_width(target);
|
||||||
uint32_t height = obs_source_get_base_height(target);
|
uint32_t height = obs_source_get_base_height(target);
|
||||||
|
|
||||||
|
@ -229,8 +229,8 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
|
||||||
|
|
||||||
try { // Capture filter and input
|
try { // Capture filter and input
|
||||||
if (!_have_filter_texture) {
|
if (!_have_filter_texture) {
|
||||||
if (obs_source_process_filter_begin(this->_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
if (obs_source_process_filter_begin(_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
||||||
auto op = this->_filter_rt->render(width, height);
|
auto op = _filter_rt->render(width, height);
|
||||||
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
|
@ -249,26 +249,26 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
|
||||||
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
|
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
|
||||||
|
|
||||||
obs_source_process_filter_end(this->_self, default_effect, width, height);
|
obs_source_process_filter_end(_self, default_effect, width, height);
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Failed to render filter.");
|
throw std::runtime_error("Failed to render filter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_filter_texture = this->_filter_rt->get_texture();
|
_filter_texture = _filter_rt->get_texture();
|
||||||
this->_have_filter_texture = true;
|
_have_filter_texture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_have_input_texture) {
|
if (!_have_input_texture) {
|
||||||
this->_input_texture = this->_input_capture->render(_input->width(), _input->height());
|
_input_texture = _input_capture->render(_input->width(), _input->height());
|
||||||
this->_have_input_texture = true;
|
_have_input_texture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw source
|
// Draw source
|
||||||
if (!this->_have_final_texture) {
|
if (!_have_final_texture) {
|
||||||
{
|
{
|
||||||
auto op = this->_final_rt->render(width, height);
|
auto op = _final_rt->render(width, height);
|
||||||
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
|
@ -287,12 +287,12 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
|
||||||
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
|
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
|
||||||
|
|
||||||
_effect.get_parameter("pMaskInputA").set_texture(this->_filter_texture);
|
_effect.get_parameter("pMaskInputA").set_texture(_filter_texture);
|
||||||
_effect.get_parameter("pMaskInputB").set_texture(this->_input_texture);
|
_effect.get_parameter("pMaskInputB").set_texture(_input_texture);
|
||||||
|
|
||||||
_effect.get_parameter("pMaskBase").set_float4(this->_precalc.base);
|
_effect.get_parameter("pMaskBase").set_float4(_precalc.base);
|
||||||
_effect.get_parameter("pMaskMatrix").set_matrix(this->_precalc.matrix);
|
_effect.get_parameter("pMaskMatrix").set_matrix(_precalc.matrix);
|
||||||
_effect.get_parameter("pMaskMultiplier").set_float4(this->_precalc.scale);
|
_effect.get_parameter("pMaskMultiplier").set_float4(_precalc.scale);
|
||||||
|
|
||||||
while (gs_effect_loop(_effect.get(), "Mask")) {
|
while (gs_effect_loop(_effect.get(), "Mask")) {
|
||||||
gs_draw_sprite(0, 0, width, height);
|
gs_draw_sprite(0, 0, width, height);
|
||||||
|
@ -301,21 +301,20 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_final_texture = this->_final_rt->get_texture();
|
_final_texture = _final_rt->get_texture();
|
||||||
this->_have_final_texture = true;
|
_have_final_texture = true;
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
obs_source_skip_video_filter(this->_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_have_filter_texture || !_have_input_texture || !_have_final_texture) {
|
if (!_have_filter_texture || !_have_input_texture || !_have_final_texture) {
|
||||||
obs_source_skip_video_filter(this->_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this->_filter_texture->get_object() || !this->_input_texture->get_object()
|
if (!_filter_texture->get_object() || !_input_texture->get_object() || !_final_texture->get_object()) {
|
||||||
|| !this->_final_texture->get_object()) {
|
obs_source_skip_video_filter(_self);
|
||||||
obs_source_skip_video_filter(this->_self);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,11 +333,11 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
|
||||||
gs_effect_t* final_effect = in_effect ? in_effect : default_effect;
|
gs_effect_t* final_effect = in_effect ? in_effect : default_effect;
|
||||||
gs_eparam_t* param = gs_effect_get_param_by_name(final_effect, "image");
|
gs_eparam_t* param = gs_effect_get_param_by_name(final_effect, "image");
|
||||||
if (!param) {
|
if (!param) {
|
||||||
P_LOG_ERROR("<filter-dynamic-mask:%s> Failed to set image param.", obs_source_get_name(this->_self));
|
P_LOG_ERROR("<filter-dynamic-mask:%s> Failed to set image param.", obs_source_get_name(_self));
|
||||||
obs_source_skip_video_filter(this->_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
gs_effect_set_texture(param, this->_final_texture->get_object());
|
gs_effect_set_texture(param, _final_texture->get_object());
|
||||||
}
|
}
|
||||||
while (gs_effect_loop(final_effect, "Draw")) {
|
while (gs_effect_loop(final_effect, "Draw")) {
|
||||||
gs_draw_sprite(0, 0, width, height);
|
gs_draw_sprite(0, 0, width, height);
|
||||||
|
@ -352,6 +351,7 @@ filter::dynamic_mask::dynamic_mask_factory::dynamic_mask_factory()
|
||||||
_info.type = OBS_SOURCE_TYPE_FILTER;
|
_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
_info.output_flags = OBS_SOURCE_VIDEO;
|
_info.output_flags = OBS_SOURCE_VIDEO;
|
||||||
|
|
||||||
|
set_resolution_enabled(false);
|
||||||
finish_setup();
|
finish_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,13 +82,12 @@ filter::sdf_effects::sdf_effects_instance::sdf_effects_instance(obs_data_t* sett
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
vec4 transparent = {0};
|
vec4 transparent = {0};
|
||||||
|
|
||||||
this->_source_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_source_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
this->_sdf_write = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
|
_sdf_write = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
|
||||||
this->_sdf_read = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
|
_sdf_read = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
|
||||||
this->_output_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_output_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
|
|
||||||
std::shared_ptr<gs::rendertarget> initialize_rts[] = {this->_source_rt, this->_sdf_write, this->_sdf_read,
|
std::shared_ptr<gs::rendertarget> initialize_rts[] = {_source_rt, _sdf_write, _sdf_read, _output_rt};
|
||||||
this->_output_rt};
|
|
||||||
for (auto rt : initialize_rts) {
|
for (auto rt : initialize_rts) {
|
||||||
auto op = rt->render(1, 1);
|
auto op = rt->render(1, 1);
|
||||||
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &transparent, 0, 0);
|
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &transparent, 0, 0);
|
||||||
|
@ -113,6 +112,7 @@ filter::sdf_effects::sdf_effects_instance::sdf_effects_instance(obs_data_t* sett
|
||||||
bfree(path);
|
bfree(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update(settings);
|
update(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ filter::sdf_effects::sdf_effects_instance::~sdf_effects_instance() {}
|
||||||
void filter::sdf_effects::sdf_effects_instance::update(obs_data_t* data)
|
void filter::sdf_effects::sdf_effects_instance::update(obs_data_t* data)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
this->_outer_shadow =
|
_outer_shadow =
|
||||||
obs_data_get_bool(data, ST_SHADOW_OUTER)
|
obs_data_get_bool(data, ST_SHADOW_OUTER)
|
||||||
&& (obs_data_get_double(data, ST_SHADOW_OUTER_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
&& (obs_data_get_double(data, ST_SHADOW_OUTER_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
||||||
{
|
{
|
||||||
|
@ -134,19 +134,19 @@ void filter::sdf_effects::sdf_effects_instance::update(obs_data_t* data)
|
||||||
cs c;
|
cs c;
|
||||||
};
|
};
|
||||||
color = uint32_t(obs_data_get_int(data, ST_SHADOW_OUTER_COLOR));
|
color = uint32_t(obs_data_get_int(data, ST_SHADOW_OUTER_COLOR));
|
||||||
this->_outer_shadow_color.x = float_t(c.r / 255.0);
|
_outer_shadow_color.x = float_t(c.r / 255.0);
|
||||||
this->_outer_shadow_color.y = float_t(c.g / 255.0);
|
_outer_shadow_color.y = float_t(c.g / 255.0);
|
||||||
this->_outer_shadow_color.z = float_t(c.b / 255.0);
|
_outer_shadow_color.z = float_t(c.b / 255.0);
|
||||||
this->_outer_shadow_color.w = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_ALPHA) / 100.0);
|
_outer_shadow_color.w = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_ALPHA) / 100.0);
|
||||||
}
|
}
|
||||||
this->_outer_shadow_range_min = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_RANGE_MINIMUM));
|
_outer_shadow_range_min = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_RANGE_MINIMUM));
|
||||||
this->_outer_shadow_range_max = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_RANGE_MAXIMUM));
|
_outer_shadow_range_max = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_RANGE_MAXIMUM));
|
||||||
this->_outer_shadow_offset_x = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_OFFSET_X));
|
_outer_shadow_offset_x = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_OFFSET_X));
|
||||||
this->_outer_shadow_offset_y = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_OFFSET_Y));
|
_outer_shadow_offset_y = float_t(obs_data_get_double(data, ST_SHADOW_OUTER_OFFSET_Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
this->_inner_shadow =
|
_inner_shadow =
|
||||||
obs_data_get_bool(data, ST_SHADOW_INNER)
|
obs_data_get_bool(data, ST_SHADOW_INNER)
|
||||||
&& (obs_data_get_double(data, ST_SHADOW_INNER_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
&& (obs_data_get_double(data, ST_SHADOW_INNER_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
||||||
{
|
{
|
||||||
|
@ -159,20 +159,19 @@ void filter::sdf_effects::sdf_effects_instance::update(obs_data_t* data)
|
||||||
cs c;
|
cs c;
|
||||||
};
|
};
|
||||||
color = uint32_t(obs_data_get_int(data, ST_SHADOW_INNER_COLOR));
|
color = uint32_t(obs_data_get_int(data, ST_SHADOW_INNER_COLOR));
|
||||||
this->_inner_shadow_color.x = float_t(c.r / 255.0);
|
_inner_shadow_color.x = float_t(c.r / 255.0);
|
||||||
this->_inner_shadow_color.y = float_t(c.g / 255.0);
|
_inner_shadow_color.y = float_t(c.g / 255.0);
|
||||||
this->_inner_shadow_color.z = float_t(c.b / 255.0);
|
_inner_shadow_color.z = float_t(c.b / 255.0);
|
||||||
this->_inner_shadow_color.w = float_t(obs_data_get_double(data, ST_SHADOW_INNER_ALPHA) / 100.0);
|
_inner_shadow_color.w = float_t(obs_data_get_double(data, ST_SHADOW_INNER_ALPHA) / 100.0);
|
||||||
}
|
}
|
||||||
this->_inner_shadow_range_min = float_t(obs_data_get_double(data, ST_SHADOW_INNER_RANGE_MINIMUM));
|
_inner_shadow_range_min = float_t(obs_data_get_double(data, ST_SHADOW_INNER_RANGE_MINIMUM));
|
||||||
this->_inner_shadow_range_max = float_t(obs_data_get_double(data, ST_SHADOW_INNER_RANGE_MAXIMUM));
|
_inner_shadow_range_max = float_t(obs_data_get_double(data, ST_SHADOW_INNER_RANGE_MAXIMUM));
|
||||||
this->_inner_shadow_offset_x = float_t(obs_data_get_double(data, ST_SHADOW_INNER_OFFSET_X));
|
_inner_shadow_offset_x = float_t(obs_data_get_double(data, ST_SHADOW_INNER_OFFSET_X));
|
||||||
this->_inner_shadow_offset_y = float_t(obs_data_get_double(data, ST_SHADOW_INNER_OFFSET_Y));
|
_inner_shadow_offset_y = float_t(obs_data_get_double(data, ST_SHADOW_INNER_OFFSET_Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
this->_outer_glow =
|
_outer_glow = obs_data_get_bool(data, ST_GLOW_OUTER)
|
||||||
obs_data_get_bool(data, ST_GLOW_OUTER)
|
|
||||||
&& (obs_data_get_double(data, ST_GLOW_OUTER_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
&& (obs_data_get_double(data, ST_GLOW_OUTER_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
||||||
{
|
{
|
||||||
struct cs {
|
struct cs {
|
||||||
|
@ -184,22 +183,21 @@ void filter::sdf_effects::sdf_effects_instance::update(obs_data_t* data)
|
||||||
cs c;
|
cs c;
|
||||||
};
|
};
|
||||||
color = uint32_t(obs_data_get_int(data, ST_GLOW_OUTER_COLOR));
|
color = uint32_t(obs_data_get_int(data, ST_GLOW_OUTER_COLOR));
|
||||||
this->_outer_glow_color.x = float_t(c.r / 255.0);
|
_outer_glow_color.x = float_t(c.r / 255.0);
|
||||||
this->_outer_glow_color.y = float_t(c.g / 255.0);
|
_outer_glow_color.y = float_t(c.g / 255.0);
|
||||||
this->_outer_glow_color.z = float_t(c.b / 255.0);
|
_outer_glow_color.z = float_t(c.b / 255.0);
|
||||||
this->_outer_glow_color.w = float_t(obs_data_get_double(data, ST_GLOW_OUTER_ALPHA) / 100.0);
|
_outer_glow_color.w = float_t(obs_data_get_double(data, ST_GLOW_OUTER_ALPHA) / 100.0);
|
||||||
}
|
}
|
||||||
this->_outer_glow_width = float_t(obs_data_get_double(data, ST_GLOW_OUTER_WIDTH));
|
_outer_glow_width = float_t(obs_data_get_double(data, ST_GLOW_OUTER_WIDTH));
|
||||||
this->_outer_glow_sharpness = float_t(obs_data_get_double(data, ST_GLOW_OUTER_SHARPNESS) / 100.0);
|
_outer_glow_sharpness = float_t(obs_data_get_double(data, ST_GLOW_OUTER_SHARPNESS) / 100.0);
|
||||||
this->_outer_glow_sharpness_inv = float_t(1.0f / (1.0f - this->_outer_glow_sharpness));
|
_outer_glow_sharpness_inv = float_t(1.0f / (1.0f - _outer_glow_sharpness));
|
||||||
if (this->_outer_glow_sharpness >= (1.0f - std::numeric_limits<float_t>::epsilon())) {
|
if (_outer_glow_sharpness >= (1.0f - std::numeric_limits<float_t>::epsilon())) {
|
||||||
this->_outer_glow_sharpness = 1.0f - std::numeric_limits<float_t>::epsilon();
|
_outer_glow_sharpness = 1.0f - std::numeric_limits<float_t>::epsilon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
this->_inner_glow =
|
_inner_glow = obs_data_get_bool(data, ST_GLOW_INNER)
|
||||||
obs_data_get_bool(data, ST_GLOW_INNER)
|
|
||||||
&& (obs_data_get_double(data, ST_GLOW_INNER_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
&& (obs_data_get_double(data, ST_GLOW_INNER_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
||||||
{
|
{
|
||||||
struct cs {
|
struct cs {
|
||||||
|
@ -211,21 +209,21 @@ void filter::sdf_effects::sdf_effects_instance::update(obs_data_t* data)
|
||||||
cs c;
|
cs c;
|
||||||
};
|
};
|
||||||
color = uint32_t(obs_data_get_int(data, ST_GLOW_INNER_COLOR));
|
color = uint32_t(obs_data_get_int(data, ST_GLOW_INNER_COLOR));
|
||||||
this->_inner_glow_color.x = float_t(c.r / 255.0);
|
_inner_glow_color.x = float_t(c.r / 255.0);
|
||||||
this->_inner_glow_color.y = float_t(c.g / 255.0);
|
_inner_glow_color.y = float_t(c.g / 255.0);
|
||||||
this->_inner_glow_color.z = float_t(c.b / 255.0);
|
_inner_glow_color.z = float_t(c.b / 255.0);
|
||||||
this->_inner_glow_color.w = float_t(obs_data_get_double(data, ST_GLOW_INNER_ALPHA) / 100.0);
|
_inner_glow_color.w = float_t(obs_data_get_double(data, ST_GLOW_INNER_ALPHA) / 100.0);
|
||||||
}
|
}
|
||||||
this->_inner_glow_width = float_t(obs_data_get_double(data, ST_GLOW_INNER_WIDTH));
|
_inner_glow_width = float_t(obs_data_get_double(data, ST_GLOW_INNER_WIDTH));
|
||||||
this->_inner_glow_sharpness = float_t(obs_data_get_double(data, ST_GLOW_INNER_SHARPNESS) / 100.0);
|
_inner_glow_sharpness = float_t(obs_data_get_double(data, ST_GLOW_INNER_SHARPNESS) / 100.0);
|
||||||
this->_inner_glow_sharpness_inv = float_t(1.0f / (1.0f - this->_inner_glow_sharpness));
|
_inner_glow_sharpness_inv = float_t(1.0f / (1.0f - _inner_glow_sharpness));
|
||||||
if (this->_inner_glow_sharpness >= (1.0f - std::numeric_limits<float_t>::epsilon())) {
|
if (_inner_glow_sharpness >= (1.0f - std::numeric_limits<float_t>::epsilon())) {
|
||||||
this->_inner_glow_sharpness = 1.0f - std::numeric_limits<float_t>::epsilon();
|
_inner_glow_sharpness = 1.0f - std::numeric_limits<float_t>::epsilon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
this->_outline = obs_data_get_bool(data, ST_OUTLINE)
|
_outline = obs_data_get_bool(data, ST_OUTLINE)
|
||||||
&& (obs_data_get_double(data, ST_OUTLINE_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
&& (obs_data_get_double(data, ST_OUTLINE_ALPHA) >= std::numeric_limits<double_t>::epsilon());
|
||||||
{
|
{
|
||||||
struct cs {
|
struct cs {
|
||||||
|
@ -237,22 +235,22 @@ void filter::sdf_effects::sdf_effects_instance::update(obs_data_t* data)
|
||||||
cs c;
|
cs c;
|
||||||
};
|
};
|
||||||
color = uint32_t(obs_data_get_int(data, ST_OUTLINE_COLOR));
|
color = uint32_t(obs_data_get_int(data, ST_OUTLINE_COLOR));
|
||||||
this->_outline_color.x = float_t(c.r / 255.0);
|
_outline_color.x = float_t(c.r / 255.0);
|
||||||
this->_outline_color.y = float_t(c.g / 255.0);
|
_outline_color.y = float_t(c.g / 255.0);
|
||||||
this->_outline_color.z = float_t(c.b / 255.0);
|
_outline_color.z = float_t(c.b / 255.0);
|
||||||
this->_outline_color.w = float_t(obs_data_get_double(data, ST_OUTLINE_ALPHA) / 100.0);
|
_outline_color.w = float_t(obs_data_get_double(data, ST_OUTLINE_ALPHA) / 100.0);
|
||||||
}
|
}
|
||||||
this->_outline_width = float_t(obs_data_get_double(data, ST_OUTLINE_WIDTH));
|
_outline_width = float_t(obs_data_get_double(data, ST_OUTLINE_WIDTH));
|
||||||
this->_outline_offset = float_t(obs_data_get_double(data, ST_OUTLINE_OFFSET));
|
_outline_offset = float_t(obs_data_get_double(data, ST_OUTLINE_OFFSET));
|
||||||
this->_outline_sharpness = float_t(obs_data_get_double(data, ST_OUTLINE_SHARPNESS) / 100.0);
|
_outline_sharpness = float_t(obs_data_get_double(data, ST_OUTLINE_SHARPNESS) / 100.0);
|
||||||
this->_outline_sharpness_inv = float_t(1.0f / (1.0f - this->_outline_sharpness));
|
_outline_sharpness_inv = float_t(1.0f / (1.0f - _outline_sharpness));
|
||||||
if (this->_outline_sharpness >= (1.0f - std::numeric_limits<float_t>::epsilon())) {
|
if (_outline_sharpness >= (1.0f - std::numeric_limits<float_t>::epsilon())) {
|
||||||
this->_outline_sharpness = 1.0f - std::numeric_limits<float_t>::epsilon();
|
_outline_sharpness = 1.0f - std::numeric_limits<float_t>::epsilon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_sdf_scale = double_t(obs_data_get_double(data, ST_SDF_SCALE) / 100.0);
|
_sdf_scale = double_t(obs_data_get_double(data, ST_SDF_SCALE) / 100.0);
|
||||||
this->_sdf_threshold = float_t(obs_data_get_double(data, ST_SDF_THRESHOLD) / 100.0);
|
_sdf_threshold = float_t(obs_data_get_double(data, ST_SDF_THRESHOLD) / 100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::sdf_effects::sdf_effects_instance::load(obs_data_t* settings)
|
void filter::sdf_effects::sdf_effects_instance::load(obs_data_t* settings)
|
||||||
|
@ -267,7 +265,7 @@ void filter::sdf_effects::sdf_effects_instance::video_tick(float)
|
||||||
|
|
||||||
// Figure out the actual source size.
|
// Figure out the actual source size.
|
||||||
do {
|
do {
|
||||||
obs_source_t* target = obs_filter_get_target(this->_self);
|
obs_source_t* target = obs_filter_get_target(_self);
|
||||||
if (target == nullptr) {
|
if (target == nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -277,21 +275,21 @@ void filter::sdf_effects::sdf_effects_instance::video_tick(float)
|
||||||
height = obs_source_get_height(target);
|
height = obs_source_get_height(target);
|
||||||
} while (false);
|
} while (false);
|
||||||
|
|
||||||
this->_source_rendered = false;
|
_source_rendered = false;
|
||||||
this->_output_rendered = false;
|
_output_rendered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect)
|
void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect)
|
||||||
{
|
{
|
||||||
obs_source_t* parent = obs_filter_get_parent(this->_self);
|
obs_source_t* parent = obs_filter_get_parent(_self);
|
||||||
obs_source_t* target = obs_filter_get_target(this->_self);
|
obs_source_t* target = obs_filter_get_target(_self);
|
||||||
uint32_t baseW = obs_source_get_base_width(target);
|
uint32_t baseW = obs_source_get_base_width(target);
|
||||||
uint32_t baseH = obs_source_get_base_height(target);
|
uint32_t baseH = obs_source_get_base_height(target);
|
||||||
gs_effect_t* final_effect = effect ? effect : obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
|
gs_effect_t* final_effect = effect ? effect : obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
|
||||||
gs_effect_t* default_effect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
|
gs_effect_t* default_effect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
|
||||||
|
|
||||||
if (!this->_self || !parent || !target || !baseW || !baseH || !final_effect) {
|
if (!_self || !parent || !target || !baseW || !baseH || !final_effect) {
|
||||||
obs_source_skip_video_filter(this->_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,28 +312,28 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
|
||||||
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
|
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
||||||
|
|
||||||
if (!this->_source_rendered) {
|
if (!_source_rendered) {
|
||||||
// Store input texture.
|
// Store input texture.
|
||||||
{
|
{
|
||||||
auto op = _source_rt->render(baseW, baseH);
|
auto op = _source_rt->render(baseW, baseH);
|
||||||
gs_ortho(0, (float)baseW, 0, (float)baseH, -1, 1);
|
gs_ortho(0, (float)baseW, 0, (float)baseH, -1, 1);
|
||||||
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0);
|
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0);
|
||||||
|
|
||||||
if (obs_source_process_filter_begin(this->_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
if (obs_source_process_filter_begin(_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
||||||
obs_source_process_filter_end(this->_self, final_effect, baseW, baseH);
|
obs_source_process_filter_end(_self, final_effect, baseW, baseH);
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("failed to process source");
|
throw std::runtime_error("failed to process source");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->_source_rt->get_texture(this->_source_texture);
|
_source_rt->get_texture(_source_texture);
|
||||||
if (!this->_source_texture) {
|
if (!_source_texture) {
|
||||||
throw std::runtime_error("failed to draw source");
|
throw std::runtime_error("failed to draw source");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate SDF Buffers
|
// Generate SDF Buffers
|
||||||
{
|
{
|
||||||
this->_sdf_read->get_texture(this->_sdf_texture);
|
_sdf_read->get_texture(_sdf_texture);
|
||||||
if (!this->_sdf_texture) {
|
if (!_sdf_texture) {
|
||||||
throw std::runtime_error("SDF Backbuffer empty");
|
throw std::runtime_error("SDF Backbuffer empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,41 +353,41 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto op = this->_sdf_write->render(uint32_t(sdfW), uint32_t(sdfH));
|
auto op = _sdf_write->render(uint32_t(sdfW), uint32_t(sdfH));
|
||||||
gs_ortho(0, (float)sdfW, 0, (float)sdfH, -1, 1);
|
gs_ortho(0, (float)sdfW, 0, (float)sdfH, -1, 1);
|
||||||
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0);
|
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0);
|
||||||
|
|
||||||
_sdf_producer_effect.get_parameter("_image").set_texture(this->_source_texture);
|
_sdf_producer_effect.get_parameter("_image").set_texture(_source_texture);
|
||||||
_sdf_producer_effect.get_parameter("_size").set_float2(float_t(sdfW), float_t(sdfH));
|
_sdf_producer_effect.get_parameter("_size").set_float2(float_t(sdfW), float_t(sdfH));
|
||||||
_sdf_producer_effect.get_parameter("_sdf").set_texture(this->_sdf_texture);
|
_sdf_producer_effect.get_parameter("_sdf").set_texture(_sdf_texture);
|
||||||
_sdf_producer_effect.get_parameter("_threshold").set_float(this->_sdf_threshold);
|
_sdf_producer_effect.get_parameter("_threshold").set_float(_sdf_threshold);
|
||||||
|
|
||||||
while (gs_effect_loop(_sdf_producer_effect.get_object(), "Draw")) {
|
while (gs_effect_loop(_sdf_producer_effect.get_object(), "Draw")) {
|
||||||
gs_draw_sprite(this->_sdf_texture->get_object(), 0, uint32_t(sdfW), uint32_t(sdfH));
|
gs_draw_sprite(_sdf_texture->get_object(), 0, uint32_t(sdfW), uint32_t(sdfH));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::swap(this->_sdf_read, this->_sdf_write);
|
std::swap(_sdf_read, _sdf_write);
|
||||||
this->_sdf_read->get_texture(this->_sdf_texture);
|
_sdf_read->get_texture(_sdf_texture);
|
||||||
if (!this->_sdf_texture) {
|
if (!_sdf_texture) {
|
||||||
throw std::runtime_error("SDF Backbuffer empty");
|
throw std::runtime_error("SDF Backbuffer empty");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_source_rendered = true;
|
_source_rendered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_source_skip_video_filter(this->_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->_output_rendered) {
|
if (!_output_rendered) {
|
||||||
this->_output_texture = this->_source_texture;
|
_output_texture = _source_texture;
|
||||||
|
|
||||||
if (!_sdf_consumer_effect) {
|
if (!_sdf_consumer_effect) {
|
||||||
obs_source_skip_video_filter(this->_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,14 +407,14 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
|
||||||
|
|
||||||
// Optimized Render path.
|
// Optimized Render path.
|
||||||
try {
|
try {
|
||||||
auto op = this->_output_rt->render(baseW, baseH);
|
auto op = _output_rt->render(baseW, baseH);
|
||||||
gs_ortho(0, 1, 0, 1, 0, 1);
|
gs_ortho(0, 1, 0, 1, 0, 1);
|
||||||
|
|
||||||
gs_enable_blending(false);
|
gs_enable_blending(false);
|
||||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO);
|
gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO);
|
||||||
auto param = gs_effect_get_param_by_name(default_effect, "image");
|
auto param = gs_effect_get_param_by_name(default_effect, "image");
|
||||||
if (param) {
|
if (param) {
|
||||||
gs_effect_set_texture(param, this->_output_texture->get_object());
|
gs_effect_set_texture(param, _output_texture->get_object());
|
||||||
}
|
}
|
||||||
while (gs_effect_loop(default_effect, "Draw")) {
|
while (gs_effect_loop(default_effect, "Draw")) {
|
||||||
gs_draw_sprite(0, 0, 1, 1);
|
gs_draw_sprite(0, 0, 1, 1);
|
||||||
|
@ -424,67 +422,65 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
|
||||||
|
|
||||||
gs_enable_blending(true);
|
gs_enable_blending(true);
|
||||||
gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
|
gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
|
||||||
if (this->_outer_shadow) {
|
if (_outer_shadow) {
|
||||||
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(this->_sdf_texture);
|
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(_sdf_texture);
|
||||||
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(this->_sdf_threshold);
|
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(_sdf_threshold);
|
||||||
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(this->_source_texture->get_object());
|
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(_source_texture->get_object());
|
||||||
_sdf_consumer_effect.get_parameter("pShadowColor").set_float4(this->_outer_shadow_color);
|
_sdf_consumer_effect.get_parameter("pShadowColor").set_float4(_outer_shadow_color);
|
||||||
_sdf_consumer_effect.get_parameter("pShadowMin").set_float(this->_outer_shadow_range_min);
|
_sdf_consumer_effect.get_parameter("pShadowMin").set_float(_outer_shadow_range_min);
|
||||||
_sdf_consumer_effect.get_parameter("pShadowMax").set_float(this->_outer_shadow_range_max);
|
_sdf_consumer_effect.get_parameter("pShadowMax").set_float(_outer_shadow_range_max);
|
||||||
_sdf_consumer_effect.get_parameter("pShadowOffset")
|
_sdf_consumer_effect.get_parameter("pShadowOffset")
|
||||||
.set_float2(this->_outer_shadow_offset_x / float_t(baseW),
|
.set_float2(_outer_shadow_offset_x / float_t(baseW), _outer_shadow_offset_y / float_t(baseH));
|
||||||
this->_outer_shadow_offset_y / float_t(baseH));
|
|
||||||
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "ShadowOuter")) {
|
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "ShadowOuter")) {
|
||||||
gs_draw_sprite(0, 0, 1, 1);
|
gs_draw_sprite(0, 0, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->_inner_shadow) {
|
if (_inner_shadow) {
|
||||||
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(this->_sdf_texture);
|
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(_sdf_texture);
|
||||||
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(this->_sdf_threshold);
|
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(_sdf_threshold);
|
||||||
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(this->_source_texture->get_object());
|
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(_source_texture->get_object());
|
||||||
_sdf_consumer_effect.get_parameter("pShadowColor").set_float4(this->_inner_shadow_color);
|
_sdf_consumer_effect.get_parameter("pShadowColor").set_float4(_inner_shadow_color);
|
||||||
_sdf_consumer_effect.get_parameter("pShadowMin").set_float(this->_inner_shadow_range_min);
|
_sdf_consumer_effect.get_parameter("pShadowMin").set_float(_inner_shadow_range_min);
|
||||||
_sdf_consumer_effect.get_parameter("pShadowMax").set_float(this->_inner_shadow_range_max);
|
_sdf_consumer_effect.get_parameter("pShadowMax").set_float(_inner_shadow_range_max);
|
||||||
_sdf_consumer_effect.get_parameter("pShadowOffset")
|
_sdf_consumer_effect.get_parameter("pShadowOffset")
|
||||||
.set_float2(this->_inner_shadow_offset_x / float_t(baseW),
|
.set_float2(_inner_shadow_offset_x / float_t(baseW), _inner_shadow_offset_y / float_t(baseH));
|
||||||
this->_inner_shadow_offset_y / float_t(baseH));
|
|
||||||
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "ShadowInner")) {
|
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "ShadowInner")) {
|
||||||
gs_draw_sprite(0, 0, 1, 1);
|
gs_draw_sprite(0, 0, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->_outer_glow) {
|
if (_outer_glow) {
|
||||||
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(this->_sdf_texture);
|
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(_sdf_texture);
|
||||||
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(this->_sdf_threshold);
|
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(_sdf_threshold);
|
||||||
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(this->_source_texture->get_object());
|
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(_source_texture->get_object());
|
||||||
_sdf_consumer_effect.get_parameter("pGlowColor").set_float4(this->_outer_glow_color);
|
_sdf_consumer_effect.get_parameter("pGlowColor").set_float4(_outer_glow_color);
|
||||||
_sdf_consumer_effect.get_parameter("pGlowWidth").set_float(this->_outer_glow_width);
|
_sdf_consumer_effect.get_parameter("pGlowWidth").set_float(_outer_glow_width);
|
||||||
_sdf_consumer_effect.get_parameter("pGlowSharpness").set_float(this->_outer_glow_sharpness);
|
_sdf_consumer_effect.get_parameter("pGlowSharpness").set_float(_outer_glow_sharpness);
|
||||||
_sdf_consumer_effect.get_parameter("pGlowSharpnessInverse").set_float(this->_outer_glow_sharpness_inv);
|
_sdf_consumer_effect.get_parameter("pGlowSharpnessInverse").set_float(_outer_glow_sharpness_inv);
|
||||||
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "GlowOuter")) {
|
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "GlowOuter")) {
|
||||||
gs_draw_sprite(0, 0, 1, 1);
|
gs_draw_sprite(0, 0, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->_inner_glow) {
|
if (_inner_glow) {
|
||||||
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(this->_sdf_texture);
|
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(_sdf_texture);
|
||||||
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(this->_sdf_threshold);
|
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(_sdf_threshold);
|
||||||
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(this->_source_texture->get_object());
|
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(_source_texture->get_object());
|
||||||
_sdf_consumer_effect.get_parameter("pGlowColor").set_float4(this->_inner_glow_color);
|
_sdf_consumer_effect.get_parameter("pGlowColor").set_float4(_inner_glow_color);
|
||||||
_sdf_consumer_effect.get_parameter("pGlowWidth").set_float(this->_inner_glow_width);
|
_sdf_consumer_effect.get_parameter("pGlowWidth").set_float(_inner_glow_width);
|
||||||
_sdf_consumer_effect.get_parameter("pGlowSharpness").set_float(this->_inner_glow_sharpness);
|
_sdf_consumer_effect.get_parameter("pGlowSharpness").set_float(_inner_glow_sharpness);
|
||||||
_sdf_consumer_effect.get_parameter("pGlowSharpnessInverse").set_float(this->_inner_glow_sharpness_inv);
|
_sdf_consumer_effect.get_parameter("pGlowSharpnessInverse").set_float(_inner_glow_sharpness_inv);
|
||||||
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "GlowInner")) {
|
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "GlowInner")) {
|
||||||
gs_draw_sprite(0, 0, 1, 1);
|
gs_draw_sprite(0, 0, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->_outline) {
|
if (_outline) {
|
||||||
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(this->_sdf_texture);
|
_sdf_consumer_effect.get_parameter("pSDFTexture").set_texture(_sdf_texture);
|
||||||
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(this->_sdf_threshold);
|
_sdf_consumer_effect.get_parameter("pSDFThreshold").set_float(_sdf_threshold);
|
||||||
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(this->_source_texture->get_object());
|
_sdf_consumer_effect.get_parameter("pImageTexture").set_texture(_source_texture->get_object());
|
||||||
_sdf_consumer_effect.get_parameter("pOutlineColor").set_float4(this->_outline_color);
|
_sdf_consumer_effect.get_parameter("pOutlineColor").set_float4(_outline_color);
|
||||||
_sdf_consumer_effect.get_parameter("pOutlineWidth").set_float(this->_outline_width);
|
_sdf_consumer_effect.get_parameter("pOutlineWidth").set_float(_outline_width);
|
||||||
_sdf_consumer_effect.get_parameter("pOutlineOffset").set_float(this->_outline_offset);
|
_sdf_consumer_effect.get_parameter("pOutlineOffset").set_float(_outline_offset);
|
||||||
_sdf_consumer_effect.get_parameter("pOutlineSharpness").set_float(this->_outline_sharpness);
|
_sdf_consumer_effect.get_parameter("pOutlineSharpness").set_float(_outline_sharpness);
|
||||||
_sdf_consumer_effect.get_parameter("pOutlineSharpnessInverse").set_float(this->_outline_sharpness_inv);
|
_sdf_consumer_effect.get_parameter("pOutlineSharpnessInverse").set_float(_outline_sharpness_inv);
|
||||||
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "Outline")) {
|
while (gs_effect_loop(_sdf_consumer_effect.get_object(), "Outline")) {
|
||||||
gs_draw_sprite(0, 0, 1, 1);
|
gs_draw_sprite(0, 0, 1, 1);
|
||||||
}
|
}
|
||||||
|
@ -492,20 +488,20 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_output_rt->get_texture(this->_output_texture);
|
_output_rt->get_texture(_output_texture);
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
this->_output_rendered = true;
|
_output_rendered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->_output_texture) {
|
if (!_output_texture) {
|
||||||
obs_source_skip_video_filter(this->_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_eparam_t* ep = gs_effect_get_param_by_name(final_effect, "image");
|
gs_eparam_t* ep = gs_effect_get_param_by_name(final_effect, "image");
|
||||||
if (ep) {
|
if (ep) {
|
||||||
gs_effect_set_texture(ep, this->_output_texture->get_object());
|
gs_effect_set_texture(ep, _output_texture->get_object());
|
||||||
}
|
}
|
||||||
while (gs_effect_loop(final_effect, "Draw")) {
|
while (gs_effect_loop(final_effect, "Draw")) {
|
||||||
gs_draw_sprite(0, 0, baseW, baseH);
|
gs_draw_sprite(0, 0, baseW, baseH);
|
||||||
|
@ -518,6 +514,7 @@ filter::sdf_effects::sdf_effects_factory::sdf_effects_factory()
|
||||||
_info.type = OBS_SOURCE_TYPE_FILTER;
|
_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
_info.output_flags = OBS_SOURCE_VIDEO;
|
_info.output_flags = OBS_SOURCE_VIDEO;
|
||||||
|
|
||||||
|
set_resolution_enabled(false);
|
||||||
finish_setup();
|
finish_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -405,6 +405,7 @@ filter::transform::transform_factory::transform_factory()
|
||||||
_info.type = OBS_SOURCE_TYPE_FILTER;
|
_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
_info.output_flags = OBS_SOURCE_VIDEO;
|
_info.output_flags = OBS_SOURCE_VIDEO;
|
||||||
|
|
||||||
|
set_resolution_enabled(false);
|
||||||
finish_setup();
|
finish_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,8 @@ source::mirror::mirror_instance::mirror_instance(obs_data_t* settings, obs_sourc
|
||||||
// Spawn Audio Thread
|
// Spawn Audio Thread
|
||||||
/// ToDo: Use ThreadPool for this?
|
/// ToDo: Use ThreadPool for this?
|
||||||
_audio_thread = std::thread(std::bind(&source::mirror::mirror_instance::audio_output_cb, this));
|
_audio_thread = std::thread(std::bind(&source::mirror::mirror_instance::audio_output_cb, this));
|
||||||
|
|
||||||
|
update(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
source::mirror::mirror_instance::~mirror_instance()
|
source::mirror::mirror_instance::~mirror_instance()
|
||||||
|
|
Loading…
Reference in a new issue