From 11a2329519fad79ef802451ca4ddf1ac86fb447d Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sun, 15 Dec 2019 11:13:47 +0100 Subject: [PATCH] gs-effect: Refactor onto std::shared_ptr --- source/obs/gs/gs-effect.cpp | 774 ++++-------------------------------- source/obs/gs/gs-effect.hpp | 268 ++----------- 2 files changed, 100 insertions(+), 942 deletions(-) diff --git a/source/obs/gs/gs-effect.cpp b/source/obs/gs/gs-effect.cpp index 4f0ef1cc..6cd9dcd3 100644 --- a/source/obs/gs/gs-effect.cpp +++ b/source/obs/gs/gs-effect.cpp @@ -19,7 +19,6 @@ #include "gs-effect.hpp" #include -#include #include #include #include "obs/gs/gs-helper.hpp" @@ -29,120 +28,118 @@ #pragma warning(push) #pragma warning(disable : 4201) #endif +#include #include #ifdef _MSC_VER #pragma warning(pop) #endif //#define OBS_LOAD_EFFECT_FILE +#define MAX_EFFECT_SIZE 32 * 1024 * 1024; -gs::effect::effect(std::string file) +static std::string load_file_as_code(std::filesystem::path file) { -#ifdef OBS_LOAD_EFFECT_FILE - char* errorMessage = nullptr; - auto gctx = gs::context(); - m_effect = gs_effect_create_from_file(file.c_str(), &errorMessage); - if (!m_effect || errorMessage) { - std::string error = "Generic Error"; - if (errorMessage) { - error = std::string(errorMessage); - bfree((void*)errorMessage); - } - throw std::runtime_error(error); - } -#else - std::ifstream filestream = std::ifstream(file, std::ios::binary); - if (!filestream.is_open()) { - throw std::runtime_error("Failed to open file."); + uintmax_t size = std::filesystem::file_size(file); + if (size > MAX_EFFECT_SIZE) { + throw std::runtime_error("File is too large to be loaded."); } - filestream.ignore(std::numeric_limits::max()); - std::streamsize length = filestream.gcount(); - filestream.clear(); // Since ignore will have set eof. - filestream.seekg(0, std::ios_base::beg); - - if (length > 256 * 1024 * 1024) { - throw std::runtime_error("Shader too large (>256mb)"); + std::ifstream ifs(file, std::ios::binary); + if (!ifs.is_open() || ifs.bad()) { + throw std::runtime_error("An unknown error occured trying to open the file."); } - std::vector shader_buf(size_t(length + 1), 0); - filestream.read(shader_buf.data(), length); + std::vector buf(size_t(size + 1), 0); + ifs.read(buf.data(), size); - char* errorMessage = nullptr; - auto gctx = gs::context(); - _effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage); - if (!_effect || errorMessage) { - std::string error = "Generic Error"; - if (errorMessage) { - error = std::string(errorMessage); - bfree((void*)errorMessage); - } - throw std::runtime_error(error); - } -#endif + return std::string(buf.data(), buf.data() + size); } gs::effect::effect(std::string code, std::string name) { - char* errorMessage = nullptr; - auto gctx = gs::context(); - _effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage); - if (!_effect || errorMessage) { - std::string error = "Generic Error"; - if (errorMessage) { - error = std::string(errorMessage); - bfree((void*)errorMessage); - } - throw std::runtime_error(error); + auto gctx = gs::context(); + + char* error_buffer = nullptr; + gs_effect_t* effect = gs_effect_create(code.c_str(), name.c_str(), &error_buffer); + + if (!effect) { + throw error_buffer ? std::runtime_error(error_buffer) + : std::runtime_error("Unknown error during effect compile."); } + + reset(effect); } +gs::effect::effect(std::filesystem::path file) : effect(load_file_as_code(file), file.string()) {} + gs::effect::~effect() { auto gctx = gs::context(); - gs_effect_destroy(_effect); + gs_effect_destroy(get()); } -gs_effect_t* gs::effect::get_object() +size_t gs::effect::count_techniques() { - return _effect; + return static_cast(get()->techniques.num); +} + +gs::effect_technique gs::effect::get_technique(size_t idx) +{ + if (idx >= count_techniques()) { + return nullptr; + } + + return gs::effect_technique(get()->techniques.array + idx, this); +} + +gs::effect_technique gs::effect::get_technique(std::string name) +{ + for (size_t idx = 0; idx < count_techniques(); idx++) { + auto ptr = get()->techniques.array + idx; + if (strcmp(ptr->name, name.c_str()) == 0) { + return gs::effect_technique(ptr, this); + } + } + + return nullptr; +} + +bool gs::effect::has_technique(std::string name) +{ + if (get_technique(name)) + return true; + return false; } size_t gs::effect::count_parameters() { - return (size_t)gs_effect_get_num_params(_effect); + return get()->params.num; } -std::list> gs::effect::get_parameters() +gs::effect_parameter gs::effect::get_parameter(size_t idx) { - size_t num = gs_effect_get_num_params(_effect); - std::list> ps; - for (size_t idx = 0; idx < num; idx++) { - ps.emplace_back(get_parameter(idx)); + if (idx >= count_parameters()) { + throw std::out_of_range("Index is out of range."); } - return ps; + + return gs::effect_parameter(get()->params.array + idx, this); } -std::shared_ptr gs::effect::get_parameter(size_t idx) +gs::effect_parameter gs::effect::get_parameter(std::string name) { - gs_eparam_t* param = gs_effect_get_param_by_idx(_effect, idx); - if (!param) - return nullptr; - return std::make_shared(this->shared_from_this(), param); -} + for (size_t idx = 0; idx < count_techniques(); idx++) { + auto ptr = get()->params.array + idx; + if (strcmp(ptr->name, name.c_str()) == 0) { + return gs::effect_parameter(ptr, this); + } + } -std::shared_ptr gs::effect::get_parameter(std::string name) -{ - gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str()); - if (!param) - return nullptr; - return std::make_shared(this->shared_from_this(), param); + return nullptr; } bool gs::effect::has_parameter(std::string name) { - auto eprm = get_parameter(name); - if (eprm) + if (get_parameter(name)) return true; return false; } @@ -151,635 +148,6 @@ bool gs::effect::has_parameter(std::string name, effect_parameter::type type) { auto eprm = get_parameter(name); if (eprm) - return eprm->get_type() == type; - return false; -} - -std::shared_ptr gs::effect::create(std::string file) -{ - return std::shared_ptr(new gs::effect(file)); -} - -std::shared_ptr gs::effect::create(std::string code, std::string name) -{ - return std::shared_ptr(new gs::effect(code, name)); -} - -gs::effect_parameter::effect_parameter(std::shared_ptr effect, gs_eparam_t* param) - : _effect(effect), _param(param) -{ - if (!effect) - throw std::invalid_argument("effect"); - if (!param) - throw std::invalid_argument("param"); - - gs_effect_get_param_info(_param, &_param_info); -} - -std::string gs::effect_parameter::get_name() -{ - return _param_info.name; -} - -gs::effect_parameter::type gs::effect_parameter::get_type() -{ - switch (_param_info.type) { - case GS_SHADER_PARAM_BOOL: - return type::Boolean; - case GS_SHADER_PARAM_FLOAT: - return type::Float; - case GS_SHADER_PARAM_VEC2: - return type::Float2; - case GS_SHADER_PARAM_VEC3: - return type::Float3; - case GS_SHADER_PARAM_VEC4: - return type::Float4; - case GS_SHADER_PARAM_INT: - return type::Integer; - case GS_SHADER_PARAM_INT2: - return type::Integer2; - case GS_SHADER_PARAM_INT3: - return type::Integer3; - case GS_SHADER_PARAM_INT4: - return type::Integer4; - case GS_SHADER_PARAM_MATRIX4X4: - return type::Matrix; - case GS_SHADER_PARAM_TEXTURE: - return type::Texture; - case GS_SHADER_PARAM_STRING: - return type::String; - default: - case GS_SHADER_PARAM_UNKNOWN: - return type::Unknown; - } -} - -void gs::effect_parameter::set_bool(bool v) -{ - if (get_type() != type::Boolean) - throw std::bad_cast(); - 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) - throw std::bad_cast(); - gs_effect_set_val(_param, v, sz); -} - -void gs::effect_parameter::set_float(float_t x) -{ - if (get_type() != type::Float) - throw std::bad_cast(); - gs_effect_set_float(_param, x); -} - -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) -{ - vec2 data; - data.x = x; - data.y = y; - set_float2(data); -} - -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) - throw std::bad_cast(); - vec3 v = {{x, y, z, 0}}; - gs_effect_set_vec3(_param, &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) - throw std::bad_cast(); - vec4 v = {{x, y, z, 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) - && (get_type() != type::Float4)) - throw std::bad_cast(); - gs_effect_set_val(_param, v, sizeof(float_t) * sz); -} - -void gs::effect_parameter::set_int(int32_t x) -{ - if ((get_type() != type::Integer) && (get_type() != type::Unknown)) - throw std::bad_cast(); - 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)) - throw std::bad_cast(); - int32_t v[2] = {x, 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)) - throw std::bad_cast(); - int32_t v[3] = {x, y, 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)) - throw std::bad_cast(); - int32_t v[4] = {x, y, z, 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) - && (get_type() != type::Integer4) && (get_type() != type::Unknown)) - throw std::bad_cast(); - gs_effect_set_val(_param, v, sizeof(int) * sz); -} - -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) - throw std::bad_cast(); - gs_effect_set_texture(_param, v->get_object()); -} - -void gs::effect_parameter::set_texture(gs_texture_t* v) -{ - if (get_type() != type::Texture) - throw std::bad_cast(); - gs_effect_set_texture(_param, v); -} - -void gs::effect_parameter::set_sampler(std::shared_ptr v) -{ - if (get_type() != type::Texture) - throw std::bad_cast(); - gs_effect_set_next_sampler(_param, v->get_object()); -} - -void gs::effect_parameter::set_sampler(gs_sampler_state* v) -{ - if (get_type() != type::Texture) - 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::String) - 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 - 1); - bfree(ptr); - } else { - v = ""; - } -} - -void gs::effect_parameter::get_default_string(std::string& v) -{ - if (get_type() != type::String) - throw std::bad_cast(); - size_t ptr_len = gs_effect_get_default_val_size(_param); - uint8_t* ptr = static_cast(gs_effect_get_default_val(_param)); - if (ptr) { - v = std::string(ptr, ptr + ptr_len - 1); - bfree(ptr); - } else { - v = ""; - } -} - -size_t gs::effect_parameter::count_annotations() -{ - return gs_param_get_num_annotations(_param); -} - -std::shared_ptr gs::effect_parameter::get_annotation(size_t idx) -{ - gs_eparam_t* param = gs_param_get_annotation_by_idx(_param, idx); - if (!param) - return nullptr; - return std::make_shared(_effect, param); -} - -std::shared_ptr gs::effect_parameter::get_annotation(std::string name) -{ - gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str()); - if (!param) - return nullptr; - return std::make_shared(_effect, param); -} - -bool gs::effect_parameter::has_annotation(std::string name) -{ - auto eprm = get_annotation(name); - if (eprm) - return true; - return false; -} - -bool gs::effect_parameter::has_annotation(std::string name, effect_parameter::type type) -{ - auto eprm = get_annotation(name); - if (eprm) - return eprm->get_type() == type; + return eprm.get_type() == type; return false; } diff --git a/source/obs/gs/gs-effect.hpp b/source/obs/gs/gs-effect.hpp index 3d5c1a3a..67c766c0 100644 --- a/source/obs/gs/gs-effect.hpp +++ b/source/obs/gs/gs-effect.hpp @@ -19,254 +19,44 @@ #pragma once #include +#include #include #include #include -#include "gs-sampler.hpp" -#include "gs-texture.hpp" - -// OBS -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4201) -#endif -#include -#include -#include -#include -#include -#ifdef _MSC_VER -#pragma warning(pop) -#endif +#include "gs-effect-parameter.hpp" +#include "gs-effect-technique.hpp" namespace gs { - class effect; - - class effect_parameter { - std::shared_ptr<::gs::effect> _effect; - gs_eparam_t* _param; - gs_effect_param_info _param_info; - + class effect : private std::shared_ptr { public: - enum class type : uint8_t { - Unknown, - Boolean, - Float, - Float2, - Float3, - Float4, - Integer, - Integer2, - Integer3, - Integer4, - Matrix, - String, - Texture, - }; - - public: - effect_parameter(std::shared_ptr effect, gs_eparam_t* param); - - std::string get_name(); - 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 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 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 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 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(); - std::shared_ptr get_annotation(size_t idx); - std::shared_ptr get_annotation(std::string name); - bool has_annotation(std::string name); - bool has_annotation(std::string name, effect_parameter::type type); - - public /* Helpers */: - inline float_t get_bool() - { - bool v; - get_bool(v); - return v; - }; - inline bool get_default_bool() - { - bool v; - get_default_bool(v); - return v; - }; - - inline float_t get_float() - { - float_t v; - get_float(v); - return v; - }; - inline float_t get_default_float() - { - float_t v; - get_default_float(v); - return v; - }; - - inline vec2 get_float2() - { - vec2 v; - get_float2(v); - return v; - }; - inline vec2 get_default_float2() - { - vec2 v; - get_default_float2(v); - return v; - }; - - inline vec3 get_float3() - { - vec3 v; - get_float3(v); - return v; - }; - inline vec3 get_default_float3() - { - vec3 v; - get_default_float3(v); - return v; - }; - - inline vec4 get_float4() - { - vec4 v; - get_float4(v); - return v; - }; - inline vec4 get_default_float4() - { - vec4 v; - get_default_float4(v); - return v; - }; - - inline int32_t get_int() - { - int32_t v; - get_int(v); - return v; - }; - inline int32_t get_default_int() - { - int32_t v; - get_default_int(v); - return v; - }; - - inline matrix4 get_matrix() - { - matrix4 v; - get_matrix(v); - return v; - }; - inline matrix4 get_default_matrix() - { - matrix4 v; - get_default_matrix(v); - return v; - }; - - inline std::string get_string() - { - std::string v; - get_string(v); - return v; - }; - inline std::string get_default_string() - { - std::string v; - get_default_string(v); - return v; - }; - }; - - class effect : public std::enable_shared_from_this<::gs::effect> { - protected: - gs_effect_t* _effect; - - public: - effect(std::string file); effect(std::string code, std::string name); - virtual ~effect(); + effect(std::filesystem::path file); + ~effect(); - gs_effect_t* get_object(); + size_t count_techniques(); + gs::effect_technique get_technique(size_t idx); + gs::effect_technique get_technique(std::string name); + bool has_technique(std::string name); - size_t count_parameters(); - std::list> get_parameters(); - std::shared_ptr get_parameter(size_t idx); - std::shared_ptr get_parameter(std::string name); - bool has_parameter(std::string name); - bool has_parameter(std::string name, effect_parameter::type type); + size_t count_parameters(); + gs::effect_parameter get_parameter(size_t idx); + gs::effect_parameter get_parameter(std::string name); + bool has_parameter(std::string name); + bool has_parameter(std::string name, effect_parameter::type type); - public: - static std::shared_ptr create(std::string file); - static std::shared_ptr create(std::string code, std::string name); + public /* Legacy Support */: + inline gs_effect_t* get_object() + { + return get(); + } + + static gs::effect create(std::string file) + { + return gs::effect(file); + }; + static gs::effect create(std::string code, std::string name) + { + return gs::effect(code, name); + }; }; } // namespace gs