From 5291b193e2f4ac882d6b1acca3438c2f7cc08637 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Thu, 23 Apr 2020 07:56:12 +0200 Subject: [PATCH] gfx-shader: Fix rendering at unexpected sizes and fix performance Fixes rendering at unexpected sizes by first rendering to a render target and then rendering the contents of that render target to the frame buffer instead. This also prevent rendering twice or more, which might cause severe FPS impact. --- source/gfx/shader/gfx-shader.cpp | 23 +++++++++++++++++++++-- source/gfx/shader/gfx-shader.hpp | 5 +++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/source/gfx/shader/gfx-shader.cpp b/source/gfx/shader/gfx-shader.cpp index 353b8bc..d651b27 100644 --- a/source/gfx/shader/gfx-shader.cpp +++ b/source/gfx/shader/gfx-shader.cpp @@ -39,7 +39,9 @@ gfx::shader::shader::shader(obs_source_t* self, shader_mode mode) _width_type(size_type::Percent), _width_value(1.0), _height_type(size_type::Percent), _height_value(1.0), - _time(0), _time_loop(0), _loops(0), _random(), _have_current_params(false) + _time(0), _time_loop(0), _loops(0), _random(), _have_current_params(false), + + _rt_up_to_date(false), _rt(std::make_shared(GS_RGBA, GS_ZS_NONE)) { _random.seed(static_cast(time(NULL))); } @@ -453,6 +455,8 @@ void gfx::shader::shader::prepare_render() 1.0f / static_cast(width()), 1.0f / static_cast(height())); } } + + _rt_up_to_date = false; } void gfx::shader::shader::render() @@ -460,7 +464,22 @@ void gfx::shader::shader::render() if (!_shader) return; - while (gs_effect_loop(_shader.get_object(), _shader_tech.c_str())) { + if (!_rt_up_to_date) { + auto op = _rt->render(width(), height()); + vec4 zero = {0, 0, 0, 0}; + gs_ortho(0, width(), 0, height(), 0, 1); + gs_clear(GS_CLEAR_COLOR, &zero, 0, 0); + gs_enable_blending(true); + gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO); + gs_enable_color(true, true, true, true); + while (gs_effect_loop(_shader.get_object(), _shader_tech.c_str())) { + gs_draw_sprite(nullptr, 0, width(), height()); + } + } + + gs_effect_set_texture(gs_effect_get_param_by_name(obs_get_base_effect(OBS_EFFECT_DEFAULT), "image"), + _rt->get_texture()->get_object()); + while (gs_effect_loop(obs_get_base_effect(OBS_EFFECT_DEFAULT), "Draw")) { gs_draw_sprite(nullptr, 0, width(), height()); } } diff --git a/source/gfx/shader/gfx-shader.hpp b/source/gfx/shader/gfx-shader.hpp index b585c93..3497cf3 100644 --- a/source/gfx/shader/gfx-shader.hpp +++ b/source/gfx/shader/gfx-shader.hpp @@ -23,6 +23,7 @@ #include #include "gfx/shader/gfx-shader-param.hpp" #include "obs/gs/gs-effect.hpp" +#include "obs/gs/gs-rendertarget.hpp" namespace gfx { namespace shader { @@ -69,6 +70,10 @@ namespace gfx { std::mt19937_64 _random; bool _have_current_params; + // Rendering + bool _rt_up_to_date; + std::shared_ptr _rt; + public: shader(obs_source_t* self, shader_mode mode); ~shader();