diff --git a/source/gfx/shader/gfx-shader-param.cpp b/source/gfx/shader/gfx-shader-param.cpp index 649b37c..141dc00 100644 --- a/source/gfx/shader/gfx-shader-param.cpp +++ b/source/gfx/shader/gfx-shader-param.cpp @@ -16,9 +16,98 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #include "gfx-shader-param.hpp" +#include #include #include "gfx-shader-param-basic.hpp" +#define ANNO_ORDER "order" +#define ANNO_VISIBILITY "visible" +#define ANNO_NAME "name" +#define ANNO_DESCRIPTION "description" +#define ANNO_TYPE "type" +#define ANNO_SIZE "size" + +typedef gs::effect_parameter::type eptype; + +gfx::shader::parameter_type gfx::shader::get_type_from_effect_type(gs::effect_parameter::type type) +{ + switch (type) { + case eptype::Boolean: + return parameter_type::Boolean; + case eptype::Integer: + case eptype::Integer2: + case eptype::Integer3: + case eptype::Integer4: + return parameter_type::Integer; + case eptype::Float: + case eptype::Float2: + case eptype::Float3: + case eptype::Float4: + case eptype::Matrix: + return parameter_type::Float; + case eptype::String: + return parameter_type::String; + case eptype::Texture: + return parameter_type::Texture; + default: + return parameter_type::Unknown; + } +} + +size_t gfx::shader::get_length_from_effect_type(gs::effect_parameter::type type) +{ + switch (type) { + case eptype::Unknown: + case eptype::Invalid: + case eptype::String: + return 0; + case eptype::Boolean: + case eptype::Float: + case eptype::Integer: + case eptype::Texture: + return 1; + case eptype::Float2: + case eptype::Integer2: + return 2; + case eptype::Float3: + case eptype::Integer3: + return 3; + case eptype::Float4: + case eptype::Integer4: + return 4; + case eptype::Matrix: + return 16; + } +} + +gfx::shader::parameter_type gfx::shader::get_type_from_string(std::string v) +{ + if ((v == "bool") || (v == "boolean")) { + return parameter_type::Boolean; + } + if ((v == "float") || (v == "single")) { + return parameter_type::Float; + } + if ((v == "int") || (v == "integer")) { + return parameter_type::Integer; + } + if ((v == "text") || (v == "string")) { + return parameter_type::String; + } + if ((v == "tex") || (v == "texture")) { + return parameter_type::Texture; + } + if ((v == "sampler")) { + return parameter_type::Sampler; + } + /* To decide on in the future: + * - Double support? + * - Half Support? + * - Texture Arrays? (Likely not supported in libobs) + */ + throw std::invalid_argument("Invalid parameter type string."); +} + gfx::shader::parameter::parameter(gs::effect_parameter param, std::string key_prefix) : _param(param), _order(0), _key(_param.get_name()), _name(_key), _description() { @@ -28,17 +117,44 @@ gfx::shader::parameter::parameter(gs::effect_parameter param, std::string key_pr _name = (_key); } - if (auto anno = _param.get_annotation("order"); anno) { + // Read Order + if (auto anno = _param.get_annotation(ANNO_ORDER); anno) { _order = anno.get_default_int(); } - if (auto anno = _param.get_annotation("name"); anno) { - if (std::string v = anno.get_default_string(); v.length() > 0) + + // Read Name + if (auto anno = _param.get_annotation(ANNO_NAME); anno) { + if (std::string v = anno.get_default_string(); v.length() > 0) { _name = v; + } else { + throw std::out_of_range("'" ANNO_NAME "' annotation has zero length."); + } } - if (auto anno = _param.get_annotation("description"); anno) { - if (std::string v = anno.get_default_string(); v.length() > 0) + + // Read Description + if (auto anno = _param.get_annotation(ANNO_DESCRIPTION); anno) { + if (std::string v = anno.get_default_string(); v.length() > 0) { _description = v; + } else { + throw std::out_of_range("'" ANNO_DESCRIPTION "' annotation has zero length."); + } } + + // Read Type override. + _type = get_type_from_effect_type(_param.get_type()); + if (auto anno = _param.get_annotation(ANNO_TYPE); anno) { + // We have a type override. + _type = get_type_from_string(anno.get_default_string()); + } + + // Read Size override. + _size = get_length_from_effect_type(_param.get_type()); + if (auto anno = _param.get_annotation(ANNO_SIZE); anno) { + size_t ov = anno.get_default_int(); + if (ov > 0) + _size = ov; + } + _size = std::clamp(_size, 1ull, 32ull); } void gfx::shader::parameter::defaults(obs_data_t* settings) {} @@ -49,11 +165,36 @@ void gfx::shader::parameter::update(obs_data_t* settings) {} void gfx::shader::parameter::assign() {} +gs::effect_parameter gfx::shader::parameter::get_parameter() +{ + return gs::effect_parameter(); +} + +gfx::shader::parameter_type gfx::shader::parameter::get_type() +{ + return _type; +} + +size_t gfx::shader::parameter::get_size() +{ + return _size; +} + int32_t gfx::shader::parameter::get_order() { return _order; } +const std::string& gfx::shader::parameter::get_key() +{ + return _key; +} + +bool gfx::shader::parameter::has_name() +{ + return _name.length() > 0; +} + const std::string& gfx::shader::parameter::get_name() { return _name; @@ -72,36 +213,23 @@ const std::string& gfx::shader::parameter::get_description() std::shared_ptr gfx::shader::parameter::make_parameter(gs::effect_parameter param, std::string prefix) { - if (!param) - return nullptr; - - // ToDo: Allow other parameters to specify hidden properties, as well as the shader itself, and the source/filter/transition. - if (auto anno = param.get_annotation("visible"); anno != nullptr) { - if (!anno.get_default_bool()) { - return nullptr; - } + if (!param) { + throw std::runtime_error("Bad call to make_parameter. This is a bug in the plugin."); } - typedef gs::effect_parameter::type eptype; - switch (param.get_type()) { - case eptype::Boolean: { - auto el = std::make_shared(param, prefix); - return el; - } - case eptype::Integer: - case eptype::Integer2: - case eptype::Integer3: - case eptype::Integer4: { - auto el = std::make_shared(param, prefix); - return el; - } - case eptype::Float: - case eptype::Float2: - case eptype::Float3: - case eptype::Float4: { - auto el = std::make_shared(param, prefix); - return el; + parameter_type real_type = get_type_from_effect_type(param.get_type()); + if (auto anno = param.get_annotation(ANNO_TYPE); anno) { + // We have a type override. + parameter_type real_type = get_type_from_string(param.get_default_string()); } + + switch (real_type) { + case parameter_type::Boolean: + return std::make_shared(param, prefix); + case parameter_type::Integer: + return std::make_shared(param, prefix); + case parameter_type::Float: + return std::make_shared(param, prefix); default: return nullptr; } diff --git a/source/gfx/shader/gfx-shader-param.hpp b/source/gfx/shader/gfx-shader-param.hpp index 5beb9ba..9aa4046 100644 --- a/source/gfx/shader/gfx-shader-param.hpp +++ b/source/gfx/shader/gfx-shader-param.hpp @@ -34,19 +34,54 @@ extern "C" { namespace gfx { namespace shader { + enum class parameter_type { + // Unknown type, could be anything. + Unknown, + // Boolean, either false or true. + Boolean, + // Single Floating Point + Float, + // 32-Bit Integer + Integer, + // UTF-8 Character based String. + String, + // Texture with dimensions stored in size (1 = Texture1D, 2 = Texture2D, 3 = Texture3D, 6 = TextureCube). + Texture, + // Sampler for Textures. + Sampler + }; + + parameter_type get_type_from_effect_type(gs::effect_parameter::type type); + + size_t get_length_from_effect_type(gs::effect_parameter::type type); + + parameter_type get_type_from_string(std::string v); + class parameter { - protected: + // Parameter used for all functionality. gs::effect_parameter _param; - int32_t _order; + // Real type of the parameter (libobs gets it wrong often). + parameter_type _type; + + // Real size of the parameter (libobs gets it wrong often). + size_t _size; + + // Order of the parameter in a list/map. + int32_t _order; + + // Key for the parameter (group) in a list/map. std::string _key; + + // Visibility, name and description. + bool _visible; std::string _name; std::string _description; + protected: parameter(gs::effect_parameter param, std::string key_prefix); virtual ~parameter(){}; - public: virtual void defaults(obs_data_t* settings); virtual void properties(obs_properties_t* props, obs_data_t* settings); @@ -56,8 +91,20 @@ namespace gfx { virtual void assign(); public: + gs::effect_parameter get_parameter(); + + parameter_type get_type(); + + size_t get_size(); + int32_t get_order(); + const std::string& get_key(); + + bool is_visible(); + + bool has_name(); + const std::string& get_name(); bool has_description();