diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index fe7eda42..4aba25a3 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -63,6 +63,7 @@ MipGenerator.Intensity.Description="Intensity of the generator." # Shader Shader="Shader" +Shader.Refresh="Refresh Options and Parameters" Shader.Shader="Shader Options" Shader.Shader.File="File" Shader.Shader.Technique="Technique" diff --git a/source/gfx/shader/gfx-shader.cpp b/source/gfx/shader/gfx-shader.cpp index a8f6a399..4e0fd84c 100644 --- a/source/gfx/shader/gfx-shader.cpp +++ b/source/gfx/shader/gfx-shader.cpp @@ -23,6 +23,7 @@ #include "plugin.hpp" #define ST "Shader" +#define ST_REFRESH ST ".Refresh" #define ST_SHADER ST ".Shader" #define ST_SHADER_FILE ST_SHADER ".File" #define ST_SHADER_TECHNIQUE ST_SHADER ".Technique" @@ -183,6 +184,15 @@ void gfx::shader::shader::properties(obs_properties_t* pr) { _have_current_params = false; + { + auto p = obs_properties_add_button2( + pr, ST_REFRESH, D_TRANSLATE(ST_REFRESH), + [](obs_properties_t* props, obs_property_t* prop, void* priv) { + return reinterpret_cast(priv)->on_refresh_properties(props, prop); + }, + this); + } + { auto grp = obs_properties_create(); obs_properties_add_group(pr, ST_SHADER, D_TRANSLATE(ST_SHADER), OBS_GROUP_NORMAL, grp); @@ -191,24 +201,25 @@ void gfx::shader::shader::properties(obs_properties_t* pr) auto p = obs_properties_add_path(grp, ST_SHADER_FILE, D_TRANSLATE(ST_SHADER_FILE), OBS_PATH_FILE, "*.*", nullptr); obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADER_FILE))); - obs_property_set_modified_callback2( + /*obs_property_set_modified_callback2( p, [](void* priv, obs_properties_t* props, obs_property_t* prop, obs_data_t* data) noexcept { - return reinterpret_cast(priv)->on_properties_modified(props, prop, data); + return reinterpret_cast(priv)->on_shader_or_technique_modified(props, prop, data); }, - this); + this);*/ } { auto p = obs_properties_add_list(grp, ST_SHADER_TECHNIQUE, D_TRANSLATE(ST_SHADER_TECHNIQUE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADER_TECHNIQUE))); - obs_property_set_modified_callback2( + /*obs_property_set_modified_callback2( p, [](void* priv, obs_properties_t* props, obs_property_t* prop, obs_data_t* data) noexcept { - return reinterpret_cast(priv)->on_properties_modified(props, prop, data); + return reinterpret_cast(priv)->on_shader_or_technique_modified(props, prop, data); }, - this); + this);*/ } + if (_mode != shader_mode::Transition) { auto grp2 = obs_properties_create(); obs_properties_add_group(grp, ST_SHADER_SIZE, D_TRANSLATE(ST_SHADER_SIZE), OBS_GROUP_NORMAL, grp2); @@ -229,9 +240,42 @@ void gfx::shader::shader::properties(obs_properties_t* pr) auto grp = obs_properties_create(); obs_properties_add_group(pr, ST_PARAMETERS, D_TRANSLATE(ST_PARAMETERS), OBS_GROUP_NORMAL, grp); } + + // Manually call the refresh. + on_refresh_properties(pr, nullptr); } -bool gfx::shader::shader::on_properties_modified(obs_properties_t* props, obs_property_t* prop, obs_data_t* data) +bool gfx::shader::shader::on_refresh_properties(obs_properties_t* props, obs_property_t* prop) +{ + if (_shader) { // Clear list of techniques and rebuild it. + obs_property_t* p_tech_list = obs_properties_get(props, ST_SHADER_TECHNIQUE); + obs_property_list_clear(p_tech_list); + for (size_t idx = 0; idx < _shader.count_techniques(); idx++) { + auto tech = _shader.get_technique(idx); + obs_property_list_add_string(p_tech_list, tech.name().c_str(), tech.name().c_str()); + } + } + { // Clear parameter options. + auto grp = obs_property_group_content(obs_properties_get(props, ST_PARAMETERS)); + for (auto p = obs_properties_first(grp); p != nullptr; p = obs_properties_first(grp)) { + obs::tools::obs_properties_remove_by_name(grp, obs_property_name(p)); + } + + // Rebuild new parameters. + obs_data_t* data = obs_source_get_settings(_self); + for (auto kv : _shader_params) { + kv.second->properties(grp, data); + kv.second->defaults(data); + kv.second->update(data); + } + obs_source_update(_self, data); + } + + return true; +} + +bool gfx::shader::shader::on_shader_or_technique_modified(obs_properties_t* props, obs_property_t* prop, + obs_data_t* data) { bool shader_dirty = false; bool param_dirty = false; diff --git a/source/gfx/shader/gfx-shader.hpp b/source/gfx/shader/gfx-shader.hpp index 078758ae..0fdf98c0 100644 --- a/source/gfx/shader/gfx-shader.hpp +++ b/source/gfx/shader/gfx-shader.hpp @@ -65,7 +65,7 @@ namespace gfx { // Cache float_t _time; float_t _time_loop; - int32_t _loops; + int32_t _loops; std::mt19937_64 _random; bool _have_current_params; @@ -84,7 +84,9 @@ namespace gfx { void properties(obs_properties_t* props); - bool on_properties_modified(obs_properties_t* props, obs_property_t* prop, obs_data_t* data); + bool on_refresh_properties(obs_properties_t* props, obs_property_t* prop); + + bool on_shader_or_technique_modified(obs_properties_t* props, obs_property_t* prop, obs_data_t* data); bool update_shader(obs_data_t* data, bool& shader_dirty, bool& param_dirty);