From 7708dd07927a92960ce121e410238e211505f5ae Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Fri, 25 Jan 2019 00:54:34 +0100 Subject: [PATCH] filter-shadow-sdf: Refactoring, fix and optimize rendering Fixes the m_source_texture = nullptr bug, which happened due to m_tick and m_last_tick both being 0, as no video_tick is called when the source is first created. Instead a boolean flag is now used that is reset to false on each video_tick. --- source/filter-shadow-sdf.cpp | 23 ++++++++++++----------- source/filter-shadow-sdf.hpp | 10 +++++++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/source/filter-shadow-sdf.cpp b/source/filter-shadow-sdf.cpp index b92e5f1e..fe80d886 100644 --- a/source/filter-shadow-sdf.cpp +++ b/source/filter-shadow-sdf.cpp @@ -72,9 +72,9 @@ bool filter::shadow_sdf::shadow_sdf_instance::cb_modified_outside(void*, obs_pro } filter::shadow_sdf::shadow_sdf_instance::shadow_sdf_instance(obs_data_t* settings, obs_source_t* self) + : m_self(self), m_source_rendered(false) { - this->m_self = self; - this->m_input = std::make_shared(GS_RGBA, GS_ZS_NONE); + this->m_source_rt = std::make_shared(GS_RGBA, GS_ZS_NONE); this->m_sdf_write = std::make_shared(GS_RGBA32F, GS_ZS_NONE); { auto op = this->m_sdf_write->render(1, 1); @@ -186,15 +186,16 @@ void filter::shadow_sdf::shadow_sdf_instance::deactivate() {} void filter::shadow_sdf::shadow_sdf_instance::video_tick(float time) { this->m_tick += time; + m_source_rendered = false; } void filter::shadow_sdf::shadow_sdf_instance::video_render(gs_effect_t*) { - obs_source_t* parent = obs_filter_get_parent(this->m_self); - obs_source_t* target = obs_filter_get_target(this->m_self); - uint32_t baseW = obs_source_get_base_width(target); - uint32_t baseH = obs_source_get_base_height(target); - gs_effect_t* default_effect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT); + obs_source_t* parent = obs_filter_get_parent(this->m_self); + obs_source_t* target = obs_filter_get_target(this->m_self); + uint32_t baseW = obs_source_get_base_width(target); + uint32_t baseH = obs_source_get_base_height(target); + gs_effect_t* default_effect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT); vec4 color_transparent; vec4_zero(&color_transparent); @@ -204,10 +205,10 @@ void filter::shadow_sdf::shadow_sdf_instance::video_render(gs_effect_t*) } try { - if (this->m_tick != this->m_last_tick) { + if (!this->m_source_rendered) { // Store input texture. { - auto op = m_input->render(baseW, baseH); + auto op = m_source_rt->render(baseW, baseH); gs_ortho(0, (float)baseW, 0, (float)baseH, -1, 1); gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0); gs_set_cull_mode(GS_NEITHER); @@ -225,7 +226,7 @@ void filter::shadow_sdf::shadow_sdf_instance::video_render(gs_effect_t*) throw std::runtime_error("failed to process source"); } } - m_input->get_texture(this->m_source_texture); + m_source_rt->get_texture(this->m_source_texture); if (!this->m_source_texture) { throw std::runtime_error("failed to draw source"); } @@ -333,9 +334,9 @@ void filter::shadow_sdf::shadow_sdf_instance::video_render(gs_effect_t*) obs_source_skip_video_filter(this->m_self); return; } + gs_reset_blend_state(); gs_enable_depth_test(false); - this->m_last_tick = this->m_tick; } filter::shadow_sdf::shadow_sdf_factory::shadow_sdf_factory() diff --git a/source/filter-shadow-sdf.hpp b/source/filter-shadow-sdf.hpp index b94b36c2..2ae61967 100644 --- a/source/filter-shadow-sdf.hpp +++ b/source/filter-shadow-sdf.hpp @@ -43,13 +43,17 @@ namespace filter { namespace shadow_sdf { class shadow_sdf_instance { obs_source_t* m_self; - std::shared_ptr m_input; - std::shared_ptr m_sdf_write, m_sdf_read; + + // Input + std::shared_ptr m_source_rt; std::shared_ptr m_source_texture; + bool m_source_rendered; + + // Distance Field + std::shared_ptr m_sdf_write, m_sdf_read; std::shared_ptr m_sdf_texture; float_t m_tick = 0.; - float_t m_last_tick = 0.; bool m_inner_shadow; float_t m_inner_range_min;