mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-10 22:05:06 +00:00
gfx-effect-source: Further work on rewrite
This partially implements most behavior to an acceptable degree for use right now.
This commit is contained in:
parent
845a2cbb21
commit
bde4e278bf
2 changed files with 901 additions and 121 deletions
|
@ -20,142 +20,688 @@
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
#include "strings.hpp"
|
#include "strings.hpp"
|
||||||
|
|
||||||
#define ST "Shader"
|
#define ST "Shader"
|
||||||
#define ST_FILE "Shader.File"
|
#define ST_FILE ST ".File"
|
||||||
|
#define ST_TECHNIQUE ST ".Technique"
|
||||||
|
|
||||||
gfx::effect_source::parameter::parameter(std::shared_ptr<gs::effect> effect, std::string name)
|
static std::vector<std::string> static_parameters{
|
||||||
: effect(effect), name(name), description(""), formulae(""), visible(true)
|
"ViewProj",
|
||||||
|
"Time",
|
||||||
|
"Random",
|
||||||
|
};
|
||||||
|
|
||||||
|
gfx::effect_source::parameter::parameter(std::shared_ptr<gs::effect> effect,
|
||||||
|
std::shared_ptr<gs::effect_parameter> param)
|
||||||
|
: _effect(effect), _param(param), _description(""), _formulae(""), _visible(true)
|
||||||
{
|
{
|
||||||
if (!effect)
|
if (!effect)
|
||||||
throw std::invalid_argument("effect");
|
throw std::invalid_argument("effect");
|
||||||
if (!effect->has_parameter(name))
|
if (!effect)
|
||||||
throw std::invalid_argument("name");
|
throw std::invalid_argument("param");
|
||||||
param = effect->get_parameter(name);
|
if (!effect->has_parameter(param->get_name(), param->get_type()))
|
||||||
|
throw std::invalid_argument("param");
|
||||||
|
_name = _param->get_name();
|
||||||
|
|
||||||
|
_visible_name = _name;
|
||||||
|
if (param->has_annotation("name", gs::effect_parameter::type::String)) {
|
||||||
|
param->get_annotation("name")->get_default_string(_visible_name);
|
||||||
|
}
|
||||||
if (param->has_annotation("description", gs::effect_parameter::type::String)) {
|
if (param->has_annotation("description", gs::effect_parameter::type::String)) {
|
||||||
param->get_annotation("description")->get_default_string(description);
|
param->get_annotation("description")->get_default_string(_description);
|
||||||
}
|
}
|
||||||
if (param->has_annotation("formulae", gs::effect_parameter::type::String)) {
|
if (param->has_annotation("formulae", gs::effect_parameter::type::String)) {
|
||||||
param->get_annotation("formulae")->get_default_string(formulae);
|
param->get_annotation("formulae")->get_default_string(_formulae);
|
||||||
}
|
}
|
||||||
if (param->has_annotation("visible", gs::effect_parameter::type::Boolean)) {
|
if (param->has_annotation("visible", gs::effect_parameter::type::Boolean)) {
|
||||||
param->get_annotation("visible")->get_default_bool(visible);
|
param->get_annotation("visible")->get_default_bool(_visible);
|
||||||
} else {
|
} else {
|
||||||
visible = true;
|
_visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::effect_source::bool_parameter::bool_parameter(std::shared_ptr<gs::effect> effect, std::string name)
|
gfx::effect_source::parameter::~parameter() {}
|
||||||
: parameter(effect, name)
|
|
||||||
|
void gfx::effect_source::parameter::properties(obs_properties_t* props) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::parameter::remove_properties(obs_properties_t* props) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::parameter::update(obs_data_t* data) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::parameter::tick(float_t time) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::parameter::prepare() {}
|
||||||
|
|
||||||
|
void gfx::effect_source::parameter::assign() {}
|
||||||
|
|
||||||
|
std::shared_ptr<gs::effect_parameter> gfx::effect_source::parameter::get_param()
|
||||||
|
{
|
||||||
|
return _param;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<gfx::effect_source::parameter>
|
||||||
|
gfx::effect_source::parameter::create(std::shared_ptr<gs::effect> effect,
|
||||||
|
std::shared_ptr<gs::effect_parameter> param)
|
||||||
|
{
|
||||||
|
if (!effect)
|
||||||
|
throw std::invalid_argument("effect");
|
||||||
|
if (!effect)
|
||||||
|
throw std::invalid_argument("param");
|
||||||
|
if (!effect->has_parameter(param->get_name(), param->get_type()))
|
||||||
|
throw std::invalid_argument("param");
|
||||||
|
|
||||||
|
switch (param->get_type()) {
|
||||||
|
case gs::effect_parameter::type::Boolean:
|
||||||
|
return std::make_shared<gfx::effect_source::bool_parameter>(effect, param);
|
||||||
|
case gs::effect_parameter::type::Float:
|
||||||
|
case gs::effect_parameter::type::Float2:
|
||||||
|
case gs::effect_parameter::type::Float3:
|
||||||
|
case gs::effect_parameter::type::Float4:
|
||||||
|
case gs::effect_parameter::type::Integer:
|
||||||
|
case gs::effect_parameter::type::Integer2:
|
||||||
|
case gs::effect_parameter::type::Integer3:
|
||||||
|
case gs::effect_parameter::type::Integer4:
|
||||||
|
return std::make_shared<gfx::effect_source::value_parameter>(effect, param);
|
||||||
|
case gs::effect_parameter::type::Matrix:
|
||||||
|
return std::make_shared<gfx::effect_source::matrix_parameter>(effect, param);
|
||||||
|
case gs::effect_parameter::type::Texture:
|
||||||
|
return std::make_shared<gfx::effect_source::texture_parameter>(effect, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::effect_source::bool_parameter::bool_parameter(std::shared_ptr<gs::effect> effect,
|
||||||
|
std::shared_ptr<gs::effect_parameter> param)
|
||||||
|
: parameter(effect, param)
|
||||||
{
|
{
|
||||||
if (param->get_type() != gs::effect_parameter::type::Boolean)
|
if (param->get_type() != gs::effect_parameter::type::Boolean)
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
|
|
||||||
param->get_default_bool(value);
|
param->get_default_bool(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::effect_source::value_parameter::value_parameter(std::shared_ptr<gs::effect> effect, std::string name)
|
void gfx::effect_source::bool_parameter::properties(obs_properties_t* props)
|
||||||
: parameter(effect, name)
|
{
|
||||||
|
auto p = obs_properties_add_bool(props, _name.c_str(), _visible_name.c_str());
|
||||||
|
obs_property_set_long_description(p, _description.c_str());
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::bool_parameter::remove_properties(obs_properties_t* props)
|
||||||
|
{
|
||||||
|
obs_properties_remove_by_name(props, _name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::bool_parameter::update(obs_data_t* data)
|
||||||
|
{
|
||||||
|
_value = obs_data_get_bool(data, _name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::bool_parameter::tick(float_t time) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::bool_parameter::prepare() {}
|
||||||
|
|
||||||
|
void gfx::effect_source::bool_parameter::assign()
|
||||||
|
{
|
||||||
|
_param->set_bool(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::effect_source::value_parameter::value_parameter(std::shared_ptr<gs::effect> effect,
|
||||||
|
std::shared_ptr<gs::effect_parameter> param)
|
||||||
|
: parameter(effect, param)
|
||||||
{
|
{
|
||||||
std::shared_ptr<gs::effect_parameter> min = param->get_annotation("minimum");
|
std::shared_ptr<gs::effect_parameter> min = param->get_annotation("minimum");
|
||||||
std::shared_ptr<gs::effect_parameter> max = param->get_annotation("maximum");
|
std::shared_ptr<gs::effect_parameter> max = param->get_annotation("maximum");
|
||||||
|
std::shared_ptr<gs::effect_parameter> stp = param->get_annotation("step");
|
||||||
|
|
||||||
|
bool is_int = false;
|
||||||
|
|
||||||
switch (param->get_type()) {
|
switch (param->get_type()) {
|
||||||
case gs::effect_parameter::type::Float:
|
case gs::effect_parameter::type::Float:
|
||||||
param->get_default_float(value.f[0]);
|
param->get_default_float(_value.f[0]);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_float(minimum.f[0]);
|
min->get_default_float(_minimum.f[0]);
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_float(maximum.f[0]);
|
max->get_default_float(_maximum.f[0]);
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_float(_step.f[0]);
|
||||||
break;
|
break;
|
||||||
case gs::effect_parameter::type::Float2:
|
case gs::effect_parameter::type::Float2:
|
||||||
param->get_default_float2(value.f[0], value.f[1]);
|
param->get_default_float2(_value.f[0], _value.f[1]);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_float2(minimum.f[0], minimum.f[1]);
|
min->get_default_float2(_minimum.f[0], _minimum.f[1]);
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_float2(maximum.f[0], maximum.f[1]);
|
max->get_default_float2(_maximum.f[0], _maximum.f[1]);
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_float2(_step.f[0], _step.f[1]);
|
||||||
break;
|
break;
|
||||||
case gs::effect_parameter::type::Float3:
|
case gs::effect_parameter::type::Float3:
|
||||||
param->get_default_float3(value.f[0], value.f[1], value.f[2]);
|
param->get_default_float3(_value.f[0], _value.f[1], _value.f[2]);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_float3(minimum.f[0], minimum.f[1], minimum.f[2]);
|
min->get_default_float3(_minimum.f[0], _minimum.f[1], _minimum.f[2]);
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_float3(maximum.f[0], maximum.f[1], maximum.f[2]);
|
max->get_default_float3(_maximum.f[0], _maximum.f[1], _maximum.f[2]);
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_float3(_step.f[0], _step.f[1], _step.f[2]);
|
||||||
break;
|
break;
|
||||||
case gs::effect_parameter::type::Float4:
|
case gs::effect_parameter::type::Float4:
|
||||||
param->get_default_float4(value.f[0], value.f[1], value.f[2], value.f[3]);
|
param->get_default_float4(_value.f[0], _value.f[1], _value.f[2], _value.f[3]);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_float4(minimum.f[0], minimum.f[1], minimum.f[2], minimum.f[3]);
|
min->get_default_float4(_minimum.f[0], _minimum.f[1], _minimum.f[2], _minimum.f[3]);
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_float4(maximum.f[0], maximum.f[1], maximum.f[2], maximum.f[3]);
|
max->get_default_float4(_maximum.f[0], _maximum.f[1], _maximum.f[2], _maximum.f[3]);
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_float4(_step.f[0], _step.f[1], _step.f[2], _step.f[3]);
|
||||||
break;
|
break;
|
||||||
case gs::effect_parameter::type::Integer:
|
case gs::effect_parameter::type::Integer:
|
||||||
param->get_default_int(value.i[0]);
|
param->get_default_int(_value.i[0]);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_int(minimum.i[0]);
|
min->get_default_int(_minimum.i[0]);
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_int(maximum.i[0]);
|
max->get_default_int(_maximum.i[0]);
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_int(_step.i[0]);
|
||||||
|
is_int = true;
|
||||||
break;
|
break;
|
||||||
case gs::effect_parameter::type::Integer2:
|
case gs::effect_parameter::type::Integer2:
|
||||||
param->get_default_int2(value.i[0], value.i[1]);
|
param->get_default_int2(_value.i[0], _value.i[1]);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_int2(minimum.i[0], minimum.i[1]);
|
min->get_default_int2(_minimum.i[0], _minimum.i[1]);
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_int2(maximum.i[0], maximum.i[1]);
|
max->get_default_int2(_maximum.i[0], _maximum.i[1]);
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_int2(_step.i[0], _step.i[1]);
|
||||||
|
is_int = true;
|
||||||
break;
|
break;
|
||||||
case gs::effect_parameter::type::Integer3:
|
case gs::effect_parameter::type::Integer3:
|
||||||
param->get_default_int3(value.i[0], value.i[1], value.i[2]);
|
param->get_default_int3(_value.i[0], _value.i[1], _value.i[2]);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_int3(minimum.i[0], minimum.i[1], minimum.i[2]);
|
min->get_default_int3(_minimum.i[0], _minimum.i[1], _minimum.i[2]);
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_int3(maximum.i[0], maximum.i[1], maximum.i[2]);
|
max->get_default_int3(_maximum.i[0], _maximum.i[1], _maximum.i[2]);
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_int3(_step.i[0], _step.i[1], _step.i[2]);
|
||||||
|
is_int = true;
|
||||||
break;
|
break;
|
||||||
case gs::effect_parameter::type::Integer4:
|
case gs::effect_parameter::type::Integer4:
|
||||||
param->get_default_int4(value.i[0], value.i[1], value.i[2], value.i[3]);
|
param->get_default_int4(_value.i[0], _value.i[1], _value.i[2], _value.i[3]);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_int4(minimum.i[0], minimum.i[1], minimum.i[2], minimum.i[3]);
|
min->get_default_int4(_minimum.i[0], _minimum.i[1], _minimum.i[2], _minimum.i[3]);
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_int4(maximum.i[0], maximum.i[1], maximum.i[2], maximum.i[3]);
|
max->get_default_int4(_maximum.i[0], _maximum.i[1], _maximum.i[2], _maximum.i[3]);
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_int4(_step.i[0], _step.i[1], _step.i[2], _step.i[3]);
|
||||||
|
is_int = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!min) {
|
||||||
|
if (is_int) {
|
||||||
|
_minimum.i[0] = _minimum.i[1] = _minimum.i[2] = _minimum.i[3] = std::numeric_limits<int32_t>::min();
|
||||||
|
} else {
|
||||||
|
_minimum.f[0] = _minimum.f[1] = _minimum.f[2] = _minimum.f[3] = -167772.16f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!max) {
|
||||||
|
if (is_int) {
|
||||||
|
_maximum.i[0] = _maximum.i[1] = _maximum.i[2] = _maximum.i[3] = std::numeric_limits<int32_t>::max();
|
||||||
|
} else {
|
||||||
|
_maximum.f[0] = _maximum.f[1] = _maximum.f[2] = _maximum.f[3] = +167772.16f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!stp) {
|
||||||
|
if (is_int) {
|
||||||
|
_step.i[0] = _step.i[1] = _step.i[2] = _step.i[3] = 1;
|
||||||
|
} else {
|
||||||
|
_step.f[0] = _step.f[1] = _step.f[2] = _step.f[3] = 0.01f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<gs::effect_parameter> mode = param->get_annotation("mode");
|
||||||
|
if (mode && (mode->get_type() == gs::effect_parameter::type::String)) {
|
||||||
|
std::string mode_str = mode->get_default_string();
|
||||||
|
if (strcmpi(mode_str.c_str(), "slider")) {
|
||||||
|
_mode = value_mode::SLIDER;
|
||||||
|
} else {
|
||||||
|
_mode = value_mode::INPUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t idx = 0; idx < 4; idx++) {
|
||||||
|
std::stringstream name_sstr;
|
||||||
|
std::stringstream ui_sstr;
|
||||||
|
|
||||||
|
name_sstr << _name << '[' << idx << ']';
|
||||||
|
ui_sstr << _visible_name << '[' << idx << ']';
|
||||||
|
|
||||||
|
_cache.name[idx] = name_sstr.str();
|
||||||
|
_cache.visible_name[idx] = ui_sstr.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::effect_source::matrix_parameter::matrix_parameter(std::shared_ptr<gs::effect> effect, std::string name)
|
void gfx::effect_source::value_parameter::properties(obs_properties_t* props)
|
||||||
: parameter(effect, name)
|
{
|
||||||
|
auto grp = props;
|
||||||
|
if (!util::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
auto p = obs_properties_add_group(props, _name.c_str(), _visible_name.c_str(), OBS_GROUP_NORMAL, grp);
|
||||||
|
obs_property_set_long_description(p, _description.c_str());
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_int = false;
|
||||||
|
size_t limit = 0;
|
||||||
|
|
||||||
|
switch (_param->get_type()) {
|
||||||
|
case gs::effect_parameter::type::Integer:
|
||||||
|
is_int = true;
|
||||||
|
limit = 1;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer2:
|
||||||
|
is_int = true;
|
||||||
|
limit = 2;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer3:
|
||||||
|
is_int = true;
|
||||||
|
limit = 3;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer4:
|
||||||
|
is_int = true;
|
||||||
|
limit = 4;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float:
|
||||||
|
is_int = false;
|
||||||
|
limit = 1;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float2:
|
||||||
|
is_int = false;
|
||||||
|
limit = 2;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float3:
|
||||||
|
is_int = false;
|
||||||
|
limit = 3;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float4:
|
||||||
|
is_int = false;
|
||||||
|
limit = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t idx = 0; idx < limit; idx++) {
|
||||||
|
if (is_int) {
|
||||||
|
if (_mode == value_mode::INPUT) {
|
||||||
|
auto p = obs_properties_add_int(grp, _cache.name[idx].c_str(), _cache.visible_name[idx].c_str(),
|
||||||
|
_minimum.i[idx], _maximum.i[idx], _step.i[idx]);
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
} else {
|
||||||
|
auto p = obs_properties_add_int_slider(grp, _cache.name[idx].c_str(), _cache.visible_name[idx].c_str(),
|
||||||
|
_minimum.i[idx], _maximum.i[idx], _step.i[idx]);
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_mode == value_mode::INPUT) {
|
||||||
|
auto p = obs_properties_add_float(grp, _cache.name[idx].c_str(), _cache.visible_name[idx].c_str(),
|
||||||
|
_minimum.f[idx], _maximum.f[idx], _step.f[idx]);
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
} else {
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_float_slider(grp, _cache.name[idx].c_str(), _cache.visible_name[idx].c_str(),
|
||||||
|
_minimum.f[idx], _maximum.f[idx], _step.f[idx]);
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::value_parameter::remove_properties(obs_properties_t* props)
|
||||||
|
{
|
||||||
|
bool is_int = false;
|
||||||
|
size_t limit = 0;
|
||||||
|
|
||||||
|
switch (_param->get_type()) {
|
||||||
|
case gs::effect_parameter::type::Integer:
|
||||||
|
is_int = true;
|
||||||
|
limit = 1;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer2:
|
||||||
|
is_int = true;
|
||||||
|
limit = 2;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer3:
|
||||||
|
is_int = true;
|
||||||
|
limit = 3;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer4:
|
||||||
|
is_int = true;
|
||||||
|
limit = 4;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float:
|
||||||
|
is_int = false;
|
||||||
|
limit = 1;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float2:
|
||||||
|
is_int = false;
|
||||||
|
limit = 2;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float3:
|
||||||
|
is_int = false;
|
||||||
|
limit = 3;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float4:
|
||||||
|
is_int = false;
|
||||||
|
limit = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t idx = 0; idx < limit; idx++) {
|
||||||
|
obs_properties_remove_by_name(props, _cache.name[idx].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::value_parameter::update(obs_data_t* data)
|
||||||
|
{
|
||||||
|
bool is_int = false;
|
||||||
|
size_t limit = 0;
|
||||||
|
|
||||||
|
switch (_param->get_type()) {
|
||||||
|
case gs::effect_parameter::type::Integer:
|
||||||
|
is_int = true;
|
||||||
|
limit = 1;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer2:
|
||||||
|
is_int = true;
|
||||||
|
limit = 2;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer3:
|
||||||
|
is_int = true;
|
||||||
|
limit = 3;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer4:
|
||||||
|
is_int = true;
|
||||||
|
limit = 4;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float:
|
||||||
|
is_int = false;
|
||||||
|
limit = 1;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float2:
|
||||||
|
is_int = false;
|
||||||
|
limit = 2;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float3:
|
||||||
|
is_int = false;
|
||||||
|
limit = 3;
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float4:
|
||||||
|
is_int = false;
|
||||||
|
limit = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t idx = 0; idx < limit; idx++) {
|
||||||
|
if (is_int) {
|
||||||
|
_value.i[idx] = obs_data_get_int(data, _cache.name[idx].c_str());
|
||||||
|
} else {
|
||||||
|
_value.f[idx] = static_cast<float_t>(obs_data_get_double(data, _cache.name[idx].c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::value_parameter::tick(float_t time) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::value_parameter::prepare() {}
|
||||||
|
|
||||||
|
void gfx::effect_source::value_parameter::assign()
|
||||||
|
{
|
||||||
|
switch (_param->get_type()) {
|
||||||
|
case gs::effect_parameter::type::Integer:
|
||||||
|
_param->set_int(_value.i[0]);
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer2:
|
||||||
|
_param->set_int2(_value.i[0], _value.i[1]);
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer3:
|
||||||
|
_param->set_int3(_value.i[0], _value.i[1], _value.i[2]);
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Integer4:
|
||||||
|
_param->set_int4(_value.i[0], _value.i[1], _value.i[2], _value.i[3]);
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float:
|
||||||
|
_param->set_float(_value.f[0]);
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float2:
|
||||||
|
_param->set_float2(_value.f[0], _value.f[1]);
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float3:
|
||||||
|
_param->set_float3(_value.f[0], _value.f[1], _value.f[2]);
|
||||||
|
break;
|
||||||
|
case gs::effect_parameter::type::Float4:
|
||||||
|
_param->set_float4(_value.f[0], _value.f[1], _value.f[2], _value.f[3]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::effect_source::matrix_parameter::matrix_parameter(std::shared_ptr<gs::effect> effect,
|
||||||
|
std::shared_ptr<gs::effect_parameter> param)
|
||||||
|
: parameter(effect, param)
|
||||||
{
|
{
|
||||||
std::shared_ptr<gs::effect_parameter> min = param->get_annotation("minimum");
|
std::shared_ptr<gs::effect_parameter> min = param->get_annotation("minimum");
|
||||||
std::shared_ptr<gs::effect_parameter> max = param->get_annotation("maximum");
|
std::shared_ptr<gs::effect_parameter> max = param->get_annotation("maximum");
|
||||||
|
std::shared_ptr<gs::effect_parameter> stp = param->get_annotation("step");
|
||||||
|
|
||||||
param->get_default_matrix(value);
|
param->get_default_matrix(_value);
|
||||||
if (min)
|
if (min)
|
||||||
min->get_default_matrix(minimum);
|
min->get_default_matrix(_minimum);
|
||||||
|
else
|
||||||
|
_minimum = matrix4{vec4{-167772.16f, -167772.16f, -167772.16f, -167772.16f},
|
||||||
|
vec4{-167772.16f, -167772.16f, -167772.16f, -167772.16f},
|
||||||
|
vec4{-167772.16f, -167772.16f, -167772.16f, -167772.16f},
|
||||||
|
vec4{-167772.16f, -167772.16f, -167772.16f, -167772.16f}};
|
||||||
|
|
||||||
if (max)
|
if (max)
|
||||||
max->get_default_matrix(maximum);
|
max->get_default_matrix(_maximum);
|
||||||
|
else
|
||||||
|
_maximum = matrix4{vec4{-167772.16f, -167772.16f, -167772.16f, -167772.16f},
|
||||||
|
vec4{-167772.16f, -167772.16f, -167772.16f, -167772.16f},
|
||||||
|
vec4{-167772.16f, -167772.16f, -167772.16f, -167772.16f},
|
||||||
|
vec4{-167772.16f, -167772.16f, -167772.16f, -167772.16f}};
|
||||||
|
|
||||||
|
if (stp)
|
||||||
|
stp->get_default_matrix(_step);
|
||||||
|
else
|
||||||
|
_step = matrix4{vec4{0.01f, 0.01f, 0.01f, 0.01f}, vec4{0.01f, 0.01f, 0.01f, 0.01f},
|
||||||
|
vec4{0.01f, 0.01f, 0.01f, 0.01f}, vec4{0.01f, 0.01f, 0.01f, 0.01f}};
|
||||||
|
|
||||||
|
std::shared_ptr<gs::effect_parameter> mode = param->get_annotation("mode");
|
||||||
|
if (mode && (mode->get_type() == gs::effect_parameter::type::String)) {
|
||||||
|
std::string mode_str = mode->get_default_string();
|
||||||
|
if (strcmpi(mode_str.c_str(), "slider")) {
|
||||||
|
_mode = value_mode::SLIDER;
|
||||||
|
} else {
|
||||||
|
_mode = value_mode::INPUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t x = 0; x < 4; x++) {
|
||||||
|
for (size_t y = 0; y < 4; y++) {
|
||||||
|
std::stringstream name_sstr;
|
||||||
|
std::stringstream ui_sstr;
|
||||||
|
|
||||||
|
name_sstr << _name << '[' << x << ']' << '[' << y << ']';
|
||||||
|
ui_sstr << _visible_name << '[' << x << ']' << '[' << y << ']';
|
||||||
|
|
||||||
|
_cache.name[x * 4 + y] = name_sstr.str();
|
||||||
|
_cache.visible_name[x * 4 + y] = ui_sstr.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::effect_source::string_parameter::string_parameter(std::shared_ptr<gs::effect> effect, std::string name)
|
void gfx::effect_source::matrix_parameter::properties(obs_properties_t* props)
|
||||||
: parameter(effect, name)
|
|
||||||
{
|
{
|
||||||
param->get_default_string(value);
|
auto grp = props;
|
||||||
|
if (!util::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
auto p = obs_properties_add_group(props, _name.c_str(), _visible_name.c_str(), OBS_GROUP_NORMAL, grp);
|
||||||
|
obs_property_set_long_description(p, _description.c_str());
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t x = 0; x < 4; x++) {
|
||||||
|
vec4& min_ref = _minimum.x;
|
||||||
|
vec4& max_ref = _maximum.x;
|
||||||
|
vec4& stp_ref = _step.x;
|
||||||
|
if (x == 0) {
|
||||||
|
min_ref = _minimum.x;
|
||||||
|
max_ref = _maximum.x;
|
||||||
|
stp_ref = _step.x;
|
||||||
|
} else if (x == 1) {
|
||||||
|
min_ref = _minimum.y;
|
||||||
|
max_ref = _maximum.y;
|
||||||
|
stp_ref = _step.y;
|
||||||
|
} else if (x == 2) {
|
||||||
|
min_ref = _minimum.z;
|
||||||
|
max_ref = _maximum.z;
|
||||||
|
stp_ref = _step.z;
|
||||||
|
} else {
|
||||||
|
min_ref = _minimum.t;
|
||||||
|
max_ref = _maximum.t;
|
||||||
|
stp_ref = _step.t;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t y = 0; y < 4; y++) {
|
||||||
|
size_t idx = x * 4 + y;
|
||||||
|
|
||||||
|
if (_mode == value_mode::INPUT) {
|
||||||
|
auto p = obs_properties_add_float(grp, _cache.name[idx].c_str(), _cache.visible_name[idx].c_str(),
|
||||||
|
min_ref.ptr[y], max_ref.ptr[y], stp_ref.ptr[y]);
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
} else {
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_float_slider(grp, _cache.name[idx].c_str(), _cache.visible_name[idx].c_str(),
|
||||||
|
min_ref.ptr[y], max_ref.ptr[y], stp_ref.ptr[y]);
|
||||||
|
obs_property_set_visible(p, _visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::effect_source::texture_parameter::texture_parameter(std::shared_ptr<gs::effect> effect, std::string name)
|
void gfx::effect_source::matrix_parameter::remove_properties(obs_properties_t* props)
|
||||||
: parameter(effect, name)
|
{
|
||||||
|
for (size_t x = 0; x < 4; x++) {
|
||||||
|
for (size_t y = 0; y < 4; y++) {
|
||||||
|
size_t idx = x * 4 + y;
|
||||||
|
obs_properties_remove_by_name(props, _cache.name[idx].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::matrix_parameter::update(obs_data_t* data)
|
||||||
|
{
|
||||||
|
for (size_t x = 0; x < 4; x++) {
|
||||||
|
vec4& v_ref = _value.x;
|
||||||
|
if (x == 0) {
|
||||||
|
vec4& v_ref = _value.x;
|
||||||
|
} else if (x == 1) {
|
||||||
|
vec4& v_ref = _value.y;
|
||||||
|
} else if (x == 2) {
|
||||||
|
vec4& v_ref = _value.z;
|
||||||
|
} else {
|
||||||
|
vec4& v_ref = _value.t;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t y = 0; y < 4; y++) {
|
||||||
|
size_t idx = x * 4 + y;
|
||||||
|
v_ref.ptr[y] = obs_data_get_double(data, _cache.name[idx].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::matrix_parameter::tick(float_t time) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::matrix_parameter::prepare() {}
|
||||||
|
|
||||||
|
void gfx::effect_source::matrix_parameter::assign()
|
||||||
|
{
|
||||||
|
_param->set_matrix(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::effect_source::string_parameter::string_parameter(std::shared_ptr<gs::effect> effect,
|
||||||
|
std::shared_ptr<gs::effect_parameter> param)
|
||||||
|
: parameter(effect, param)
|
||||||
|
{
|
||||||
|
param->get_default_string(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::string_parameter::properties(obs_properties_t* props) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::string_parameter::remove_properties(obs_properties_t* props) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::string_parameter::update(obs_data_t* data) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::string_parameter::tick(float_t time) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::string_parameter::prepare() {}
|
||||||
|
|
||||||
|
void gfx::effect_source::string_parameter::assign() {}
|
||||||
|
|
||||||
|
gfx::effect_source::texture_parameter::texture_parameter(std::shared_ptr<gs::effect> effect,
|
||||||
|
std::shared_ptr<gs::effect_parameter> param)
|
||||||
|
: parameter(effect, param)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void gfx::effect_source::shader_instance::load_file(std::string file)
|
void gfx::effect_source::texture_parameter::properties(obs_properties_t* props) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::texture_parameter::remove_properties(obs_properties_t* props) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::texture_parameter::update(obs_data_t* data) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::texture_parameter::tick(float_t time) {}
|
||||||
|
|
||||||
|
void gfx::effect_source::texture_parameter::prepare() {}
|
||||||
|
|
||||||
|
void gfx::effect_source::texture_parameter::assign() {}
|
||||||
|
|
||||||
|
bool gfx::effect_source::effect_source::modified2(obs_properties_t* props, obs_property_t* property,
|
||||||
|
obs_data_t* settings)
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
for (auto& kv : _params) {
|
||||||
|
if (kv.second)
|
||||||
|
kv.second->remove_properties(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const char* str = obs_data_get_string(settings, ST_FILE);
|
||||||
|
load_file(str ? str : "");
|
||||||
|
} catch (std::exception& ex) {
|
||||||
|
P_LOG_ERROR("<gfx::effect_source> Failed to load effect \"%s\" due to error: %s", _file.c_str(), ex.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& kv : _params) {
|
||||||
|
if (kv.second)
|
||||||
|
kv.second->properties(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::effect_source::load_file(std::string file)
|
||||||
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
_params.clear();
|
_params.clear();
|
||||||
_effect.reset();
|
_effect.reset();
|
||||||
_file = file;
|
_file = file;
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (!os_stat(_file.c_str(), &st)) {
|
if (os_stat(_file.c_str(), &st) == -1) {
|
||||||
_last_size = 0;
|
_last_size = 0;
|
||||||
_last_modify_time = 0;
|
_last_modify_time = 0;
|
||||||
_last_create_time = 0;
|
_last_create_time = 0;
|
||||||
|
@ -172,46 +718,83 @@ void gfx::effect_source::shader_instance::load_file(std::string file)
|
||||||
param_ident_t identity;
|
param_ident_t identity;
|
||||||
identity.first = prm->get_type();
|
identity.first = prm->get_type();
|
||||||
identity.second = prm->get_name();
|
identity.second = prm->get_name();
|
||||||
std::shared_ptr<parameter> parameter;
|
|
||||||
|
|
||||||
switch (prm->get_type()) {
|
bool skip = false;
|
||||||
case gs::effect_parameter::type::Boolean:
|
for (auto v : static_parameters) {
|
||||||
parameter = std::make_shared<bool_parameter>(_effect, prm->get_name());
|
if (prm->get_name() == v) {
|
||||||
break;
|
skip = true;
|
||||||
case gs::effect_parameter::type::Float:
|
break;
|
||||||
case gs::effect_parameter::type::Float2:
|
}
|
||||||
case gs::effect_parameter::type::Float3:
|
|
||||||
case gs::effect_parameter::type::Float4:
|
|
||||||
case gs::effect_parameter::type::Integer:
|
|
||||||
case gs::effect_parameter::type::Integer2:
|
|
||||||
case gs::effect_parameter::type::Integer3:
|
|
||||||
case gs::effect_parameter::type::Integer4:
|
|
||||||
parameter = std::make_shared<value_parameter>(_effect, prm->get_name());
|
|
||||||
break;
|
|
||||||
case gs::effect_parameter::type::Matrix:
|
|
||||||
parameter = std::make_shared<matrix_parameter>(_effect, prm->get_name());
|
|
||||||
break;
|
|
||||||
case gs::effect_parameter::type::String:
|
|
||||||
parameter = std::make_shared<string_parameter>(_effect, prm->get_name());
|
|
||||||
break;
|
|
||||||
case gs::effect_parameter::type::Texture:
|
|
||||||
parameter = std::make_shared<texture_parameter>(_effect, prm->get_name());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (skip)
|
||||||
|
continue;
|
||||||
|
|
||||||
_params.emplace(identity, parameter);
|
_params.emplace(identity, parameter::create(_effect, prm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::effect_source::shader_instance::shader_instance(std::string file)
|
gfx::effect_source::effect_source::effect_source()
|
||||||
: _last_check(0), _last_size(0), _last_modify_time(0), _last_create_time(0)
|
: _last_check(0), _last_size(0), _last_modify_time(0), _last_create_time(0)
|
||||||
{
|
{
|
||||||
load_file(file);
|
auto gctx = gs::context();
|
||||||
|
|
||||||
|
_tri = std::make_shared<gs::vertex_buffer>(3ul, uint8_t(1));
|
||||||
|
{
|
||||||
|
auto& vtx = _tri->at(0);
|
||||||
|
vec3_set(vtx.position, 0, 0, 0);
|
||||||
|
vec4_set(vtx.uv[0], 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto& vtx = _tri->at(1);
|
||||||
|
vec3_set(vtx.position, 2, 0, 0);
|
||||||
|
vec4_set(vtx.uv[0], 2, 0, 0, 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto& vtx = _tri->at(2);
|
||||||
|
vec3_set(vtx.position, 0, 2, 0);
|
||||||
|
vec4_set(vtx.uv[0], 0, 2, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::effect_source::shader_instance::~shader_instance() {}
|
gfx::effect_source::effect_source::~effect_source() {}
|
||||||
|
|
||||||
void gfx::effect_source::shader_instance::tick(float_t time)
|
void gfx::effect_source::effect_source::properties(obs_properties_t* props)
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_path(props, ST_FILE, D_TRANSLATE(ST_FILE), OBS_PATH_FILE, "Effects (*.effect);;*.*",
|
||||||
|
nullptr);
|
||||||
|
/*obs_property_set_modified_callback2(p,
|
||||||
|
[](void* priv, obs_properties_t* props, obs_property_t* property, obs_data_t* settings) {
|
||||||
|
return reinterpret_cast<gfx::effect_source::effect_source*>(priv)->modified2(props, property, settings);
|
||||||
|
}, this);*/
|
||||||
|
obs_properties_add_text(props, ST_TECHNIQUE, D_TRANSLATE(ST_TECHNIQUE), OBS_TEXT_DEFAULT);
|
||||||
|
|
||||||
|
for (auto& kv : _params) {
|
||||||
|
if (kv.second)
|
||||||
|
kv.second->properties(props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::effect_source::update(obs_data_t* data)
|
||||||
|
{
|
||||||
|
const char* file = obs_data_get_string(data, ST_FILE);
|
||||||
|
if (file != _file) {
|
||||||
|
try {
|
||||||
|
load_file(file);
|
||||||
|
} catch (std::exception& ex) {
|
||||||
|
P_LOG_ERROR("<gfx::effect_source> Failed to load effect \"%s\" due to error: %s", _file.c_str(), ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* str = obs_data_get_string(data, ST_TECHNIQUE);
|
||||||
|
_tech = str ? str : "Draw";
|
||||||
|
|
||||||
|
for (auto& kv : _params) {
|
||||||
|
if (kv.second)
|
||||||
|
kv.second->update(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::effect_source::effect_source::tick(float_t time)
|
||||||
{
|
{
|
||||||
_last_check += time;
|
_last_check += time;
|
||||||
if (_last_check >= 0.5f) {
|
if (_last_check >= 0.5f) {
|
||||||
|
@ -219,18 +802,65 @@ void gfx::effect_source::shader_instance::tick(float_t time)
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (os_stat(_file.c_str(), &st)) {
|
if (os_stat(_file.c_str(), &st) != -1) {
|
||||||
changed =
|
changed =
|
||||||
(_last_size != st.st_size) || (_last_modify_time != st.st_mtime) || (_last_create_time != st.st_ctime);
|
(_last_size != st.st_size) || (_last_modify_time != st.st_mtime) || (_last_create_time != st.st_ctime);
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
load_file(_file);
|
try {
|
||||||
|
load_file(_file);
|
||||||
|
} catch (std::exception& ex) {
|
||||||
|
P_LOG_ERROR("Loading shader \"%s\" failed, error: %s", _file.c_str(), ex.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& kv : _params) {
|
||||||
|
if (kv.second)
|
||||||
|
kv.second->tick(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
_time += time;
|
||||||
|
_time_since_last_tick = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::effect_source::shader_instance::render(std::string technique)
|
void gfx::effect_source::effect_source::render()
|
||||||
{
|
{
|
||||||
|
if (!_effect)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto& kv : _params) {
|
||||||
|
if (kv.second)
|
||||||
|
kv.second->prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& kv : _params) {
|
||||||
|
if (kv.second)
|
||||||
|
kv.second->assign();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply "special" parameters.
|
||||||
|
_time_active += _time_since_last_tick;
|
||||||
|
{
|
||||||
|
auto p_time = _effect->get_parameter("Time");
|
||||||
|
if (p_time && (p_time->get_type() == gs::effect_parameter::type::Float4)) {
|
||||||
|
p_time->set_float4(_time, _time_active, _time_since_last_tick, _random_dist(_random_generator));
|
||||||
|
}
|
||||||
|
auto p_random = _effect->get_parameter("Random");
|
||||||
|
if (p_random && (p_random->get_type() == gs::effect_parameter::type::Matrix)) {
|
||||||
|
matrix4 m;
|
||||||
|
vec4_set(&m.x, _random_dist(_random_generator), _random_dist(_random_generator),
|
||||||
|
_random_dist(_random_generator), _random_dist(_random_generator));
|
||||||
|
vec4_set(&m.y, _random_dist(_random_generator), _random_dist(_random_generator),
|
||||||
|
_random_dist(_random_generator), _random_dist(_random_generator));
|
||||||
|
vec4_set(&m.z, _random_dist(_random_generator), _random_dist(_random_generator),
|
||||||
|
_random_dist(_random_generator), _random_dist(_random_generator));
|
||||||
|
vec4_set(&m.t, _random_dist(_random_generator), _random_dist(_random_generator),
|
||||||
|
_random_dist(_random_generator), _random_dist(_random_generator));
|
||||||
|
p_random->set_matrix(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_matrix_push();
|
gs_matrix_push();
|
||||||
|
|
||||||
|
@ -242,7 +872,10 @@ void gfx::effect_source::shader_instance::render(std::string technique)
|
||||||
gs_enable_stencil_write(false);
|
gs_enable_stencil_write(false);
|
||||||
gs_ortho(0, 1, 0, 1, -1., 1.);
|
gs_ortho(0, 1, 0, 1, -1., 1.);
|
||||||
|
|
||||||
while (gs_effect_loop(_effect->get_object(), technique.c_str())) {
|
while (gs_effect_loop(_effect->get_object(), _tech.c_str())) {
|
||||||
|
gs_load_vertexbuffer(_tri->update());
|
||||||
|
gs_load_indexbuffer(nullptr);
|
||||||
|
gs_draw(gs_draw_mode::GS_TRIS, 0, _tri->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_matrix_pop();
|
gs_matrix_pop();
|
||||||
|
|
|
@ -16,8 +16,10 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -43,61 +45,193 @@ extern "C" {
|
||||||
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
namespace effect_source {
|
namespace effect_source {
|
||||||
struct parameter {
|
enum class value_mode {
|
||||||
std::shared_ptr<gs::effect> effect;
|
INPUT,
|
||||||
std::shared_ptr<gs::effect_parameter> param;
|
SLIDER,
|
||||||
|
|
||||||
std::string name;
|
|
||||||
std::string description;
|
|
||||||
std::string formulae;
|
|
||||||
bool visible;
|
|
||||||
|
|
||||||
parameter(std::shared_ptr<gs::effect> effect, std::string name);
|
|
||||||
};
|
};
|
||||||
struct bool_parameter : parameter {
|
enum class string_mode {
|
||||||
bool value;
|
TEXT,
|
||||||
|
MULTILINE,
|
||||||
bool_parameter(std::shared_ptr<gs::effect> effect, std::string name);
|
PASSWORD,
|
||||||
};
|
};
|
||||||
struct value_parameter : parameter {
|
enum class texture_mode {
|
||||||
|
FILE,
|
||||||
|
SOURCE,
|
||||||
|
};
|
||||||
|
|
||||||
|
class parameter {
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<gs::effect> _effect;
|
||||||
|
std::shared_ptr<gs::effect_parameter> _param;
|
||||||
|
|
||||||
|
std::string _name;
|
||||||
|
std::string _visible_name;
|
||||||
|
std::string _description;
|
||||||
|
std::string _formulae;
|
||||||
|
bool _visible;
|
||||||
|
|
||||||
|
public:
|
||||||
|
parameter(std::shared_ptr<gs::effect> effect, std::shared_ptr<gs::effect_parameter> param);
|
||||||
|
virtual ~parameter();
|
||||||
|
|
||||||
|
virtual void properties(obs_properties_t* props) = 0;
|
||||||
|
|
||||||
|
virtual void remove_properties(obs_properties_t* props) = 0;
|
||||||
|
|
||||||
|
virtual void update(obs_data_t* data) = 0;
|
||||||
|
|
||||||
|
virtual void tick(float_t time) = 0;
|
||||||
|
|
||||||
|
virtual void prepare() = 0;
|
||||||
|
|
||||||
|
virtual void assign() = 0;
|
||||||
|
|
||||||
|
std::shared_ptr<gs::effect_parameter> get_param();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<gfx::effect_source::parameter> create(std::shared_ptr<gs::effect> effect,
|
||||||
|
std::shared_ptr<gs::effect_parameter> param);
|
||||||
|
};
|
||||||
|
|
||||||
|
class bool_parameter : public parameter {
|
||||||
|
bool _value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool_parameter(std::shared_ptr<gs::effect> effect, std::shared_ptr<gs::effect_parameter> param);
|
||||||
|
|
||||||
|
virtual void properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void remove_properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void update(obs_data_t* data) override;
|
||||||
|
|
||||||
|
virtual void tick(float_t time) override;
|
||||||
|
|
||||||
|
virtual void prepare() override;
|
||||||
|
|
||||||
|
virtual void assign() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class value_parameter : public parameter {
|
||||||
union {
|
union {
|
||||||
float_t f[16];
|
float_t f[4];
|
||||||
int32_t i[4];
|
int32_t i[4];
|
||||||
} value;
|
} _value;
|
||||||
union {
|
union {
|
||||||
float_t f[16];
|
float_t f[4];
|
||||||
int32_t i[4];
|
int32_t i[4];
|
||||||
} minimum;
|
} _minimum;
|
||||||
union {
|
union {
|
||||||
float_t f[16];
|
float_t f[4];
|
||||||
int32_t i[4];
|
int32_t i[4];
|
||||||
} maximum;
|
} _maximum;
|
||||||
|
union {
|
||||||
|
float_t f[4];
|
||||||
|
int32_t i[4];
|
||||||
|
} _step;
|
||||||
|
value_mode _mode = value_mode::INPUT;
|
||||||
|
|
||||||
value_parameter(std::shared_ptr<gs::effect> effect, std::string name);
|
struct {
|
||||||
|
std::string name[4];
|
||||||
|
std::string visible_name[4];
|
||||||
|
} _cache;
|
||||||
|
|
||||||
|
public:
|
||||||
|
value_parameter(std::shared_ptr<gs::effect> effect, std::shared_ptr<gs::effect_parameter> param);
|
||||||
|
|
||||||
|
virtual void properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void remove_properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void update(obs_data_t* data) override;
|
||||||
|
|
||||||
|
virtual void tick(float_t time) override;
|
||||||
|
|
||||||
|
virtual void prepare() override;
|
||||||
|
|
||||||
|
virtual void assign() override;
|
||||||
};
|
};
|
||||||
struct matrix_parameter : parameter {
|
|
||||||
matrix4 value;
|
|
||||||
matrix4 minimum;
|
|
||||||
matrix4 maximum;
|
|
||||||
|
|
||||||
matrix_parameter(std::shared_ptr<gs::effect> effect, std::string name);
|
class matrix_parameter : public parameter {
|
||||||
|
matrix4 _value;
|
||||||
|
matrix4 _minimum;
|
||||||
|
matrix4 _maximum;
|
||||||
|
matrix4 _step;
|
||||||
|
value_mode _mode = value_mode::INPUT;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
std::string name[16];
|
||||||
|
std::string visible_name[16];
|
||||||
|
} _cache;
|
||||||
|
|
||||||
|
public:
|
||||||
|
matrix_parameter(std::shared_ptr<gs::effect> effect, std::shared_ptr<gs::effect_parameter> param);
|
||||||
|
|
||||||
|
virtual void properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void remove_properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void update(obs_data_t* data) override;
|
||||||
|
|
||||||
|
virtual void tick(float_t time) override;
|
||||||
|
|
||||||
|
virtual void prepare() override;
|
||||||
|
|
||||||
|
virtual void assign() override;
|
||||||
};
|
};
|
||||||
struct string_parameter : parameter {
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
string_parameter(std::shared_ptr<gs::effect> effect, std::string name);
|
class string_parameter : public parameter {
|
||||||
|
std::string _value;
|
||||||
|
string_mode _mode = string_mode::TEXT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
string_parameter(std::shared_ptr<gs::effect> effect, std::shared_ptr<gs::effect_parameter> param);
|
||||||
|
|
||||||
|
virtual void properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void remove_properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void update(obs_data_t* data) override;
|
||||||
|
|
||||||
|
virtual void tick(float_t time) override;
|
||||||
|
|
||||||
|
virtual void prepare() override;
|
||||||
|
|
||||||
|
virtual void assign() override;
|
||||||
};
|
};
|
||||||
struct texture_parameter : parameter {
|
|
||||||
std::shared_ptr<gs::texture> value;
|
|
||||||
|
|
||||||
texture_parameter(std::shared_ptr<gs::effect> effect, std::string name);
|
class texture_parameter : public parameter {
|
||||||
|
std::string _file_name;
|
||||||
|
std::shared_ptr<gs::texture> _file;
|
||||||
|
|
||||||
|
std::string _source_name;
|
||||||
|
std::shared_ptr<obs::source> _source;
|
||||||
|
std::shared_ptr<gfx::source_texture> _source_renderer;
|
||||||
|
|
||||||
|
texture_mode _mode = texture_mode::FILE;
|
||||||
|
|
||||||
|
public:
|
||||||
|
texture_parameter(std::shared_ptr<gs::effect> effect, std::shared_ptr<gs::effect_parameter> param);
|
||||||
|
|
||||||
|
virtual void properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void remove_properties(obs_properties_t* props) override;
|
||||||
|
|
||||||
|
virtual void update(obs_data_t* data) override;
|
||||||
|
|
||||||
|
virtual void tick(float_t time) override;
|
||||||
|
|
||||||
|
virtual void prepare() override;
|
||||||
|
|
||||||
|
virtual void assign() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<gs::effect_parameter::type, std::string> param_ident_t;
|
typedef std::pair<gs::effect_parameter::type, std::string> param_ident_t;
|
||||||
|
|
||||||
class shader_instance {
|
class effect_source {
|
||||||
std::string _file;
|
std::string _file;
|
||||||
std::shared_ptr<gs::effect> _effect;
|
std::shared_ptr<gs::effect> _effect;
|
||||||
|
std::string _tech;
|
||||||
std::map<param_ident_t, std::shared_ptr<parameter>> _params;
|
std::map<param_ident_t, std::shared_ptr<parameter>> _params;
|
||||||
|
|
||||||
std::shared_ptr<gs::vertex_buffer> _tri;
|
std::shared_ptr<gs::vertex_buffer> _tri;
|
||||||
|
@ -107,15 +241,28 @@ namespace gfx {
|
||||||
time_t _last_modify_time;
|
time_t _last_modify_time;
|
||||||
time_t _last_create_time;
|
time_t _last_create_time;
|
||||||
|
|
||||||
|
float_t _time;
|
||||||
|
float_t _time_active;
|
||||||
|
float_t _time_since_last_tick;
|
||||||
|
|
||||||
|
std::uniform_real_distribution<float_t> _random_dist{0.f, 1.f};
|
||||||
|
std::default_random_engine _random_generator;
|
||||||
|
|
||||||
|
bool modified2(obs_properties_t* props, obs_property_t* property, obs_data_t* settings);
|
||||||
|
|
||||||
void load_file(std::string file);
|
void load_file(std::string file);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
shader_instance(std::string file);
|
effect_source();
|
||||||
~shader_instance();
|
~effect_source();
|
||||||
|
|
||||||
|
void properties(obs_properties_t* props);
|
||||||
|
|
||||||
|
void update(obs_data_t* data);
|
||||||
|
|
||||||
void tick(float_t time);
|
void tick(float_t time);
|
||||||
|
|
||||||
void render(std::string technique);
|
void render();
|
||||||
};
|
};
|
||||||
} // namespace effect_source
|
} // namespace effect_source
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
|
Loading…
Reference in a new issue