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.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2019-01-25 00:54:34 +01:00
parent d29f5ce477
commit 7708dd0792
2 changed files with 19 additions and 14 deletions

View File

@ -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) 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_source_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
this->m_input = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
this->m_sdf_write = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE); this->m_sdf_write = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
{ {
auto op = this->m_sdf_write->render(1, 1); 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) void filter::shadow_sdf::shadow_sdf_instance::video_tick(float time)
{ {
this->m_tick += time; this->m_tick += time;
m_source_rendered = false;
} }
void filter::shadow_sdf::shadow_sdf_instance::video_render(gs_effect_t*) 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* parent = obs_filter_get_parent(this->m_self);
obs_source_t* target = obs_filter_get_target(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 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* 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);
vec4 color_transparent; vec4 color_transparent;
vec4_zero(&color_transparent); vec4_zero(&color_transparent);
@ -204,10 +205,10 @@ void filter::shadow_sdf::shadow_sdf_instance::video_render(gs_effect_t*)
} }
try { try {
if (this->m_tick != this->m_last_tick) { if (!this->m_source_rendered) {
// Store input texture. // 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_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);
gs_set_cull_mode(GS_NEITHER); 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"); 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) { if (!this->m_source_texture) {
throw std::runtime_error("failed to draw source"); 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); obs_source_skip_video_filter(this->m_self);
return; return;
} }
gs_reset_blend_state(); gs_reset_blend_state();
gs_enable_depth_test(false); gs_enable_depth_test(false);
this->m_last_tick = this->m_tick;
} }
filter::shadow_sdf::shadow_sdf_factory::shadow_sdf_factory() filter::shadow_sdf::shadow_sdf_factory::shadow_sdf_factory()

View File

@ -43,13 +43,17 @@ namespace filter {
namespace shadow_sdf { namespace shadow_sdf {
class shadow_sdf_instance { class shadow_sdf_instance {
obs_source_t* m_self; obs_source_t* m_self;
std::shared_ptr<gs::rendertarget> m_input;
std::shared_ptr<gs::rendertarget> m_sdf_write, m_sdf_read; // Input
std::shared_ptr<gs::rendertarget> m_source_rt;
std::shared_ptr<gs::texture> m_source_texture; std::shared_ptr<gs::texture> m_source_texture;
bool m_source_rendered;
// Distance Field
std::shared_ptr<gs::rendertarget> m_sdf_write, m_sdf_read;
std::shared_ptr<gs::texture> m_sdf_texture; std::shared_ptr<gs::texture> m_sdf_texture;
float_t m_tick = 0.; float_t m_tick = 0.;
float_t m_last_tick = 0.;
bool m_inner_shadow; bool m_inner_shadow;
float_t m_inner_range_min; float_t m_inner_range_min;