From ff6f4d5ddf753e6e05c5095396ad63609ed3911b Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sun, 4 Aug 2019 22:44:46 +0200 Subject: [PATCH] gs-effect: Add string support, get accessors and annotations --- source/obs/gs/gs-effect.cpp | 448 +++++++++++++++++++++++++++++++++++- source/obs/gs/gs-effect.hpp | 59 ++++- 2 files changed, 490 insertions(+), 17 deletions(-) diff --git a/source/obs/gs/gs-effect.cpp b/source/obs/gs/gs-effect.cpp index d2d32f39..9024415e 100644 --- a/source/obs/gs/gs-effect.cpp +++ b/source/obs/gs/gs-effect.cpp @@ -72,7 +72,7 @@ gs::effect::effect(std::string file) : effect() char* errorMessage = nullptr; auto gctx = gs::context(); - _effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage); + _effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage); if (!_effect || errorMessage) { std::string error = "Generic Error"; if (errorMessage) { @@ -88,7 +88,7 @@ gs::effect::effect(std::string code, std::string name) : effect() { char* errorMessage = nullptr; auto gctx = gs::context(); - _effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage); + _effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage); if (!_effect || errorMessage) { std::string error = "Generic Error"; if (errorMessage) { @@ -194,8 +194,8 @@ gs::effect_parameter::type gs::effect_parameter::get_type() return type::Matrix; case GS_SHADER_PARAM_TEXTURE: return type::Texture; - //case GS_SHADER_PARAM_STRING: - // return Type::String; + case GS_SHADER_PARAM_STRING: + return type::String; default: case GS_SHADER_PARAM_UNKNOWN: return type::Unknown; @@ -209,6 +209,32 @@ void gs::effect_parameter::set_bool(bool v) gs_effect_set_bool(_param, v); } +void gs::effect_parameter::get_bool(bool& v) +{ + if (get_type() != type::Boolean) + throw std::bad_cast(); + void* ptr = gs_effect_get_val(_param); + if (ptr) { + v = *reinterpret_cast(ptr); + bfree(ptr); + } else { + v = false; + } +} + +void gs::effect_parameter::get_default_bool(bool& v) +{ + if (get_type() != type::Boolean) + throw std::bad_cast(); + void* ptr = gs_effect_get_default_val(_param); + if (ptr) { + v = *reinterpret_cast(ptr); + bfree(ptr); + } else { + v = false; + } +} + void gs::effect_parameter::set_bool_array(bool v[], size_t sz) { if (get_type() != type::Boolean) @@ -223,28 +249,102 @@ void gs::effect_parameter::set_float(float_t x) gs_effect_set_float(_param, x); } -void gs::effect_parameter::set_float2(vec2& v) +void gs::effect_parameter::get_float(float_t& x) +{ + if (get_type() != type::Float) + throw std::bad_cast(); + void* ptr = gs_effect_get_val(_param); + if (ptr) { + x = *reinterpret_cast(ptr); + bfree(ptr); + } else { + x = 0; + } +} + +void gs::effect_parameter::get_default_float(float_t& x) +{ + if (get_type() != type::Float) + throw std::bad_cast(); + void* ptr = gs_effect_get_default_val(_param); + if (ptr) { + x = *reinterpret_cast(ptr); + bfree(ptr); + } else { + x = 0; + } +} + +void gs::effect_parameter::set_float2(vec2 const& v) { if (get_type() != type::Float2) throw std::bad_cast(); gs_effect_set_vec2(_param, &v); } +void gs::effect_parameter::get_float2(vec2& v) +{ + get_float2(v.x, v.y); +} + +void gs::effect_parameter::get_default_float2(vec2& v) +{ + get_default_float2(v.x, v.y); +} + void gs::effect_parameter::set_float2(float_t x, float_t y) { - if (get_type() != type::Float2) - throw std::bad_cast(); - vec2 v = {{x, y}}; - gs_effect_set_vec2(_param, &v); + vec2 data; + data.x = x; + data.y = y; + set_float2(data); } -void gs::effect_parameter::set_float3(vec3& v) +void gs::effect_parameter::get_float2(float_t& x, float_t& y) +{ + if (get_type() != type::Float2) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(float_t)); + bfree(ptr); + } else { + x, y = 0; + } +} + +void gs::effect_parameter::get_default_float2(float_t& x, float_t& y) +{ + if (get_type() != type::Float2) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(float_t)); + bfree(ptr); + } else { + x, y = 0; + } +} + +void gs::effect_parameter::set_float3(vec3 const& v) { if (get_type() != type::Float3) throw std::bad_cast(); gs_effect_set_vec3(_param, &v); } +void gs::effect_parameter::get_float3(vec3& v) +{ + get_float3(v.x, v.y, v.z); +} + +void gs::effect_parameter::get_default_float3(vec3& v) +{ + get_default_float3(v.x, v.y, v.z); +} + void gs::effect_parameter::set_float3(float_t x, float_t y, float_t z) { if (get_type() != type::Float3) @@ -253,13 +353,53 @@ void gs::effect_parameter::set_float3(float_t x, float_t y, float_t z) gs_effect_set_vec3(_param, &v); } -void gs::effect_parameter::set_float4(vec4& v) +void gs::effect_parameter::get_float3(float_t& x, float_t& y, float_t& z) +{ + if (get_type() != type::Float3) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(float_t)); + z = *reinterpret_cast(ptr + sizeof(float_t) * 2); + bfree(ptr); + } else { + x, y, z = 0; + } +} + +void gs::effect_parameter::get_default_float3(float_t& x, float_t& y, float_t& z) +{ + if (get_type() != type::Float3) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(float_t)); + z = *reinterpret_cast(ptr + sizeof(float_t) * 2); + bfree(ptr); + } else { + x, y, z = 0; + } +} + +void gs::effect_parameter::set_float4(vec4 const& v) { if (get_type() != type::Float4) throw std::bad_cast(); gs_effect_set_vec4(_param, &v); } +void gs::effect_parameter::get_float4(vec4& v) +{ + get_float4(v.x, v.y, v.z, v.w); +} + +void gs::effect_parameter::get_default_float4(vec4& v) +{ + get_default_float4(v.x, v.y, v.z, v.w); +} + void gs::effect_parameter::set_float4(float_t x, float_t y, float_t z, float_t w) { if (get_type() != type::Float4) @@ -268,6 +408,38 @@ void gs::effect_parameter::set_float4(float_t x, float_t y, float_t z, float_t w gs_effect_set_vec4(_param, &v); } +void gs::effect_parameter::get_float4(float_t& x, float_t& y, float_t& z, float_t& w) +{ + if (get_type() != type::Float4) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(float_t)); + z = *reinterpret_cast(ptr + sizeof(float_t) * 2); + w = *reinterpret_cast(ptr + sizeof(float_t) * 3); + bfree(ptr); + } else { + x, y, z, w = 0; + } +} + +void gs::effect_parameter::get_default_float4(float_t& x, float_t& y, float_t& z, float_t& w) +{ + if (get_type() != type::Float4) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(float_t)); + z = *reinterpret_cast(ptr + sizeof(float_t) * 2); + w = *reinterpret_cast(ptr + sizeof(float_t) * 3); + bfree(ptr); + } else { + x, y, z, w = 0; + } +} + void gs::effect_parameter::set_float_array(float_t v[], size_t sz) { if ((get_type() != type::Float) && (get_type() != type::Float2) && (get_type() != type::Float3) @@ -283,6 +455,32 @@ void gs::effect_parameter::set_int(int32_t x) gs_effect_set_int(_param, x); } +void gs::effect_parameter::get_int(int32_t& x) +{ + if ((get_type() != type::Integer) && (get_type() != type::Unknown)) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + bfree(ptr); + } else { + x = 0; + } +} + +void gs::effect_parameter::get_default_int(int32_t& x) +{ + if ((get_type() != type::Integer) && (get_type() != type::Unknown)) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + bfree(ptr); + } else { + x = 0; + } +} + void gs::effect_parameter::set_int2(int32_t x, int32_t y) { if ((get_type() != type::Integer2) && (get_type() != type::Unknown)) @@ -291,6 +489,34 @@ void gs::effect_parameter::set_int2(int32_t x, int32_t y) gs_effect_set_val(_param, v, sizeof(int) * 2); } +void gs::effect_parameter::get_int2(int32_t& x, int32_t& y) +{ + if ((get_type() != type::Integer2) && (get_type() != type::Unknown)) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(int32_t)); + bfree(ptr); + } else { + x, y = 0; + } +} + +void gs::effect_parameter::get_default_int2(int32_t& x, int32_t& y) +{ + if ((get_type() != type::Integer2) && (get_type() != type::Unknown)) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(int32_t)); + bfree(ptr); + } else { + x, y = 0; + } +} + void gs::effect_parameter::set_int3(int32_t x, int32_t y, int32_t z) { if ((get_type() != type::Integer3) && (get_type() != type::Unknown)) @@ -299,6 +525,36 @@ void gs::effect_parameter::set_int3(int32_t x, int32_t y, int32_t z) gs_effect_set_val(_param, v, sizeof(int) * 3); } +void gs::effect_parameter::get_int3(int32_t& x, int32_t& y, int32_t& z) +{ + if ((get_type() != type::Integer3) && (get_type() != type::Unknown)) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(int32_t)); + z = *reinterpret_cast(ptr + sizeof(int32_t) * 2); + bfree(ptr); + } else { + x, y, z = 0; + } +} + +void gs::effect_parameter::get_default_int3(int32_t& x, int32_t& y, int32_t& z) +{ + if ((get_type() != type::Integer3) && (get_type() != type::Unknown)) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(int32_t)); + z = *reinterpret_cast(ptr + sizeof(int32_t) * 2); + bfree(ptr); + } else { + x, y, z = 0; + } +} + void gs::effect_parameter::set_int4(int32_t x, int32_t y, int32_t z, int32_t w) { if ((get_type() != type::Integer4) && (get_type() != type::Unknown)) @@ -307,6 +563,38 @@ void gs::effect_parameter::set_int4(int32_t x, int32_t y, int32_t z, int32_t w) gs_effect_set_val(_param, v, sizeof(int) * 4); } +void gs::effect_parameter::get_int4(int32_t& x, int32_t& y, int32_t& z, int32_t& w) +{ + if ((get_type() != type::Integer4) && (get_type() != type::Unknown)) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(int32_t)); + z = *reinterpret_cast(ptr + sizeof(int32_t) * 2); + w = *reinterpret_cast(ptr + sizeof(int32_t) * 3); + bfree(ptr); + } else { + x, y, z, w = 0; + } +} + +void gs::effect_parameter::get_default_int4(int32_t& x, int32_t& y, int32_t& z, int32_t& w) +{ + if ((get_type() != type::Integer4) && (get_type() != type::Unknown)) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + x = *reinterpret_cast(ptr); + y = *reinterpret_cast(ptr + sizeof(int32_t)); + z = *reinterpret_cast(ptr + sizeof(int32_t) * 2); + w = *reinterpret_cast(ptr + sizeof(int32_t) * 3); + bfree(ptr); + } else { + x, y, z, w = 0; + } +} + void gs::effect_parameter::set_int_array(int32_t v[], size_t sz) { if ((get_type() != type::Integer) && (get_type() != type::Integer2) && (get_type() != type::Integer3) @@ -315,13 +603,75 @@ void gs::effect_parameter::set_int_array(int32_t v[], size_t sz) gs_effect_set_val(_param, v, sizeof(int) * sz); } -void gs::effect_parameter::set_matrix(matrix4& v) +void gs::effect_parameter::set_matrix(matrix4 const& v) { if (get_type() != type::Matrix) throw std::bad_cast(); gs_effect_set_matrix4(_param, &v); } +void gs::effect_parameter::get_matrix(matrix4& v) +{ + if (get_type() != type::Matrix) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + v.x.x = *reinterpret_cast(ptr + sizeof(float_t) * 0); + v.x.y = *reinterpret_cast(ptr + sizeof(float_t) * 1); + v.x.z = *reinterpret_cast(ptr + sizeof(float_t) * 2); + v.x.w = *reinterpret_cast(ptr + sizeof(float_t) * 3); + v.y.x = *reinterpret_cast(ptr + sizeof(float_t) * 4); + v.y.y = *reinterpret_cast(ptr + sizeof(float_t) * 5); + v.y.z = *reinterpret_cast(ptr + sizeof(float_t) * 6); + v.y.w = *reinterpret_cast(ptr + sizeof(float_t) * 7); + v.z.x = *reinterpret_cast(ptr + sizeof(float_t) * 8); + v.z.y = *reinterpret_cast(ptr + sizeof(float_t) * 9); + v.z.z = *reinterpret_cast(ptr + sizeof(float_t) * 10); + v.z.w = *reinterpret_cast(ptr + sizeof(float_t) * 11); + v.t.x = *reinterpret_cast(ptr + sizeof(float_t) * 12); + v.t.y = *reinterpret_cast(ptr + sizeof(float_t) * 13); + v.t.z = *reinterpret_cast(ptr + sizeof(float_t) * 14); + v.t.w = *reinterpret_cast(ptr + sizeof(float_t) * 15); + bfree(ptr); + } else { + v.x = vec4{}; + v.y = vec4{}; + v.z = vec4{}; + v.t = vec4{}; + } +} + +void gs::effect_parameter::get_default_matrix(matrix4& v) +{ + if (get_type() != type::Matrix) + throw std::bad_cast(); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + v.x.x = *reinterpret_cast(ptr + sizeof(float_t) * 0); + v.x.y = *reinterpret_cast(ptr + sizeof(float_t) * 1); + v.x.z = *reinterpret_cast(ptr + sizeof(float_t) * 2); + v.x.w = *reinterpret_cast(ptr + sizeof(float_t) * 3); + v.y.x = *reinterpret_cast(ptr + sizeof(float_t) * 4); + v.y.y = *reinterpret_cast(ptr + sizeof(float_t) * 5); + v.y.z = *reinterpret_cast(ptr + sizeof(float_t) * 6); + v.y.w = *reinterpret_cast(ptr + sizeof(float_t) * 7); + v.z.x = *reinterpret_cast(ptr + sizeof(float_t) * 8); + v.z.y = *reinterpret_cast(ptr + sizeof(float_t) * 9); + v.z.z = *reinterpret_cast(ptr + sizeof(float_t) * 10); + v.z.w = *reinterpret_cast(ptr + sizeof(float_t) * 11); + v.t.x = *reinterpret_cast(ptr + sizeof(float_t) * 12); + v.t.y = *reinterpret_cast(ptr + sizeof(float_t) * 13); + v.t.z = *reinterpret_cast(ptr + sizeof(float_t) * 14); + v.t.w = *reinterpret_cast(ptr + sizeof(float_t) * 15); + bfree(ptr); + } else { + v.x = vec4{}; + v.y = vec4{}; + v.z = vec4{}; + v.t = vec4{}; + } +} + void gs::effect_parameter::set_texture(std::shared_ptr v) { if (get_type() != type::Texture) @@ -349,3 +699,77 @@ void gs::effect_parameter::set_sampler(gs_sampler_state* v) throw std::bad_cast(); gs_effect_set_next_sampler(_param, v); } + +void gs::effect_parameter::set_string(std::string const& v) +{ + if (get_type() != type::String) + throw std::bad_cast(); + gs_effect_set_val(_param, v.c_str(), v.length()); +} + +void gs::effect_parameter::get_string(std::string& v) +{ + if (get_type() != type::Matrix) + throw std::bad_cast(); + size_t ptr_len = gs_effect_get_val_size(_param); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + if (ptr) { + v = std::string(ptr, ptr + ptr_len); + bfree(ptr); + } else { + v = ""; + } +} + +void gs::effect_parameter::get_default_string(std::string& v) +{ + if (get_type() != type::Matrix) + throw std::bad_cast(); + size_t ptr_len = gs_effect_get_val_size(_param); + uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); + if (ptr) { + v = std::string(ptr, ptr + ptr_len); + bfree(ptr); + } else { + v = ""; + } +} + +size_t gs::effect_parameter::count_annotations() +{ + return gs_param_get_num_annotations(_param); +} + +gs::effect_parameter gs::effect_parameter::get_annotation(size_t idx) +{ + gs_eparam_t* param = gs_param_get_annotation_by_idx(_param, idx); + if (!param) + throw std::invalid_argument("annotation with index not found"); + return effect_parameter(param); +} + +gs::effect_parameter gs::effect_parameter::get_annotation(std::string name) +{ + gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str()); + if (!param) + throw std::invalid_argument("annotation with name not found"); + return effect_parameter(param); +} + +bool gs::effect_parameter::has_annotation(std::string name) +{ + gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str()); + if (!param) + return false; + return true; +} + +bool gs::effect_parameter::has_annotation(std::string name, effect_parameter::type type) +{ + try { + auto eprm = get_annotation(name); + return eprm.get_type() == type; + } catch (...) { + return false; + } +} diff --git a/source/obs/gs/gs-effect.hpp b/source/obs/gs/gs-effect.hpp index 633b796a..f4fe9421 100644 --- a/source/obs/gs/gs-effect.hpp +++ b/source/obs/gs/gs-effect.hpp @@ -68,25 +68,75 @@ namespace gs { type get_type(); void set_bool(bool v); + void get_bool(bool& v); + void get_default_bool(bool& v); + void set_bool_array(bool v[], size_t sz); + void set_float(float_t x); - void set_float2(vec2& v); + void get_float(float_t& x); + void get_default_float(float_t& x); + + void set_float2(vec2 const& v); + void get_float2(vec2& v); + void get_default_float2(vec2& v); void set_float2(float_t x, float_t y); - void set_float3(vec3& v); + void get_float2(float_t& x, float_t& y); + void get_default_float2(float_t& x, float_t& y); + + void set_float3(vec3 const& v); + void get_float3(vec3& v); + void get_default_float3(vec3& v); void set_float3(float_t x, float_t y, float_t z); - void set_float4(vec4& v); + void get_float3(float_t& x, float_t& y, float_t& z); + void get_default_float3(float_t& x, float_t& y, float_t& z); + + void set_float4(vec4 const& v); + void get_float4(vec4& v); + void get_default_float4(vec4& v); void set_float4(float_t x, float_t y, float_t z, float_t w); + void get_float4(float_t& x, float_t& y, float_t& z, float_t& w); + void get_default_float4(float_t& x, float_t& y, float_t& z, float_t& w); + void set_float_array(float_t v[], size_t sz); + void set_int(int32_t x); + void get_int(int32_t& x); + void get_default_int(int32_t& x); + void set_int2(int32_t x, int32_t y); + void get_int2(int32_t& x, int32_t& y); + void get_default_int2(int32_t& x, int32_t& y); + void set_int3(int32_t x, int32_t y, int32_t z); + void get_int3(int32_t& x, int32_t& y, int32_t& z); + void get_default_int3(int32_t& x, int32_t& y, int32_t& z); + void set_int4(int32_t x, int32_t y, int32_t z, int32_t w); + void get_int4(int32_t& x, int32_t& y, int32_t& z, int32_t& w); + void get_default_int4(int32_t& x, int32_t& y, int32_t& z, int32_t& w); + void set_int_array(int32_t v[], size_t sz); - void set_matrix(matrix4& v); + + void set_matrix(matrix4 const& v); + void get_matrix(matrix4& v); + void get_default_matrix(matrix4& v); + void set_texture(std::shared_ptr v); void set_texture(gs_texture_t* v); + void set_sampler(std::shared_ptr v); void set_sampler(gs_sampler_state* v); + + void set_string(std::string const& v); + void get_string(std::string& v); + void get_default_string(std::string& v); + + size_t count_annotations(); + effect_parameter get_annotation(size_t idx); + effect_parameter get_annotation(std::string name); + bool has_annotation(std::string name); + bool has_annotation(std::string name, effect_parameter::type type); }; class effect { @@ -107,6 +157,5 @@ namespace gs { effect_parameter get_parameter(std::string name); bool has_parameter(std::string name); bool has_parameter(std::string name, effect_parameter::type type); - }; } // namespace gs