project: Apply new coding guidelines

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2019-08-04 16:20:26 +02:00
parent b6a3dea3f6
commit 0e350415b3
55 changed files with 2365 additions and 2357 deletions

File diff suppressed because it is too large Load diff

View file

@ -52,12 +52,12 @@ namespace filter {
};
class blur_factory {
obs_source_info source_info;
std::list<blur_instance*> sources;
std::shared_ptr<gs::effect> color_converter_effect;
std::shared_ptr<gs::effect> mask_effect;
obs_source_info _source_info;
std::list<blur_instance*> _sources;
std::shared_ptr<gs::effect> _color_converter_effect;
std::shared_ptr<gs::effect> _mask_effect;
std::map<std::string, std::string> translation_map;
std::map<std::string, std::string> _translation_map;
public: // Singleton
static void initialize();
@ -98,25 +98,25 @@ namespace filter {
};
class blur_instance {
obs_source_t* m_self;
obs_source_t* _self;
// Input
std::shared_ptr<gs::rendertarget> m_source_rt;
std::shared_ptr<gs::texture> m_source_texture;
bool m_source_rendered;
std::shared_ptr<gs::rendertarget> _source_rt;
std::shared_ptr<gs::texture> _source_texture;
bool _source_rendered;
// Rendering
std::shared_ptr<gs::texture> m_output_texture;
std::shared_ptr<gs::rendertarget> m_output_rt;
bool m_output_rendered;
std::shared_ptr<gs::texture> _output_texture;
std::shared_ptr<gs::rendertarget> _output_rt;
bool _output_rendered;
// Blur
std::shared_ptr<::gfx::blur::ibase> m_blur;
double_t m_blur_size;
double_t m_blur_angle;
std::pair<double_t, double_t> m_blur_center;
bool m_blur_step_scaling;
std::pair<double_t, double_t> m_blur_step_scale;
std::shared_ptr<::gfx::blur::base> _blur;
double_t _blur_size;
double_t _blur_angle;
std::pair<double_t, double_t> _blur_center;
bool _blur_step_scaling;
std::pair<double_t, double_t> _blur_step_scale;
// Masking
struct {
@ -150,7 +150,7 @@ namespace filter {
float_t a;
} color;
float_t multiplier;
} m_mask;
} _mask;
public:
blur_instance(obs_data_t* settings, obs_source_t* self);

View file

@ -61,15 +61,15 @@
#define TONE_HIG Highlight
// Initializer & Finalizer
INITIALIZER(FilterColorGradeInit)
P_INITIALIZER(FilterColorGradeInit)
{
initializerFunctions.push_back([] { filter::color_grade::color_grade_factory::initialize(); });
finalizerFunctions.push_back([] { filter::color_grade::color_grade_factory::finalize(); });
initializer_functions.push_back([] { filter::color_grade::color_grade_factory::initialize(); });
finalizer_functions.push_back([] { filter::color_grade::color_grade_factory::finalize(); });
}
const char* get_name(void*)
{
return P_TRANSLATE(ST);
return D_TRANSLATE(ST);
}
void get_defaults(obs_data_t* data)
@ -152,13 +152,13 @@ obs_properties_t* get_properties(void*)
if (util::are_property_groups_broken()) {
auto p =
obs_properties_add_list(pr, ST_TOOL, P_TRANSLATE(ST_TOOL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_list_add_string(p, P_TRANSLATE(ST_LIFT), ST_LIFT);
obs_property_list_add_string(p, P_TRANSLATE(ST_GAMMA), ST_GAMMA);
obs_property_list_add_string(p, P_TRANSLATE(ST_GAIN), ST_GAIN);
obs_property_list_add_string(p, P_TRANSLATE(ST_OFFSET), ST_OFFSET);
obs_property_list_add_string(p, P_TRANSLATE(ST_TINT), ST_TINT);
obs_property_list_add_string(p, P_TRANSLATE(ST_CORRECTION), ST_CORRECTION);
obs_properties_add_list(pr, ST_TOOL, D_TRANSLATE(ST_TOOL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_list_add_string(p, D_TRANSLATE(ST_LIFT), ST_LIFT);
obs_property_list_add_string(p, D_TRANSLATE(ST_GAMMA), ST_GAMMA);
obs_property_list_add_string(p, D_TRANSLATE(ST_GAIN), ST_GAIN);
obs_property_list_add_string(p, D_TRANSLATE(ST_OFFSET), ST_OFFSET);
obs_property_list_add_string(p, D_TRANSLATE(ST_TINT), ST_TINT);
obs_property_list_add_string(p, D_TRANSLATE(ST_CORRECTION), ST_CORRECTION);
obs_property_set_modified_callback(p, &tool_modified);
}
@ -166,80 +166,80 @@ obs_properties_t* get_properties(void*)
obs_properties_t* grp = pr;
if (!util::are_property_groups_broken()) {
grp = obs_properties_create();
obs_properties_add_group(pr, ST_LIFT, P_TRANSLATE(ST_LIFT), OBS_GROUP_NORMAL, grp);
obs_properties_add_group(pr, ST_LIFT, D_TRANSLATE(ST_LIFT), OBS_GROUP_NORMAL, grp);
}
obs_properties_add_float_slider(grp, ST_LIFT_(RED), P_TRANSLATE(ST_LIFT_(RED)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_LIFT_(GREEN), P_TRANSLATE(ST_LIFT_(GREEN)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_LIFT_(BLUE), P_TRANSLATE(ST_LIFT_(BLUE)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_LIFT_(ALL), P_TRANSLATE(ST_LIFT_(ALL)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_LIFT_(RED), D_TRANSLATE(ST_LIFT_(RED)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_LIFT_(GREEN), D_TRANSLATE(ST_LIFT_(GREEN)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_LIFT_(BLUE), D_TRANSLATE(ST_LIFT_(BLUE)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_LIFT_(ALL), D_TRANSLATE(ST_LIFT_(ALL)), -1000.0, 1000.0, 0.01);
}
{
obs_properties_t* grp = pr;
if (!util::are_property_groups_broken()) {
grp = obs_properties_create();
obs_properties_add_group(pr, ST_GAMMA, P_TRANSLATE(ST_GAMMA), OBS_GROUP_NORMAL, grp);
obs_properties_add_group(pr, ST_GAMMA, D_TRANSLATE(ST_GAMMA), OBS_GROUP_NORMAL, grp);
}
obs_properties_add_float_slider(grp, ST_GAMMA_(RED), P_TRANSLATE(ST_GAMMA_(RED)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAMMA_(GREEN), P_TRANSLATE(ST_GAMMA_(GREEN)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAMMA_(BLUE), P_TRANSLATE(ST_GAMMA_(BLUE)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAMMA_(ALL), P_TRANSLATE(ST_GAMMA_(ALL)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAMMA_(RED), D_TRANSLATE(ST_GAMMA_(RED)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAMMA_(GREEN), D_TRANSLATE(ST_GAMMA_(GREEN)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAMMA_(BLUE), D_TRANSLATE(ST_GAMMA_(BLUE)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAMMA_(ALL), D_TRANSLATE(ST_GAMMA_(ALL)), -1000.0, 1000.0, 0.01);
}
{
obs_properties_t* grp = pr;
if (!util::are_property_groups_broken()) {
grp = obs_properties_create();
obs_properties_add_group(pr, ST_GAIN, P_TRANSLATE(ST_GAIN), OBS_GROUP_NORMAL, grp);
obs_properties_add_group(pr, ST_GAIN, D_TRANSLATE(ST_GAIN), OBS_GROUP_NORMAL, grp);
}
obs_properties_add_float_slider(grp, ST_GAIN_(RED), P_TRANSLATE(ST_GAIN_(RED)), 0.01, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAIN_(GREEN), P_TRANSLATE(ST_GAIN_(GREEN)), 0.01, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAIN_(BLUE), P_TRANSLATE(ST_GAIN_(BLUE)), 0.01, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAIN_(ALL), P_TRANSLATE(ST_GAIN_(ALL)), 0.01, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAIN_(RED), D_TRANSLATE(ST_GAIN_(RED)), 0.01, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAIN_(GREEN), D_TRANSLATE(ST_GAIN_(GREEN)), 0.01, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAIN_(BLUE), D_TRANSLATE(ST_GAIN_(BLUE)), 0.01, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_GAIN_(ALL), D_TRANSLATE(ST_GAIN_(ALL)), 0.01, 1000.0, 0.01);
}
{
obs_properties_t* grp = pr;
if (!util::are_property_groups_broken()) {
grp = obs_properties_create();
obs_properties_add_group(pr, ST_OFFSET, P_TRANSLATE(ST_OFFSET), OBS_GROUP_NORMAL, grp);
obs_properties_add_group(pr, ST_OFFSET, D_TRANSLATE(ST_OFFSET), OBS_GROUP_NORMAL, grp);
}
obs_properties_add_float_slider(grp, ST_OFFSET_(RED), P_TRANSLATE(ST_OFFSET_(RED)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_OFFSET_(GREEN), P_TRANSLATE(ST_OFFSET_(GREEN)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_OFFSET_(BLUE), P_TRANSLATE(ST_OFFSET_(BLUE)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_OFFSET_(ALL), P_TRANSLATE(ST_OFFSET_(ALL)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_OFFSET_(RED), D_TRANSLATE(ST_OFFSET_(RED)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_OFFSET_(GREEN), D_TRANSLATE(ST_OFFSET_(GREEN)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_OFFSET_(BLUE), D_TRANSLATE(ST_OFFSET_(BLUE)), -1000.0, 1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_OFFSET_(ALL), D_TRANSLATE(ST_OFFSET_(ALL)), -1000.0, 1000.0, 0.01);
}
{
obs_properties_t* grp = pr;
if (!util::are_property_groups_broken()) {
grp = obs_properties_create();
obs_properties_add_group(pr, ST_TINT, P_TRANSLATE(ST_TINT), OBS_GROUP_NORMAL, grp);
obs_properties_add_group(pr, ST_TINT, D_TRANSLATE(ST_TINT), OBS_GROUP_NORMAL, grp);
}
obs_properties_add_float_slider(grp, ST_TINT_(TONE_LOW, RED), P_TRANSLATE(ST_TINT_(TONE_LOW, RED)), 0, 1000.0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_LOW, RED), D_TRANSLATE(ST_TINT_(TONE_LOW, RED)), 0, 1000.0,
0.01);
obs_properties_add_float_slider(grp, ST_TINT_(TONE_LOW, GREEN), P_TRANSLATE(ST_TINT_(TONE_LOW, GREEN)), 0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_LOW, GREEN), D_TRANSLATE(ST_TINT_(TONE_LOW, GREEN)), 0,
1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_TINT_(TONE_LOW, BLUE), P_TRANSLATE(ST_TINT_(TONE_LOW, BLUE)), 0, 1000.0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_LOW, BLUE), D_TRANSLATE(ST_TINT_(TONE_LOW, BLUE)), 0, 1000.0,
0.01);
obs_properties_add_float_slider(grp, ST_TINT_(TONE_MID, RED), P_TRANSLATE(ST_TINT_(TONE_MID, RED)), 0, 1000.0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_MID, RED), D_TRANSLATE(ST_TINT_(TONE_MID, RED)), 0, 1000.0,
0.01);
obs_properties_add_float_slider(grp, ST_TINT_(TONE_MID, GREEN), P_TRANSLATE(ST_TINT_(TONE_MID, GREEN)), 0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_MID, GREEN), D_TRANSLATE(ST_TINT_(TONE_MID, GREEN)), 0,
1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_TINT_(TONE_MID, BLUE), P_TRANSLATE(ST_TINT_(TONE_MID, BLUE)), 0, 1000.0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_MID, BLUE), D_TRANSLATE(ST_TINT_(TONE_MID, BLUE)), 0, 1000.0,
0.01);
obs_properties_add_float_slider(grp, ST_TINT_(TONE_HIG, RED), P_TRANSLATE(ST_TINT_(TONE_HIG, RED)), 0, 1000.0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_HIG, RED), D_TRANSLATE(ST_TINT_(TONE_HIG, RED)), 0, 1000.0,
0.01);
obs_properties_add_float_slider(grp, ST_TINT_(TONE_HIG, GREEN), P_TRANSLATE(ST_TINT_(TONE_HIG, GREEN)), 0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_HIG, GREEN), D_TRANSLATE(ST_TINT_(TONE_HIG, GREEN)), 0,
1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_TINT_(TONE_HIG, BLUE), P_TRANSLATE(ST_TINT_(TONE_HIG, BLUE)), 0, 1000.0,
obs_properties_add_float_slider(grp, ST_TINT_(TONE_HIG, BLUE), D_TRANSLATE(ST_TINT_(TONE_HIG, BLUE)), 0, 1000.0,
0.01);
}
@ -247,15 +247,15 @@ obs_properties_t* get_properties(void*)
obs_properties_t* grp = pr;
if (!util::are_property_groups_broken()) {
grp = obs_properties_create();
obs_properties_add_group(pr, ST_CORRECTION, P_TRANSLATE(ST_CORRECTION), OBS_GROUP_NORMAL, grp);
obs_properties_add_group(pr, ST_CORRECTION, D_TRANSLATE(ST_CORRECTION), OBS_GROUP_NORMAL, grp);
}
obs_properties_add_float_slider(grp, ST_CORRECTION_(HUE), P_TRANSLATE(ST_CORRECTION_(HUE)), -180, 180.0, 0.01);
obs_properties_add_float_slider(grp, ST_CORRECTION_(SATURATION), P_TRANSLATE(ST_CORRECTION_(SATURATION)), 0.0,
obs_properties_add_float_slider(grp, ST_CORRECTION_(HUE), D_TRANSLATE(ST_CORRECTION_(HUE)), -180, 180.0, 0.01);
obs_properties_add_float_slider(grp, ST_CORRECTION_(SATURATION), D_TRANSLATE(ST_CORRECTION_(SATURATION)), 0.0,
1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_CORRECTION_(LIGHTNESS), P_TRANSLATE(ST_CORRECTION_(LIGHTNESS)), 0.0,
obs_properties_add_float_slider(grp, ST_CORRECTION_(LIGHTNESS), D_TRANSLATE(ST_CORRECTION_(LIGHTNESS)), 0.0,
1000.0, 0.01);
obs_properties_add_float_slider(grp, ST_CORRECTION_(CONTRAST), P_TRANSLATE(ST_CORRECTION_(CONTRAST)), 0.0,
obs_properties_add_float_slider(grp, ST_CORRECTION_(CONTRAST), D_TRANSLATE(ST_CORRECTION_(CONTRAST)), 0.0,
1000.0, 0.01);
}
@ -374,12 +374,12 @@ filter::color_grade::color_grade_instance::color_grade_instance(obs_data_t* data
update(data);
{
char* file = obs_module_file("effects/color-grade.effect");
char* file = obs_module_file("effects/color-grade._effect");
try {
_effect = std::make_shared<gs::effect>(file);
bfree(file);
} catch (std::runtime_error& ex) {
P_LOG_ERROR("<filter-color-grade> Loading effect '%s' failed with error(s): %s", file, ex.what());
P_LOG_ERROR("<filter-color-grade> Loading _effect '%s' failed with error(s): %s", file, ex.what());
bfree(file);
throw ex;
}

View file

@ -59,10 +59,10 @@
enum class ShaderType : int64_t { Text, File };
static filter::CustomShader* handler;
INITIALIZER(HandlerInit)
P_INITIALIZER(HandlerInit)
{
initializerFunctions.push_back([] { handler = new filter::CustomShader(); });
finalizerFunctions.push_back([] { delete handler; });
initializer_functions.push_back([] { handler = new filter::CustomShader(); });
finalizer_functions.push_back([] { delete handler; });
}
filter::CustomShader::CustomShader()
@ -91,7 +91,7 @@ filter::CustomShader::~CustomShader() {}
const char* filter::CustomShader::get_name(void*)
{
return P_TRANSLATE(S);
return D_TRANSLATE(S);
}
void filter::CustomShader::get_defaults(obs_data_t* data)
@ -153,7 +153,7 @@ void filter::CustomShader::video_render(void* ptr, gs_effect_t* effect)
filter::CustomShader::Instance::Instance(obs_data_t* data, obs_source_t* source) : gfx::effect_source(data, source)
{
m_defaultShaderPath = "shaders/filter/example.effect";
m_defaultShaderPath = "shaders/filter/example._effect";
m_renderTarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
update(data);
}

View file

@ -21,11 +21,17 @@
#include <sys/stat.h>
#include "strings.hpp"
#define ST "Filter.Displacement"
#define ST_FILE "Filter.Displacement.File"
#define ST_FILE_TYPES "Filter.Displacement.File.Types"
#define ST_RATIO "Filter.Displacement.Ratio"
#define ST_SCALE "Filter.Displacement.Scale"
// Initializer & Finalizer
INITIALIZER(FilterDisplacementInit)
P_INITIALIZER(FilterDisplacementInit)
{
initializerFunctions.push_back([] { filter::displacement::displacement_factory::initialize(); });
finalizerFunctions.push_back([] { filter::displacement::displacement_factory::finalize(); });
initializer_functions.push_back([] { filter::displacement::displacement_factory::initialize(); });
finalizer_functions.push_back([] { filter::displacement::displacement_factory::finalize(); });
}
static std::shared_ptr<filter::displacement::displacement_factory> factory_instance = nullptr;
@ -47,32 +53,32 @@ std::shared_ptr<filter::displacement::displacement_factory> filter::displacement
filter::displacement::displacement_factory::displacement_factory()
{
memset(&sourceInfo, 0, sizeof(obs_source_info));
sourceInfo.id = "obs-stream-effects-filter-displacement";
sourceInfo.type = OBS_SOURCE_TYPE_FILTER;
sourceInfo.output_flags = OBS_SOURCE_VIDEO;
sourceInfo.get_name = get_name;
sourceInfo.get_defaults = get_defaults;
sourceInfo.get_properties = get_properties;
memset(&_source_info, 0, sizeof(obs_source_info));
_source_info.id = "obs-stream-effects-filter-displacement";
_source_info.type = OBS_SOURCE_TYPE_FILTER;
_source_info.output_flags = OBS_SOURCE_VIDEO;
_source_info.get_name = get_name;
_source_info.get_defaults = get_defaults;
_source_info.get_properties = get_properties;
sourceInfo.create = create;
sourceInfo.destroy = destroy;
sourceInfo.update = update;
sourceInfo.activate = activate;
sourceInfo.deactivate = deactivate;
sourceInfo.show = show;
sourceInfo.hide = hide;
sourceInfo.video_tick = video_tick;
sourceInfo.video_render = video_render;
_source_info.create = create;
_source_info.destroy = destroy;
_source_info.update = update;
_source_info.activate = activate;
_source_info.deactivate = deactivate;
_source_info.show = show;
_source_info.hide = hide;
_source_info.video_tick = video_tick;
_source_info.video_render = video_render;
obs_register_source(&sourceInfo);
obs_register_source(&_source_info);
}
filter::displacement::displacement_factory::~displacement_factory() {}
const char* filter::displacement::displacement_factory::get_name(void*)
{
return P_TRANSLATE(S_FILTER_DISPLACEMENT);
return D_TRANSLATE(ST);
}
void* filter::displacement::displacement_factory::create(obs_data_t* data, obs_source_t* source)
@ -98,9 +104,9 @@ uint32_t filter::displacement::displacement_factory::get_height(void* ptr)
void filter::displacement::displacement_factory::get_defaults(obs_data_t* data)
{
char* disp = obs_module_file("filter-displacement/neutral.png");
obs_data_set_default_string(data, S_FILTER_DISPLACEMENT_FILE, disp);
obs_data_set_default_double(data, S_FILTER_DISPLACEMENT_RATIO, 0);
obs_data_set_default_double(data, S_FILTER_DISPLACEMENT_SCALE, 0);
obs_data_set_default_string(data, ST_FILE, disp);
obs_data_set_default_double(data, ST_RATIO, 0);
obs_data_set_default_double(data, ST_SCALE, 0);
bfree(disp);
}
@ -112,11 +118,11 @@ obs_properties_t* filter::displacement::displacement_factory::get_properties(voi
if (ptr)
path = reinterpret_cast<displacement_instance*>(ptr)->get_file();
obs_properties_add_path(pr, S_FILTER_DISPLACEMENT_FILE, P_TRANSLATE(S_FILTER_DISPLACEMENT_FILE),
obs_path_type::OBS_PATH_FILE, P_TRANSLATE(S_FILTER_DISPLACEMENT_FILE_TYPES), path.c_str());
obs_properties_add_float_slider(pr, S_FILTER_DISPLACEMENT_RATIO, P_TRANSLATE(S_FILTER_DISPLACEMENT_RATIO), 0, 1,
obs_properties_add_path(pr, ST_FILE, D_TRANSLATE(ST_FILE),
obs_path_type::OBS_PATH_FILE, D_TRANSLATE(ST_FILE_TYPES), path.c_str());
obs_properties_add_float_slider(pr, ST_RATIO, D_TRANSLATE(ST_RATIO), 0, 1,
0.01);
obs_properties_add_float_slider(pr, S_FILTER_DISPLACEMENT_SCALE, P_TRANSLATE(S_FILTER_DISPLACEMENT_SCALE), -1000,
obs_properties_add_float_slider(pr, ST_SCALE, D_TRANSLATE(ST_SCALE), -1000,
1000, 0.01);
return pr;
}
@ -166,41 +172,41 @@ void filter::displacement::displacement_instance::validate_file_texture(std::str
}
// File name different
if (file != m_file_name) {
if (file != _file_name) {
do_update = true;
m_file_name = file;
_file_name = file;
}
// Timestamp verification
struct stat stats;
if (os_stat(m_file_name.c_str(), &stats) != 0) {
do_update = do_update || (stats.st_ctime != m_file_create_time);
do_update = do_update || (stats.st_mtime != m_file_modified_time);
do_update = do_update || (static_cast<size_t>(stats.st_size) != m_file_size);
m_file_create_time = stats.st_ctime;
m_file_modified_time = stats.st_mtime;
m_file_size = static_cast<size_t>(stats.st_size);
if (os_stat(_file_name.c_str(), &stats) != 0) {
do_update = do_update || (stats.st_ctime != _file_create_time);
do_update = do_update || (stats.st_mtime != _file_modified_time);
do_update = do_update || (static_cast<size_t>(stats.st_size) != _file_size);
_file_create_time = stats.st_ctime;
_file_modified_time = stats.st_mtime;
_file_size = static_cast<size_t>(stats.st_size);
}
do_update = !m_file_texture || do_update;
do_update = !_file_texture || do_update;
if (do_update) {
try {
m_file_texture = std::make_shared<gs::texture>(m_file_name);
_file_texture = std::make_shared<gs::texture>(_file_name);
} catch (...) {
}
}
}
filter::displacement::displacement_instance::displacement_instance(obs_data_t* data, obs_source_t* context)
: m_self(context), m_timer(0), m_effect(nullptr), m_distance(0), m_file_create_time(0), m_file_modified_time(0),
m_file_size(0)
: _self(context), _timer(0), _effect(nullptr), _distance(0), _file_create_time(0), _file_modified_time(0),
_file_size(0)
{
char* effectFile = obs_module_file("effects/displace.effect");
char* effectFile = obs_module_file("effects/displace._effect");
try {
m_effect = std::make_shared<gs::effect>(effectFile);
_effect = std::make_shared<gs::effect>(effectFile);
} catch (...) {
P_LOG_ERROR("<Displacement Filter:%s> Failed to load displacement effect.", obs_source_get_name(m_self));
P_LOG_ERROR("<Displacement Filter:%s> Failed to load displacement _effect.", obs_source_get_name(_self));
}
bfree(effectFile);
@ -209,17 +215,17 @@ filter::displacement::displacement_instance::displacement_instance(obs_data_t* d
filter::displacement::displacement_instance::~displacement_instance()
{
m_effect.reset();
m_file_texture.reset();
_effect.reset();
_file_texture.reset();
}
void filter::displacement::displacement_instance::update(obs_data_t* data)
{
validate_file_texture(obs_data_get_string(data, S_FILTER_DISPLACEMENT_FILE));
validate_file_texture(obs_data_get_string(data, ST_FILE));
m_distance = float_t(obs_data_get_double(data, S_FILTER_DISPLACEMENT_RATIO));
vec2_set(&m_displacement_scale, float_t(obs_data_get_double(data, S_FILTER_DISPLACEMENT_SCALE)),
float_t(obs_data_get_double(data, S_FILTER_DISPLACEMENT_SCALE)));
_distance = float_t(obs_data_get_double(data, ST_RATIO));
vec2_set(&_displacement_scale, float_t(obs_data_get_double(data, ST_SCALE)),
float_t(obs_data_get_double(data, ST_SCALE)));
}
uint32_t filter::displacement::displacement_instance::get_width()
@ -242,10 +248,10 @@ void filter::displacement::displacement_instance::hide() {}
void filter::displacement::displacement_instance::video_tick(float time)
{
m_timer += time;
if (m_timer >= 1.0f) {
m_timer -= 1.0f;
validate_file_texture(m_file_name);
_timer += time;
if (_timer >= 1.0f) {
_timer -= 1.0f;
validate_file_texture(_file_name);
}
}
@ -256,36 +262,36 @@ static float interp(float a, float b, float v)
void filter::displacement::displacement_instance::video_render(gs_effect_t*)
{
obs_source_t* parent = obs_filter_get_parent(m_self);
obs_source_t* target = obs_filter_get_target(m_self);
obs_source_t* parent = obs_filter_get_parent(_self);
obs_source_t* target = obs_filter_get_target(_self);
uint32_t baseW = obs_source_get_base_width(target), baseH = obs_source_get_base_height(target);
// Skip rendering if our target, parent or context is not valid.
if (!parent || !target || !baseW || !baseH || !m_file_texture) {
obs_source_skip_video_filter(m_self);
if (!parent || !target || !baseW || !baseH || !_file_texture) {
obs_source_skip_video_filter(_self);
return;
}
if (!obs_source_process_filter_begin(m_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
obs_source_skip_video_filter(m_self);
if (!obs_source_process_filter_begin(_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
obs_source_skip_video_filter(_self);
return;
}
if (m_effect->has_parameter("texelScale")) {
m_effect->get_parameter("texelScale")
.set_float2(interp((1.0f / baseW), 1.0f, m_distance), interp((1.0f / baseH), 1.0f, m_distance));
if (_effect->has_parameter("texelScale")) {
_effect->get_parameter("texelScale")
.set_float2(interp((1.0f / baseW), 1.0f, _distance), interp((1.0f / baseH), 1.0f, _distance));
}
if (m_effect->has_parameter("displacementScale")) {
m_effect->get_parameter("displacementScale").set_float2(m_displacement_scale);
if (_effect->has_parameter("displacementScale")) {
_effect->get_parameter("displacementScale").set_float2(_displacement_scale);
}
if (m_effect->has_parameter("displacementMap")) {
m_effect->get_parameter("displacementMap").set_texture(m_file_texture);
if (_effect->has_parameter("displacementMap")) {
_effect->get_parameter("displacementMap").set_texture(_file_texture);
}
obs_source_process_filter_end(m_self, m_effect->get_object(), baseW, baseH);
obs_source_process_filter_end(_self, _effect->get_object(), baseW, baseH);
}
std::string filter::displacement::displacement_instance::get_file()
{
return m_file_name;
return _file_name;
}

View file

@ -34,16 +34,10 @@
#pragma warning(pop)
#endif
#define S_FILTER_DISPLACEMENT "Filter.Displacement"
#define S_FILTER_DISPLACEMENT_FILE "Filter.Displacement.File"
#define S_FILTER_DISPLACEMENT_FILE_TYPES "Filter.Displacement.File.Types"
#define S_FILTER_DISPLACEMENT_RATIO "Filter.Displacement.Ratio"
#define S_FILTER_DISPLACEMENT_SCALE "Filter.Displacement.Scale"
namespace filter {
namespace displacement {
class displacement_factory {
obs_source_info sourceInfo;
obs_source_info _source_info;
public: // Singleton
static void initialize();
@ -72,20 +66,20 @@ namespace filter {
};
class displacement_instance {
obs_source_t* m_self;
float_t m_timer;
obs_source_t* _self;
float_t _timer;
// Rendering
std::shared_ptr<gs::effect> m_effect;
float_t m_distance;
vec2 m_displacement_scale;
std::shared_ptr<gs::effect> _effect;
float_t _distance;
vec2 _displacement_scale;
// Displacement Map
std::string m_file_name;
std::shared_ptr<gs::texture> m_file_texture;
time_t m_file_create_time;
time_t m_file_modified_time;
size_t m_file_size;
std::string _file_name;
std::shared_ptr<gs::texture> _file_texture;
time_t _file_create_time;
time_t _file_modified_time;
size_t _file_size;
void validate_file_texture(std::string file);

View file

@ -30,13 +30,13 @@
// - Green Mask Output
// - Alpha Mask Output
#define SOURCE_NAME "Filter.DynamicMask"
#define ST "Filter.DynamicMask"
#define S_INPUT "Filter.DynamicMask.Input"
#define S_CHANNEL "Filter.DynamicMask.Channel"
#define S_CHANNEL_VALUE "Filter.DynamicMask.Channel.Value"
#define S_CHANNEL_MULTIPLIER "Filter.DynamicMask.Channel.Multiplier"
#define S_CHANNEL_INPUT "Filter.DynamicMask.Channel.Input"
#define ST_INPUT "Filter.DynamicMask.Input"
#define ST_CHANNEL "Filter.DynamicMask.Channel"
#define ST_CHANNEL_VALUE "Filter.DynamicMask.Channel.Value"
#define ST_CHANNEL_MULTIPLIER "Filter.DynamicMask.Channel.Multiplier"
#define ST_CHANNEL_INPUT "Filter.DynamicMask.Channel.Input"
static std::pair<filter::dynamic_mask::channel, const char*> channel_translations[] = {
{filter::dynamic_mask::channel::Red, S_CHANNEL_RED},
@ -45,10 +45,10 @@ static std::pair<filter::dynamic_mask::channel, const char*> channel_translation
{filter::dynamic_mask::channel::Alpha, S_CHANNEL_ALPHA},
};
INITIALIZER(FilterDynamicMaskInit)
P_INITIALIZER(FilterDynamicMaskInit)
{
initializerFunctions.push_back([] { filter::dynamic_mask::dynamic_mask_factory::initialize(); });
finalizerFunctions.push_back([] { filter::dynamic_mask::dynamic_mask_factory::finalize(); });
initializer_functions.push_back([] { filter::dynamic_mask::dynamic_mask_factory::initialize(); });
finalizer_functions.push_back([] { filter::dynamic_mask::dynamic_mask_factory::finalize(); });
}
static std::shared_ptr<filter::dynamic_mask::dynamic_mask_factory> factory_instance = nullptr;
@ -70,73 +70,73 @@ std::shared_ptr<filter::dynamic_mask::dynamic_mask_factory> filter::dynamic_mask
filter::dynamic_mask::dynamic_mask_factory::dynamic_mask_factory()
{
memset(&sourceInfo, 0, sizeof(obs_source_info));
sourceInfo.id = "obs-stream-effects-filter-dynamic-mask";
sourceInfo.type = OBS_SOURCE_TYPE_FILTER;
sourceInfo.output_flags = OBS_SOURCE_VIDEO;
memset(&_source_info, 0, sizeof(obs_source_info));
_source_info.id = "obs-stream-effects-filter-dynamic-mask";
_source_info.type = OBS_SOURCE_TYPE_FILTER;
_source_info.output_flags = OBS_SOURCE_VIDEO;
sourceInfo.get_name = [](void*) { return P_TRANSLATE(SOURCE_NAME); };
_source_info.get_name = [](void*) { return D_TRANSLATE(ST); };
sourceInfo.create = [](obs_data_t* settings, obs_source_t* source) {
_source_info.create = [](obs_data_t* settings, obs_source_t* source) {
return reinterpret_cast<void*>(new filter::dynamic_mask::dynamic_mask_instance(settings, source));
};
sourceInfo.destroy = [](void* _ptr) {
_source_info.destroy = [](void* _ptr) {
delete reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr);
};
sourceInfo.get_defaults2 = [](void*, obs_data_t* settings) {
obs_data_set_default_int(settings, S_CHANNEL, static_cast<int64_t>(channel::Red));
_source_info.get_defaults2 = [](void*, obs_data_t* settings) {
obs_data_set_default_int(settings, ST_CHANNEL, static_cast<int64_t>(channel::Red));
for (auto kv : channel_translations) {
obs_data_set_default_double(settings, (std::string(S_CHANNEL_VALUE) + "." + kv.second).c_str(), 1.0);
obs_data_set_default_double(settings, (std::string(S_CHANNEL_MULTIPLIER) + "." + kv.second).c_str(), 1.0);
obs_data_set_default_double(settings, (std::string(ST_CHANNEL_VALUE) + "." + kv.second).c_str(), 1.0);
obs_data_set_default_double(settings, (std::string(ST_CHANNEL_MULTIPLIER) + "." + kv.second).c_str(), 1.0);
for (auto kv2 : channel_translations) {
obs_data_set_default_double(
settings, (std::string(S_CHANNEL_INPUT) + "." + kv.second + "." + kv2.second).c_str(), 0.0);
settings, (std::string(ST_CHANNEL_INPUT) + "." + kv.second + "." + kv2.second).c_str(), 0.0);
}
}
};
sourceInfo.get_properties2 = [](void* _ptr, void* _type_data_ptr) {
_source_info.get_properties2 = [](void* _ptr, void* _type_data_ptr) {
obs_properties_t* props = obs_properties_create_param(_type_data_ptr, nullptr);
reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr)->get_properties(props);
return props;
};
sourceInfo.update = [](void* _ptr, obs_data_t* settings) {
_source_info.update = [](void* _ptr, obs_data_t* settings) {
reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr)->update(settings);
};
sourceInfo.load = [](void* _ptr, obs_data_t* settings) {
_source_info.load = [](void* _ptr, obs_data_t* settings) {
reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr)->load(settings);
};
sourceInfo.save = [](void* _ptr, obs_data_t* settings) {
_source_info.save = [](void* _ptr, obs_data_t* settings) {
reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr)->save(settings);
};
sourceInfo.video_tick = [](void* _ptr, float_t _seconds) {
_source_info.video_tick = [](void* _ptr, float_t _seconds) {
reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr)->video_tick(_seconds);
};
sourceInfo.video_render = [](void* _ptr, gs_effect_t* _effect) {
_source_info.video_render = [](void* _ptr, gs_effect_t* _effect) {
reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr)->video_render(_effect);
};
obs_register_source(&sourceInfo);
obs_register_source(&_source_info);
}
filter::dynamic_mask::dynamic_mask_factory::~dynamic_mask_factory() {}
filter::dynamic_mask::dynamic_mask_instance::dynamic_mask_instance(obs_data_t* data, obs_source_t* self) : self(self)
filter::dynamic_mask::dynamic_mask_instance::dynamic_mask_instance(obs_data_t* data, obs_source_t* self) : _self(self)
{
this->update(data);
this->filter_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
this->final_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
this->_filter_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
this->_final_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
{
char* file = obs_module_file("effects/channel-mask.effect");
char* file = obs_module_file("effects/channel-mask._effect");
try {
this->effect = std::make_shared<gs::effect>(file);
this->_effect = std::make_shared<gs::effect>(file);
} catch (std::exception& ex) {
P_LOG_ERROR("Loading channel mask effect failed with error(s):\n%s", ex.what());
P_LOG_ERROR("Loading channel mask _effect failed with error(s):\n%s", ex.what());
}
assert(this->effect != nullptr);
assert(this->_effect != nullptr);
bfree(file);
}
}
@ -157,17 +157,17 @@ void filter::dynamic_mask::dynamic_mask_instance::get_properties(obs_properties_
{
obs_property_t* p;
this->translation_map.clear();
this->_translation_map.clear();
{
p = obs_properties_add_list(properties, S_INPUT, P_TRANSLATE(S_INPUT), OBS_COMBO_TYPE_LIST,
p = obs_properties_add_list(properties, ST_INPUT, D_TRANSLATE(ST_INPUT), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(S_INPUT)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_INPUT)));
obs_property_list_add_string(p, "", "");
obs::source_tracker::get()->enumerate(
[&p](std::string name, obs_source_t*) {
std::stringstream sstr;
sstr << name << " (" << P_TRANSLATE(S_SOURCETYPE_SOURCE) << ")";
sstr << name << " (" << D_TRANSLATE(S_SOURCETYPE_SOURCE) << ")";
obs_property_list_add_string(p, sstr.str().c_str(), name.c_str());
return false;
},
@ -175,7 +175,7 @@ void filter::dynamic_mask::dynamic_mask_instance::get_properties(obs_properties_
obs::source_tracker::get()->enumerate(
[&p](std::string name, obs_source_t*) {
std::stringstream sstr;
sstr << name << " (" << P_TRANSLATE(S_SOURCETYPE_SCENE) << ")";
sstr << name << " (" << D_TRANSLATE(S_SOURCETYPE_SCENE) << ")";
obs_property_list_add_string(p, sstr.str().c_str(), name.c_str());
return false;
},
@ -183,62 +183,62 @@ void filter::dynamic_mask::dynamic_mask_instance::get_properties(obs_properties_
}
{
p = obs_properties_add_list(properties, S_CHANNEL, P_TRANSLATE(S_CHANNEL), OBS_COMBO_TYPE_LIST,
p = obs_properties_add_list(properties, ST_CHANNEL, D_TRANSLATE(ST_CHANNEL), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(S_CHANNEL)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CHANNEL)));
for (auto kv : channel_translations) {
obs_property_list_add_int(p, P_TRANSLATE(kv.second), static_cast<int64_t>(kv.first));
obs_property_list_add_int(p, D_TRANSLATE(kv.second), static_cast<int64_t>(kv.first));
}
obs_property_set_modified_callback2(p, modified, this);
for (auto kv : channel_translations) {
std::string color = P_TRANSLATE(kv.second);
std::string color = D_TRANSLATE(kv.second);
{
std::string _chv = P_TRANSLATE(S_CHANNEL_VALUE);
std::string _chv = D_TRANSLATE(ST_CHANNEL_VALUE);
std::vector<char> _chv_data(_chv.size() * 2 + color.size() * 2, '\0');
sprintf_s(_chv_data.data(), _chv_data.size(), _chv.c_str(), color.c_str());
auto _chv_key = std::tuple{kv.first, channel::Invalid, std::string(S_CHANNEL_VALUE)};
translation_map.insert({_chv_key, std::string(_chv_data.begin(), _chv_data.end())});
auto chv = translation_map.find(_chv_key);
std::string chv_key = std::string(S_CHANNEL_VALUE) + "." + kv.second;
auto _chv_key = std::tuple{kv.first, channel::Invalid, std::string(ST_CHANNEL_VALUE)};
_translation_map.insert({_chv_key, std::string(_chv_data.begin(), _chv_data.end())});
auto chv = _translation_map.find(_chv_key);
std::string chv_key = std::string(ST_CHANNEL_VALUE) + "." + kv.second;
p = obs_properties_add_float_slider(properties, chv_key.c_str(), chv->second.c_str(), -100.0, 100.0,
0.01);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(S_CHANNEL_VALUE)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CHANNEL_VALUE)));
std::string _chm = P_TRANSLATE(S_CHANNEL_MULTIPLIER);
std::string _chm = D_TRANSLATE(ST_CHANNEL_MULTIPLIER);
std::vector<char> _chm_data(_chm.size() * 2 + color.size() * 2, '\0');
sprintf_s(_chm_data.data(), _chm_data.size(), _chm.c_str(), color.c_str());
auto _chm_key = std::tuple{kv.first, channel::Invalid, std::string(S_CHANNEL_MULTIPLIER)};
translation_map.insert({_chm_key, std::string(_chm_data.begin(), _chm_data.end())});
auto chm = translation_map.find(_chm_key);
std::string chm_key = std::string(S_CHANNEL_MULTIPLIER) + "." + kv.second;
auto _chm_key = std::tuple{kv.first, channel::Invalid, std::string(ST_CHANNEL_MULTIPLIER)};
_translation_map.insert({_chm_key, std::string(_chm_data.begin(), _chm_data.end())});
auto chm = _translation_map.find(_chm_key);
std::string chm_key = std::string(ST_CHANNEL_MULTIPLIER) + "." + kv.second;
p = obs_properties_add_float_slider(properties, chm_key.c_str(), chm->second.c_str(), -100.0, 100.0,
0.01);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(S_CHANNEL_MULTIPLIER)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CHANNEL_MULTIPLIER)));
}
}
}
{
for (auto kv1 : channel_translations) {
std::string color1 = P_TRANSLATE(kv1.second);
std::string color1 = D_TRANSLATE(kv1.second);
for (auto kv2 : channel_translations) {
std::string color2 = P_TRANSLATE(kv2.second);
std::string color2 = D_TRANSLATE(kv2.second);
std::string _chm = P_TRANSLATE(S_CHANNEL_INPUT);
std::string _chm = D_TRANSLATE(ST_CHANNEL_INPUT);
std::vector<char> _chm_data(_chm.size() * 2 + color1.size() * 2 + color2.size() * 2, '\0');
sprintf_s(_chm_data.data(), _chm_data.size(), _chm.c_str(), color1.c_str(), color2.c_str());
auto _chm_key = std::tuple{kv1.first, kv2.first, std::string(S_CHANNEL_INPUT)};
translation_map.insert({_chm_key, std::string(_chm_data.begin(), _chm_data.end())});
auto chm = translation_map.find(_chm_key);
std::string chm_key = std::string(S_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
auto _chm_key = std::tuple{kv1.first, kv2.first, std::string(ST_CHANNEL_INPUT)};
_translation_map.insert({_chm_key, std::string(_chm_data.begin(), _chm_data.end())});
auto chm = _translation_map.find(_chm_key);
std::string chm_key = std::string(ST_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
p = obs_properties_add_float_slider(properties, chm_key.c_str(), chm->second.c_str(), -100.0, 100.0,
0.01);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(S_CHANNEL_INPUT)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CHANNEL_INPUT)));
}
}
}
@ -248,54 +248,54 @@ void filter::dynamic_mask::dynamic_mask_instance::update(obs_data_t* settings)
{
// Update source.
try {
this->input = std::make_shared<obs::source>(obs_data_get_string(settings, S_INPUT));
this->input_capture = std::make_shared<gfx::source_texture>(this->input, self);
this->input->events.rename += std::bind(&filter::dynamic_mask::dynamic_mask_instance::input_renamed, this,
this->_input = std::make_shared<obs::source>(obs_data_get_string(settings, ST_INPUT));
this->_input_capture = std::make_shared<gfx::source_texture>(this->_input, _self);
this->_input->events.rename += std::bind(&filter::dynamic_mask::dynamic_mask_instance::input_renamed, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
} catch (...) {
this->input.reset();
this->input_capture.reset();
this->input_texture.reset();
this->_input.reset();
this->_input_capture.reset();
this->_input_texture.reset();
}
// Update data store
for (auto kv1 : channel_translations) {
auto found = this->channels.find(kv1.first);
if (found == this->channels.end()) {
this->channels.insert({kv1.first, channel_data()});
found = this->channels.find(kv1.first);
if (found == this->channels.end()) {
assert(found != this->channels.end());
throw std::exception("Unable to insert element into data store.");
auto found = this->_channels.find(kv1.first);
if (found == this->_channels.end()) {
this->_channels.insert({kv1.first, channel_data()});
found = this->_channels.find(kv1.first);
if (found == this->_channels.end()) {
assert(found != this->_channels.end());
throw std::exception("Unable to insert element into data _store.");
}
}
std::string chv_key = std::string(S_CHANNEL_VALUE) + "." + kv1.second;
std::string chv_key = std::string(ST_CHANNEL_VALUE) + "." + kv1.second;
found->second.value = static_cast<float_t>(obs_data_get_double(settings, chv_key.c_str()));
this->precalc.base.ptr[static_cast<size_t>(kv1.first)] = found->second.value;
this->_precalc.base.ptr[static_cast<size_t>(kv1.first)] = found->second.value;
std::string chm_key = std::string(S_CHANNEL_MULTIPLIER) + "." + kv1.second;
std::string chm_key = std::string(ST_CHANNEL_MULTIPLIER) + "." + kv1.second;
found->second.scale = static_cast<float_t>(obs_data_get_double(settings, chm_key.c_str()));
this->precalc.scale.ptr[static_cast<size_t>(kv1.first)] = found->second.scale;
this->_precalc.scale.ptr[static_cast<size_t>(kv1.first)] = found->second.scale;
vec4* ch = nullptr;
switch (kv1.first) {
case channel::Red:
ch = &this->precalc.matrix.x;
ch = &this->_precalc.matrix.x;
break;
case channel::Green:
ch = &this->precalc.matrix.y;
ch = &this->_precalc.matrix.y;
break;
case channel::Blue:
ch = &this->precalc.matrix.z;
ch = &this->_precalc.matrix.z;
break;
case channel::Alpha:
ch = &this->precalc.matrix.t;
ch = &this->_precalc.matrix.t;
break;
}
for (auto kv2 : channel_translations) {
std::string ab_key = std::string(S_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
std::string ab_key = std::string(ST_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
found->second.values.ptr[static_cast<size_t>(kv2.first)] =
static_cast<float_t>(obs_data_get_double(settings, ab_key.c_str()));
ch->ptr[static_cast<size_t>(kv2.first)] = found->second.values.ptr[static_cast<size_t>(kv2.first)];
@ -310,29 +310,29 @@ void filter::dynamic_mask::dynamic_mask_instance::load(obs_data_t* settings)
void filter::dynamic_mask::dynamic_mask_instance::save(obs_data_t* settings)
{
if (this->input) {
obs_data_set_string(settings, S_INPUT, obs_source_get_name(this->input->get()));
if (this->_input) {
obs_data_set_string(settings, ST_INPUT, obs_source_get_name(this->_input->get()));
}
for (auto kv1 : channel_translations) {
auto found = this->channels.find(kv1.first);
if (found == this->channels.end()) {
this->channels.insert({kv1.first, channel_data()});
found = this->channels.find(kv1.first);
if (found == this->channels.end()) {
assert(found != this->channels.end());
throw std::exception("Unable to insert element into data store.");
auto found = this->_channels.find(kv1.first);
if (found == this->_channels.end()) {
this->_channels.insert({kv1.first, channel_data()});
found = this->_channels.find(kv1.first);
if (found == this->_channels.end()) {
assert(found != this->_channels.end());
throw std::exception("Unable to insert element into data _store.");
}
}
std::string chv_key = std::string(S_CHANNEL_VALUE) + "." + kv1.second;
std::string chv_key = std::string(ST_CHANNEL_VALUE) + "." + kv1.second;
obs_data_set_double(settings, chv_key.c_str(), static_cast<double_t>(found->second.value));
std::string chm_key = std::string(S_CHANNEL_MULTIPLIER) + "." + kv1.second;
std::string chm_key = std::string(ST_CHANNEL_MULTIPLIER) + "." + kv1.second;
obs_data_set_double(settings, chm_key.c_str(), static_cast<double_t>(found->second.scale));
for (auto kv2 : channel_translations) {
std::string ab_key = std::string(S_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
std::string ab_key = std::string(ST_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
obs_data_set_double(settings, ab_key.c_str(),
static_cast<double_t>(found->second.values.ptr[static_cast<size_t>(kv2.first)]));
}
@ -342,24 +342,24 @@ void filter::dynamic_mask::dynamic_mask_instance::save(obs_data_t* settings)
void filter::dynamic_mask::dynamic_mask_instance::input_renamed(obs::source*, std::string old_name,
std::string new_name)
{
obs_data_t* settings = obs_source_get_settings(self);
obs_data_set_string(settings, S_INPUT, new_name.c_str());
obs_source_update(self, settings);
obs_data_t* settings = obs_source_get_settings(_self);
obs_data_set_string(settings, ST_INPUT, new_name.c_str());
obs_source_update(_self, settings);
}
bool filter::dynamic_mask::dynamic_mask_instance::modified(void*, obs_properties_t* properties, obs_property_t*,
obs_data_t* settings)
{
channel mask = static_cast<channel>(obs_data_get_int(settings, S_CHANNEL));
channel mask = static_cast<channel>(obs_data_get_int(settings, ST_CHANNEL));
for (auto kv1 : channel_translations) {
std::string chv_key = std::string(S_CHANNEL_VALUE) + "." + kv1.second;
std::string chv_key = std::string(ST_CHANNEL_VALUE) + "." + kv1.second;
obs_property_set_visible(obs_properties_get(properties, chv_key.c_str()), (mask == kv1.first));
std::string chm_key = std::string(S_CHANNEL_MULTIPLIER) + "." + kv1.second;
std::string chm_key = std::string(ST_CHANNEL_MULTIPLIER) + "." + kv1.second;
obs_property_set_visible(obs_properties_get(properties, chm_key.c_str()), (mask == kv1.first));
for (auto kv2 : channel_translations) {
std::string io_key = std::string(S_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
std::string io_key = std::string(ST_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
obs_property_set_visible(obs_properties_get(properties, io_key.c_str()), (mask == kv1.first));
}
}
@ -369,32 +369,32 @@ bool filter::dynamic_mask::dynamic_mask_instance::modified(void*, obs_properties
void filter::dynamic_mask::dynamic_mask_instance::video_tick(float)
{
have_input_texture = false;
have_filter_texture = false;
have_final_texture = false;
_have_input_texture = false;
_have_filter_texture = false;
_have_final_texture = false;
}
void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_effect)
{
obs_source_t* parent = obs_filter_get_parent(this->self);
obs_source_t* target = obs_filter_get_target(this->self);
obs_source_t* parent = obs_filter_get_parent(this->_self);
obs_source_t* target = obs_filter_get_target(this->_self);
uint32_t width = obs_source_get_base_width(target);
uint32_t height = obs_source_get_base_height(target);
if (!self || !parent || !target || !width || !height || !input || !input_capture || !effect) {
obs_source_skip_video_filter(self);
if (!_self || !parent || !target || !width || !height || !_input || !_input_capture || !_effect) {
obs_source_skip_video_filter(_self);
return;
} else if (!input->width() || !input->height()) {
obs_source_skip_video_filter(self);
} else if (!_input->width() || !_input->height()) {
obs_source_skip_video_filter(_self);
return;
}
gs_effect_t* default_effect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
try { // Capture filter and input
if (!have_filter_texture) {
if (obs_source_process_filter_begin(this->self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
auto op = this->filter_rt->render(width, height);
if (!_have_filter_texture) {
if (obs_source_process_filter_begin(this->_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
auto op = this->_filter_rt->render(width, height);
gs_blend_state_push();
gs_reset_blend_state();
@ -413,26 +413,26 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
obs_source_process_filter_end(this->self, default_effect, width, height);
obs_source_process_filter_end(this->_self, default_effect, width, height);
gs_blend_state_pop();
} else {
throw std::exception("Failed to render filter.");
}
this->filter_texture = this->filter_rt->get_texture();
this->have_filter_texture = true;
this->_filter_texture = this->_filter_rt->get_texture();
this->_have_filter_texture = true;
}
if (!have_input_texture) {
this->input_texture = this->input_capture->render(input->width(), input->height());
this->have_input_texture = true;
if (!_have_input_texture) {
this->_input_texture = this->_input_capture->render(_input->width(), _input->height());
this->_have_input_texture = true;
}
// Draw source
if (!this->have_final_texture) {
if (!this->_have_final_texture) {
{
auto op = this->final_rt->render(width, height);
auto op = this->_final_rt->render(width, height);
gs_blend_state_push();
gs_reset_blend_state();
@ -451,34 +451,34 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
this->effect->get_parameter("pMaskInputA").set_texture(this->filter_texture);
this->effect->get_parameter("pMaskInputB").set_texture(this->input_texture);
this->_effect->get_parameter("pMaskInputA").set_texture(this->_filter_texture);
this->_effect->get_parameter("pMaskInputB").set_texture(this->_input_texture);
this->effect->get_parameter("pMaskBase").set_float4(this->precalc.base);
this->effect->get_parameter("pMaskMatrix").set_matrix(this->precalc.matrix);
this->effect->get_parameter("pMaskMultiplier").set_float4(this->precalc.scale);
this->_effect->get_parameter("pMaskBase").set_float4(this->_precalc.base);
this->_effect->get_parameter("pMaskMatrix").set_matrix(this->_precalc.matrix);
this->_effect->get_parameter("pMaskMultiplier").set_float4(this->_precalc.scale);
while (gs_effect_loop(this->effect->get_object(), "Mask")) {
while (gs_effect_loop(this->_effect->get_object(), "Mask")) {
gs_draw_sprite(0, 0, width, height);
}
gs_blend_state_pop();
}
this->final_texture = this->final_rt->get_texture();
this->have_final_texture = true;
this->_final_texture = this->_final_rt->get_texture();
this->_have_final_texture = true;
}
} catch (...) {
obs_source_skip_video_filter(this->self);
obs_source_skip_video_filter(this->_self);
return;
}
if (!have_filter_texture || !have_input_texture || !have_final_texture) {
obs_source_skip_video_filter(this->self);
if (!_have_filter_texture || !_have_input_texture || !_have_final_texture) {
obs_source_skip_video_filter(this->_self);
return;
}
if (!this->filter_texture->get_object() || !this->input_texture->get_object() || !this->final_texture->get_object()) {
obs_source_skip_video_filter(this->self);
if (!this->_filter_texture->get_object() || !this->_input_texture->get_object() || !this->_final_texture->get_object()) {
obs_source_skip_video_filter(this->_self);
return;
}
@ -497,11 +497,11 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
gs_effect_t* final_effect = in_effect ? in_effect : default_effect;
gs_eparam_t* param = gs_effect_get_param_by_name(final_effect, "image");
if (!param) {
P_LOG_ERROR("<filter-dynamic-mask:%s> Failed to set image param.", obs_source_get_name(this->self));
obs_source_skip_video_filter(this->self);
P_LOG_ERROR("<filter-dynamic-mask:%s> Failed to set image param.", obs_source_get_name(this->_self));
obs_source_skip_video_filter(this->_self);
return;
} else {
gs_effect_set_texture(param, this->final_texture->get_object());
gs_effect_set_texture(param, this->_final_texture->get_object());
}
while (gs_effect_loop(final_effect, "Draw")) {
gs_draw_sprite(0, 0, width, height);

View file

@ -42,7 +42,7 @@ namespace filter {
enum class channel : int8_t { Invalid = -1, Red, Green, Blue, Alpha };
class dynamic_mask_factory {
obs_source_info sourceInfo;
obs_source_info _source_info;
public: // Singleton
static void initialize();
@ -55,37 +55,37 @@ namespace filter {
};
class dynamic_mask_instance {
obs_source_t* self;
obs_source_t* _self;
std::map<std::tuple<channel, channel, std::string>, std::string> translation_map;
std::map<std::tuple<channel, channel, std::string>, std::string> _translation_map;
std::shared_ptr<gs::effect> effect;
std::shared_ptr<gs::effect> _effect;
bool have_filter_texture;
std::shared_ptr<gs::rendertarget> filter_rt;
std::shared_ptr<gs::texture> filter_texture;
bool _have_filter_texture;
std::shared_ptr<gs::rendertarget> _filter_rt;
std::shared_ptr<gs::texture> _filter_texture;
bool have_input_texture;
std::shared_ptr<obs::source> input;
std::shared_ptr<gfx::source_texture> input_capture;
std::shared_ptr<gs::texture> input_texture;
bool _have_input_texture;
std::shared_ptr<obs::source> _input;
std::shared_ptr<gfx::source_texture> _input_capture;
std::shared_ptr<gs::texture> _input_texture;
bool have_final_texture;
std::shared_ptr<gs::rendertarget> final_rt;
std::shared_ptr<gs::texture> final_texture;
bool _have_final_texture;
std::shared_ptr<gs::rendertarget> _final_rt;
std::shared_ptr<gs::texture> _final_texture;
struct channel_data {
float_t value = 0.0;
float_t scale = 1.0;
vec4 values = {0};
};
std::map<channel, channel_data> channels;
std::map<channel, channel_data> _channels;
struct _precalc {
vec4 base;
vec4 scale;
matrix4 matrix;
} precalc;
} _precalc;
public:
dynamic_mask_instance(obs_data_t* data, obs_source_t* self);

File diff suppressed because it is too large Load diff

View file

@ -41,12 +41,12 @@ namespace filter {
class sdf_effects_instance;
class sdf_effects_factory {
obs_source_info source_info;
obs_source_info _source_info;
std::list<sdf_effects_instance*> sources;
std::list<sdf_effects_instance*> _sources;
std::shared_ptr<gs::effect> sdf_producer_effect;
std::shared_ptr<gs::effect> sdf_consumer_effect;
std::shared_ptr<gs::effect> _sdf_producer_effect;
std::shared_ptr<gs::effect> _sdf_consumer_effect;
public: // Singleton
static void initialize();
@ -83,56 +83,57 @@ namespace filter {
};
class sdf_effects_instance {
obs_source_t* m_self;
obs_source_t* _self;
// Input
std::shared_ptr<gs::rendertarget> m_source_rt;
std::shared_ptr<gs::texture> m_source_texture;
bool m_source_rendered;
std::shared_ptr<gs::rendertarget> _source_rt;
std::shared_ptr<gs::texture> _source_texture;
bool _source_rendered;
// Distance Field
std::shared_ptr<gs::rendertarget> m_sdf_write, m_sdf_read;
std::shared_ptr<gs::texture> m_sdf_texture;
double_t m_sdf_scale;
float_t m_sdf_threshold;
std::shared_ptr<gs::rendertarget> _sdf_write;
std::shared_ptr<gs::rendertarget> _sdf_read;
std::shared_ptr<gs::texture> _sdf_texture;
double_t _sdf_scale;
float_t _sdf_threshold;
// Effects
bool m_output_rendered;
std::shared_ptr<gs::texture> m_output_texture;
std::shared_ptr<gs::rendertarget> m_output_rt;
bool _output_rendered;
std::shared_ptr<gs::texture> _output_texture;
std::shared_ptr<gs::rendertarget> _output_rt;
/// Inner Shadow
bool m_inner_shadow;
vec4 m_inner_shadow_color;
float_t m_inner_shadow_range_min;
float_t m_inner_shadow_range_max;
float_t m_inner_shadow_offset_x;
float_t m_inner_shadow_offset_y;
bool _inner_shadow;
vec4 _inner_shadow_color;
float_t _inner_shadow_range_min;
float_t _inner_shadow_range_max;
float_t _inner_shadow_offset_x;
float_t _inner_shadow_offset_y;
/// Outer Shadow
bool m_outer_shadow;
vec4 m_outer_shadow_color;
float_t m_outer_shadow_range_min;
float_t m_outer_shadow_range_max;
float_t m_outer_shadow_offset_x;
float_t m_outer_shadow_offset_y;
bool _outer_shadow;
vec4 _outer_shadow_color;
float_t _outer_shadow_range_min;
float_t _outer_shadow_range_max;
float_t _outer_shadow_offset_x;
float_t _outer_shadow_offset_y;
/// Inner Glow
bool m_inner_glow;
vec4 m_inner_glow_color;
float_t m_inner_glow_width;
float_t m_inner_glow_sharpness;
float_t m_inner_glow_sharpness_inv;
bool _inner_glow;
vec4 _inner_glow_color;
float_t _inner_glow_width;
float_t _inner_glow_sharpness;
float_t _inner_glow_sharpness_inv;
/// Outer Glow
bool m_outer_glow;
vec4 m_outer_glow_color;
float_t m_outer_glow_width;
float_t m_outer_glow_sharpness;
float_t m_outer_glow_sharpness_inv;
bool _outer_glow;
vec4 _outer_glow_color;
float_t _outer_glow_width;
float_t _outer_glow_sharpness;
float_t _outer_glow_sharpness_inv;
/// Outline
bool m_outline;
vec4 m_outline_color;
float_t m_outline_width;
float_t m_outline_offset;
float_t m_outline_sharpness;
float_t m_outline_sharpness_inv;
bool _outline;
vec4 _outline_color;
float_t _outline_width;
float_t _outline_offset;
float_t _outline_sharpness;
float_t _outline_sharpness_inv;
static bool cb_modified_shadow_inside(void* ptr, obs_properties_t* props, obs_property* prop,
obs_data_t* settings);

View file

@ -76,10 +76,10 @@ enum RotationOrder : int64_t {
};
// Initializer & Finalizer
INITIALIZER(FilterTransformInit)
P_INITIALIZER(FilterTransformInit)
{
initializerFunctions.push_back([] { filter::transform::transform_factory::initialize(); });
finalizerFunctions.push_back([] { filter::transform::transform_factory::finalize(); });
initializer_functions.push_back([] { filter::transform::transform_factory::initialize(); });
finalizer_functions.push_back([] { filter::transform::transform_factory::finalize(); });
}
static std::shared_ptr<filter::transform::transform_factory> factory_instance = nullptr;
@ -101,30 +101,30 @@ std::shared_ptr<filter::transform::transform_factory> filter::transform::transfo
filter::transform::transform_factory::transform_factory()
{
memset(&sourceInfo, 0, sizeof(obs_source_info));
sourceInfo.id = "obs-stream-effects-filter-transform";
sourceInfo.type = OBS_SOURCE_TYPE_FILTER;
sourceInfo.output_flags = OBS_SOURCE_VIDEO;
sourceInfo.get_name = get_name;
sourceInfo.get_defaults = get_defaults;
sourceInfo.get_properties = get_properties;
memset(&_source_info, 0, sizeof(obs_source_info));
_source_info.id = "obs-stream-effects-filter-transform";
_source_info.type = OBS_SOURCE_TYPE_FILTER;
_source_info.output_flags = OBS_SOURCE_VIDEO;
_source_info.get_name = get_name;
_source_info.get_defaults = get_defaults;
_source_info.get_properties = get_properties;
sourceInfo.create = create;
sourceInfo.destroy = destroy;
sourceInfo.update = update;
sourceInfo.activate = activate;
sourceInfo.deactivate = deactivate;
sourceInfo.video_tick = video_tick;
sourceInfo.video_render = video_render;
_source_info.create = create;
_source_info.destroy = destroy;
_source_info.update = update;
_source_info.activate = activate;
_source_info.deactivate = deactivate;
_source_info.video_tick = video_tick;
_source_info.video_render = video_render;
obs_register_source(&sourceInfo);
obs_register_source(&_source_info);
}
filter::transform::transform_factory::~transform_factory() {}
const char* filter::transform::transform_factory::get_name(void*)
{
return P_TRANSLATE(ST);
return D_TRANSLATE(ST);
}
void filter::transform::transform_factory::get_defaults(obs_data_t* data)
@ -152,95 +152,95 @@ obs_properties_t* filter::transform::transform_factory::get_properties(void*)
// Camera
/// Projection Mode
p = obs_properties_add_list(pr, ST_CAMERA, P_TRANSLATE(ST_CAMERA), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(ST_CAMERA)));
obs_property_list_add_int(p, P_TRANSLATE(ST_CAMERA_ORTHOGRAPHIC), (int64_t)CameraMode::Orthographic);
obs_property_list_add_int(p, P_TRANSLATE(ST_CAMERA_PERSPECTIVE), (int64_t)CameraMode::Perspective);
p = obs_properties_add_list(pr, ST_CAMERA, D_TRANSLATE(ST_CAMERA), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA)));
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_ORTHOGRAPHIC), (int64_t)CameraMode::Orthographic);
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_PERSPECTIVE), (int64_t)CameraMode::Perspective);
obs_property_set_modified_callback(p, modified_properties);
/// Field Of View
p = obs_properties_add_float_slider(pr, ST_CAMERA_FIELDOFVIEW, P_TRANSLATE(ST_CAMERA_FIELDOFVIEW), 1.0, 179.0,
p = obs_properties_add_float_slider(pr, ST_CAMERA_FIELDOFVIEW, D_TRANSLATE(ST_CAMERA_FIELDOFVIEW), 1.0, 179.0,
0.01);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(ST_CAMERA_FIELDOFVIEW)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA_FIELDOFVIEW)));
// Mesh
/// Position
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_POSITION_X, P_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_Y, P_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_Z, P_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_X, D_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_Y, D_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_Z, D_DESC(ST_POSITION)),
};
for (auto kv : entries) {
p = obs_properties_add_float(pr, kv.first, P_TRANSLATE(kv.first), -10000, 10000, 0.01);
obs_property_set_long_description(p, P_TRANSLATE(kv.second));
p = obs_properties_add_float(pr, kv.first, D_TRANSLATE(kv.first), -10000, 10000, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Rotation
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_ROTATION_X, P_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_Y, P_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_Z, P_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_X, D_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_Y, D_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_Z, D_DESC(ST_ROTATION)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, P_TRANSLATE(kv.first), -180, 180, 0.01);
obs_property_set_long_description(p, P_TRANSLATE(kv.second));
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -180, 180, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Scale
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_SCALE_X, P_DESC(ST_SCALE)),
std::make_pair(ST_SCALE_Y, P_DESC(ST_SCALE)),
std::make_pair(ST_SCALE_X, D_DESC(ST_SCALE)),
std::make_pair(ST_SCALE_Y, D_DESC(ST_SCALE)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, P_TRANSLATE(kv.first), -1000, 1000, 0.01);
obs_property_set_long_description(p, P_TRANSLATE(kv.second));
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -1000, 1000, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Shear
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_SHEAR_X, P_DESC(ST_SHEAR)),
std::make_pair(ST_SHEAR_Y, P_DESC(ST_SHEAR)),
std::make_pair(ST_SHEAR_X, D_DESC(ST_SHEAR)),
std::make_pair(ST_SHEAR_Y, D_DESC(ST_SHEAR)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, P_TRANSLATE(kv.first), -100.0, 100.0, 0.01);
obs_property_set_long_description(p, P_TRANSLATE(kv.second));
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -100.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
p = obs_properties_add_bool(pr, S_ADVANCED, P_TRANSLATE(S_ADVANCED));
p = obs_properties_add_bool(pr, S_ADVANCED, D_TRANSLATE(S_ADVANCED));
obs_property_set_modified_callback(p, modified_properties);
p = obs_properties_add_list(pr, ST_ROTATION_ORDER, P_TRANSLATE(ST_ROTATION_ORDER), OBS_COMBO_TYPE_LIST,
p = obs_properties_add_list(pr, ST_ROTATION_ORDER, D_TRANSLATE(ST_ROTATION_ORDER), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(ST_ROTATION_ORDER)));
obs_property_list_add_int(p, P_TRANSLATE(ST_ROTATION_ORDER_XYZ), RotationOrder::XYZ);
obs_property_list_add_int(p, P_TRANSLATE(ST_ROTATION_ORDER_XZY), RotationOrder::XZY);
obs_property_list_add_int(p, P_TRANSLATE(ST_ROTATION_ORDER_YXZ), RotationOrder::YXZ);
obs_property_list_add_int(p, P_TRANSLATE(ST_ROTATION_ORDER_YZX), RotationOrder::YZX);
obs_property_list_add_int(p, P_TRANSLATE(ST_ROTATION_ORDER_ZXY), RotationOrder::ZXY);
obs_property_list_add_int(p, P_TRANSLATE(ST_ROTATION_ORDER_ZYX), RotationOrder::ZYX);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROTATION_ORDER)));
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_XYZ), RotationOrder::XYZ);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_XZY), RotationOrder::XZY);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_YXZ), RotationOrder::YXZ);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_YZX), RotationOrder::YZX);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_ZXY), RotationOrder::ZXY);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_ZYX), RotationOrder::ZYX);
p = obs_properties_add_bool(pr, ST_MIPMAPPING, P_TRANSLATE(ST_MIPMAPPING));
p = obs_properties_add_bool(pr, ST_MIPMAPPING, D_TRANSLATE(ST_MIPMAPPING));
obs_property_set_modified_callback(p, modified_properties);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(ST_MIPMAPPING)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MIPMAPPING)));
p = obs_properties_add_list(pr, S_MIPGENERATOR, P_TRANSLATE(S_MIPGENERATOR), OBS_COMBO_TYPE_LIST,
p = obs_properties_add_list(pr, S_MIPGENERATOR, D_TRANSLATE(S_MIPGENERATOR), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(S_MIPGENERATOR)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_MIPGENERATOR)));
obs_property_list_add_int(p, P_TRANSLATE(S_MIPGENERATOR_POINT), (long long)gs::mipmapper::generator::Point);
obs_property_list_add_int(p, P_TRANSLATE(S_MIPGENERATOR_LINEAR), (long long)gs::mipmapper::generator::Linear);
obs_property_list_add_int(p, P_TRANSLATE(S_MIPGENERATOR_SHARPEN), (long long)gs::mipmapper::generator::Sharpen);
obs_property_list_add_int(p, P_TRANSLATE(S_MIPGENERATOR_SMOOTHEN), (long long)gs::mipmapper::generator::Smoothen);
obs_property_list_add_int(p, P_TRANSLATE(S_MIPGENERATOR_BICUBIC), (long long)gs::mipmapper::generator::Bicubic);
obs_property_list_add_int(p, P_TRANSLATE(S_MIPGENERATOR_LANCZOS), (long long)gs::mipmapper::generator::Lanczos);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_POINT), (long long)gs::mipmapper::generator::Point);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_LINEAR), (long long)gs::mipmapper::generator::Linear);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_SHARPEN), (long long)gs::mipmapper::generator::Sharpen);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_SMOOTHEN), (long long)gs::mipmapper::generator::Smoothen);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_BICUBIC), (long long)gs::mipmapper::generator::Bicubic);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_LANCZOS), (long long)gs::mipmapper::generator::Lanczos);
p = obs_properties_add_float_slider(pr, S_MIPGENERATOR_INTENSITY, P_TRANSLATE(S_MIPGENERATOR_INTENSITY), 0.0,
p = obs_properties_add_float_slider(pr, S_MIPGENERATOR_INTENSITY, D_TRANSLATE(S_MIPGENERATOR_INTENSITY), 0.0,
1000.0, 0.01);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(S_MIPGENERATOR_INTENSITY)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_MIPGENERATOR_INTENSITY)));
return pr;
}
@ -316,34 +316,34 @@ void filter::transform::transform_factory::video_render(void* ptr, gs_effect_t*
filter::transform::transform_instance::~transform_instance()
{
m_shear.reset();
m_scale.reset();
m_rotation.reset();
m_position.reset();
m_vertex_buffer.reset();
m_shape_texture.reset();
m_shape_rendertarget.reset();
m_source_texture.reset();
m_source_rendertarget.reset();
_shear.reset();
_scale.reset();
_rotation.reset();
_position.reset();
_vertex_buffer.reset();
_shape_texture.reset();
_shape_rendertarget.reset();
_source_texture.reset();
_source_rendertarget.reset();
}
filter::transform::transform_instance::transform_instance(obs_data_t* data, obs_source_t* context)
: m_active(true), m_self(context), m_source_rendered(false), m_mipmap_enabled(false), m_mipmap_strength(50.0),
m_mipmap_generator(gs::mipmapper::generator::Linear), m_update_mesh(false), m_rotation_order(RotationOrder::ZXY),
m_camera_orthographic(true), m_camera_fov(90.0)
: _active(true), _self(context), _source_rendered(false), _mipmap_enabled(false), _mipmap_strength(50.0),
_mipmap_generator(gs::mipmapper::generator::Linear), _update_mesh(false), _rotation_order(RotationOrder::ZXY),
_camera_orthographic(true), _camera_fov(90.0)
{
m_source_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
m_shape_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
m_vertex_buffer = std::make_shared<gs::vertex_buffer>(uint32_t(4u), uint8_t(1u));
_source_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_shape_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_vertex_buffer = std::make_shared<gs::vertex_buffer>(uint32_t(4u), uint8_t(1u));
m_position = std::make_unique<util::vec3a>();
m_rotation = std::make_unique<util::vec3a>();
m_scale = std::make_unique<util::vec3a>();
m_shear = std::make_unique<util::vec3a>();
_position = std::make_unique<util::vec3a>();
_rotation = std::make_unique<util::vec3a>();
_scale = std::make_unique<util::vec3a>();
_shear = std::make_unique<util::vec3a>();
vec3_set(m_position.get(), 0, 0, 0);
vec3_set(m_rotation.get(), 0, 0, 0);
vec3_set(m_scale.get(), 1, 1, 1);
vec3_set(_position.get(), 0, 0, 0);
vec3_set(_rotation.get(), 0, 0, 0);
vec3_set(_scale.get(), 1, 1, 1);
update(data);
}
@ -361,40 +361,40 @@ uint32_t filter::transform::transform_instance::get_height()
void filter::transform::transform_instance::update(obs_data_t* data)
{
// Camera
m_camera_orthographic = obs_data_get_int(data, ST_CAMERA) == 0;
m_camera_fov = (float)obs_data_get_double(data, ST_CAMERA_FIELDOFVIEW);
_camera_orthographic = obs_data_get_int(data, ST_CAMERA) == 0;
_camera_fov = (float)obs_data_get_double(data, ST_CAMERA_FIELDOFVIEW);
// Source
m_position->x = static_cast<float_t>(obs_data_get_double(data, ST_POSITION_X) / 100.0);
m_position->y = static_cast<float_t>(obs_data_get_double(data, ST_POSITION_Y) / 100.0);
m_position->z = static_cast<float_t>(obs_data_get_double(data, ST_POSITION_Z) / 100.0);
m_scale->x = static_cast<float_t>(obs_data_get_double(data, ST_SCALE_X) / 100.0);
m_scale->y = static_cast<float_t>(obs_data_get_double(data, ST_SCALE_Y) / 100.0);
m_scale->z = 1.0f;
m_rotation_order = static_cast<uint32_t>(obs_data_get_int(data, ST_ROTATION_ORDER));
m_rotation->x = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_X) / 180.0 * PI);
m_rotation->y = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_Y) / 180.0 * PI);
m_rotation->z = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_Z) / 180.0 * PI);
m_shear->x = static_cast<float_t>(obs_data_get_double(data, ST_SHEAR_X) / 100.0);
m_shear->y = static_cast<float_t>(obs_data_get_double(data, ST_SHEAR_Y) / 100.0);
m_shear->z = 0.0f;
_position->x = static_cast<float_t>(obs_data_get_double(data, ST_POSITION_X) / 100.0);
_position->y = static_cast<float_t>(obs_data_get_double(data, ST_POSITION_Y) / 100.0);
_position->z = static_cast<float_t>(obs_data_get_double(data, ST_POSITION_Z) / 100.0);
_scale->x = static_cast<float_t>(obs_data_get_double(data, ST_SCALE_X) / 100.0);
_scale->y = static_cast<float_t>(obs_data_get_double(data, ST_SCALE_Y) / 100.0);
_scale->z = 1.0f;
_rotation_order = static_cast<uint32_t>(obs_data_get_int(data, ST_ROTATION_ORDER));
_rotation->x = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_X) / 180.0 * S_PI);
_rotation->y = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_Y) / 180.0 * S_PI);
_rotation->z = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_Z) / 180.0 * S_PI);
_shear->x = static_cast<float_t>(obs_data_get_double(data, ST_SHEAR_X) / 100.0);
_shear->y = static_cast<float_t>(obs_data_get_double(data, ST_SHEAR_Y) / 100.0);
_shear->z = 0.0f;
// Mipmapping
m_mipmap_enabled = obs_data_get_bool(data, ST_MIPMAPPING);
m_mipmap_strength = obs_data_get_double(data, S_MIPGENERATOR_INTENSITY);
m_mipmap_generator = static_cast<gs::mipmapper::generator>(obs_data_get_int(data, S_MIPGENERATOR));
_mipmap_enabled = obs_data_get_bool(data, ST_MIPMAPPING);
_mipmap_strength = obs_data_get_double(data, S_MIPGENERATOR_INTENSITY);
_mipmap_generator = static_cast<gs::mipmapper::generator>(obs_data_get_int(data, S_MIPGENERATOR));
m_update_mesh = true;
_update_mesh = true;
}
void filter::transform::transform_instance::activate()
{
m_active = true;
_active = true;
}
void filter::transform::transform_instance::deactivate()
{
m_active = false;
_active = false;
}
void filter::transform::transform_instance::video_tick(float)
@ -403,7 +403,7 @@ void filter::transform::transform_instance::video_tick(float)
uint32_t height = 0;
// Grab parent and target.
obs_source_t* target = obs_filter_get_target(m_self);
obs_source_t* target = obs_filter_get_target(_self);
if (target) {
// Grab width an height of the target source (child filter or source).
width = obs_source_get_base_width(target);
@ -411,16 +411,16 @@ void filter::transform::transform_instance::video_tick(float)
}
// If size mismatch, force an update.
if (width != m_source_size.first) {
m_update_mesh = true;
} else if (height != m_source_size.second) {
m_update_mesh = true;
if (width != _source_size.first) {
_update_mesh = true;
} else if (height != _source_size.second) {
_update_mesh = true;
}
// Update Mesh
if (m_update_mesh) {
m_source_size.first = width;
m_source_size.second = height;
if (_update_mesh) {
_source_size.first = width;
_source_size.second = height;
if (width == 0) {
width = 1;
@ -431,99 +431,99 @@ void filter::transform::transform_instance::video_tick(float)
// Calculate Aspect Ratio
float_t aspectRatioX = float_t(width) / float_t(height);
if (m_camera_orthographic)
if (_camera_orthographic)
aspectRatioX = 1.0;
// Mesh
matrix4 ident;
matrix4_identity(&ident);
switch (m_rotation_order) {
switch (_rotation_order) {
case RotationOrder::XYZ: // XYZ
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
break;
case RotationOrder::XZY: // XZY
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
break;
case RotationOrder::YXZ: // YXZ
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
break;
case RotationOrder::YZX: // YZX
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
break;
case RotationOrder::ZXY: // ZXY
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
break;
case RotationOrder::ZYX: // ZYX
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
break;
}
matrix4_translate3f(&ident, &ident, m_position->x, m_position->y, m_position->z);
matrix4_translate3f(&ident, &ident, _position->x, _position->y, _position->z);
/// Calculate vertex position once only.
float_t p_x = aspectRatioX * m_scale->x;
float_t p_y = 1.0f * m_scale->y;
float_t p_x = aspectRatioX * _scale->x;
float_t p_y = 1.0f * _scale->y;
/// Generate mesh
{
auto vtx = m_vertex_buffer->at(0);
auto vtx = _vertex_buffer->at(0);
*vtx.color = 0xFFFFFFFF;
vec4_set(vtx.uv[0], 0, 0, 0, 0);
vec3_set(vtx.position, -p_x + m_shear->x, -p_y - m_shear->y, 0);
vec3_set(vtx.position, -p_x + _shear->x, -p_y - _shear->y, 0);
vec3_transform(vtx.position, vtx.position, &ident);
}
{
auto vtx = m_vertex_buffer->at(1);
auto vtx = _vertex_buffer->at(1);
*vtx.color = 0xFFFFFFFF;
vec4_set(vtx.uv[0], 1, 0, 0, 0);
vec3_set(vtx.position, p_x + m_shear->x, -p_y + m_shear->y, 0);
vec3_set(vtx.position, p_x + _shear->x, -p_y + _shear->y, 0);
vec3_transform(vtx.position, vtx.position, &ident);
}
{
auto vtx = m_vertex_buffer->at(2);
auto vtx = _vertex_buffer->at(2);
*vtx.color = 0xFFFFFFFF;
vec4_set(vtx.uv[0], 0, 1, 0, 0);
vec3_set(vtx.position, -p_x - m_shear->x, p_y - m_shear->y, 0);
vec3_set(vtx.position, -p_x - _shear->x, p_y - _shear->y, 0);
vec3_transform(vtx.position, vtx.position, &ident);
}
{
auto vtx = m_vertex_buffer->at(3);
auto vtx = _vertex_buffer->at(3);
*vtx.color = 0xFFFFFFFF;
vec4_set(vtx.uv[0], 1, 1, 0, 0);
vec3_set(vtx.position, p_x - m_shear->x, p_y + m_shear->y, 0);
vec3_set(vtx.position, p_x - _shear->x, p_y + _shear->y, 0);
vec3_transform(vtx.position, vtx.position, &ident);
}
m_vertex_buffer->update(true);
m_update_mesh = false;
_vertex_buffer->update(true);
_update_mesh = false;
}
this->m_source_rendered = false;
this->_source_rendered = false;
}
void filter::transform::transform_instance::video_render(gs_effect_t* paramEffect)
{
if (!m_active) {
obs_source_skip_video_filter(m_self);
if (!_active) {
obs_source_skip_video_filter(_self);
return;
}
// Grab parent and target.
obs_source_t* parent = obs_filter_get_parent(m_self);
obs_source_t* target = obs_filter_get_target(m_self);
obs_source_t* parent = obs_filter_get_parent(_self);
obs_source_t* target = obs_filter_get_target(_self);
if (!parent || !target) {
obs_source_skip_video_filter(m_self);
obs_source_skip_video_filter(_self);
return;
}
@ -531,20 +531,20 @@ void filter::transform::transform_instance::video_render(gs_effect_t* paramEffec
uint32_t width = obs_source_get_base_width(target);
uint32_t height = obs_source_get_base_height(target);
if ((width == 0) || (height == 0)) {
obs_source_skip_video_filter(m_self);
obs_source_skip_video_filter(_self);
return;
}
gs_effect_t* default_effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
// Only render if we didn't already render.
if (!this->m_source_rendered) {
if (!this->_source_rendered) {
std::shared_ptr<gs::texture> source_tex;
uint32_t real_width = width;
uint32_t real_height = height;
// If MipMapping is enabled, resize Render Target to be a Power of Two.
if (m_mipmap_enabled) {
if (_mipmap_enabled) {
real_width = uint32_t(pow(2, util::math::get_power_of_two_exponent_ceil(width)));
real_height = uint32_t(pow(2, util::math::get_power_of_two_exponent_ceil(height)));
if ((real_width >= 8192) || (real_height >= 8192)) {
@ -562,7 +562,7 @@ void filter::transform::transform_instance::video_render(gs_effect_t* paramEffec
// Draw previous filters to texture.
try {
auto op = m_source_rendertarget->render(real_width, real_height);
auto op = _source_rendertarget->render(real_width, real_height);
gs_set_cull_mode(GS_NEITHER);
gs_reset_blend_state();
@ -579,20 +579,20 @@ void filter::transform::transform_instance::video_render(gs_effect_t* paramEffec
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0);
/// Render original source
if (obs_source_process_filter_begin(m_self, GS_RGBA, OBS_NO_DIRECT_RENDERING)) {
obs_source_process_filter_end(m_self, paramEffect ? paramEffect : default_effect, width, height);
if (obs_source_process_filter_begin(_self, GS_RGBA, OBS_NO_DIRECT_RENDERING)) {
obs_source_process_filter_end(_self, paramEffect ? paramEffect : default_effect, width, height);
} else {
obs_source_skip_video_filter(m_self);
obs_source_skip_video_filter(_self);
}
} catch (...) {
obs_source_skip_video_filter(m_self);
obs_source_skip_video_filter(_self);
return;
}
m_source_rendertarget->get_texture(source_tex);
_source_rendertarget->get_texture(source_tex);
if (m_mipmap_enabled) {
if ((!m_source_texture) || (m_source_texture->get_width() != real_width)
|| (m_source_texture->get_height() != real_height)) {
if (_mipmap_enabled) {
if ((!_source_texture) || (_source_texture->get_width() != real_width)
|| (_source_texture->get_height() != real_height)) {
size_t mip_levels = 0;
if (util::math::is_power_of_two(real_width) && util::math::is_power_of_two(real_height)) {
size_t w_level = util::math::get_power_of_two_exponent_ceil(real_width);
@ -604,22 +604,22 @@ void filter::transform::transform_instance::video_render(gs_effect_t* paramEffec
}
}
m_source_texture =
_source_texture =
std::make_shared<gs::texture>(real_width, real_height, GS_RGBA, uint32_t(1u + mip_levels), nullptr,
gs::texture::flags::BuildMipMaps);
}
m_mipmapper.rebuild(source_tex, m_source_texture, m_mipmap_generator, float_t(m_mipmap_strength));
_mipmapper.rebuild(source_tex, _source_texture, _mipmap_generator, float_t(_mipmap_strength));
}
// Draw shape to texture
try {
auto op = m_shape_rendertarget->render(width, height);
auto op = _shape_rendertarget->render(width, height);
if (m_camera_orthographic) {
if (_camera_orthographic) {
gs_ortho(-1.0, 1.0, -1.0, 1.0, -farZ, farZ);
} else {
gs_perspective(m_camera_fov, float_t(width) / float_t(height), nearZ, farZ);
gs_perspective(_camera_fov, float_t(width) / float_t(height), nearZ, farZ);
// Fix camera pointing at -Z instead of +Z.
gs_matrix_scale3f(1.0, 1.0, -1.0);
// Move backwards so we can actually see stuff.
@ -637,28 +637,28 @@ void filter::transform::transform_instance::video_render(gs_effect_t* paramEffec
gs_enable_stencil_test(false);
gs_enable_stencil_write(false);
gs_enable_color(true, true, true, true);
gs_load_vertexbuffer(m_vertex_buffer->update(false));
gs_load_vertexbuffer(_vertex_buffer->update(false));
gs_load_indexbuffer(nullptr);
while (gs_effect_loop(default_effect, "Draw")) {
gs_effect_set_texture(gs_effect_get_param_by_name(default_effect, "image"),
m_mipmap_enabled ? m_source_texture->get_object() : source_tex->get_object());
_mipmap_enabled ? _source_texture->get_object() : source_tex->get_object());
gs_draw(GS_TRISTRIP, 0, 4);
}
gs_load_vertexbuffer(nullptr);
} catch (...) {
obs_source_skip_video_filter(m_self);
obs_source_skip_video_filter(_self);
return;
}
m_shape_rendertarget->get_texture(m_shape_texture);
_shape_rendertarget->get_texture(_shape_texture);
this->m_source_rendered = true;
this->_source_rendered = true;
}
// Draw final shape
gs_reset_blend_state();
gs_enable_depth_test(false);
while (gs_effect_loop(default_effect, "Draw")) {
gs_effect_set_texture(gs_effect_get_param_by_name(default_effect, "image"), m_shape_texture->get_object());
gs_draw_sprite(m_shape_texture->get_object(), 0, 0, 0);
gs_effect_set_texture(gs_effect_get_param_by_name(default_effect, "image"), _shape_texture->get_object());
gs_draw_sprite(_shape_texture->get_object(), 0, 0, 0);
}
}

View file

@ -29,7 +29,7 @@
namespace filter {
namespace transform {
class transform_factory {
obs_source_info sourceInfo;
obs_source_info _source_info;
public: // Singleton
static void initialize();
@ -59,37 +59,37 @@ namespace filter {
};
class transform_instance {
bool m_active;
obs_source_t* m_self;
bool _active;
obs_source_t* _self;
// Input
std::shared_ptr<gs::rendertarget> m_source_rendertarget;
std::shared_ptr<gs::texture> m_source_texture;
bool m_source_rendered;
std::pair<uint32_t, uint32_t> m_source_size;
std::shared_ptr<gs::rendertarget> _source_rendertarget;
std::shared_ptr<gs::texture> _source_texture;
bool _source_rendered;
std::pair<uint32_t, uint32_t> _source_size;
// Mipmapping
bool m_mipmap_enabled;
double_t m_mipmap_strength;
gs::mipmapper::generator m_mipmap_generator;
gs::mipmapper m_mipmapper;
bool _mipmap_enabled;
double_t _mipmap_strength;
gs::mipmapper::generator _mipmap_generator;
gs::mipmapper _mipmapper;
// Rendering
std::shared_ptr<gs::rendertarget> m_shape_rendertarget;
std::shared_ptr<gs::texture> m_shape_texture;
std::shared_ptr<gs::rendertarget> _shape_rendertarget;
std::shared_ptr<gs::texture> _shape_texture;
// Mesh
bool m_update_mesh;
std::shared_ptr<gs::vertex_buffer> m_vertex_buffer;
uint32_t m_rotation_order;
std::unique_ptr<util::vec3a> m_position;
std::unique_ptr<util::vec3a> m_rotation;
std::unique_ptr<util::vec3a> m_scale;
std::unique_ptr<util::vec3a> m_shear;
bool _update_mesh;
std::shared_ptr<gs::vertex_buffer> _vertex_buffer;
uint32_t _rotation_order;
std::unique_ptr<util::vec3a> _position;
std::unique_ptr<util::vec3a> _rotation;
std::unique_ptr<util::vec3a> _scale;
std::unique_ptr<util::vec3a> _shear;
// Camera
bool m_camera_orthographic;
float_t m_camera_fov;
bool _camera_orthographic;
float_t _camera_fov;
public:
~transform_instance();

View file

@ -17,48 +17,48 @@
#include "gfx-blur-base.hpp"
void gfx::blur::ibase::set_step_scale_x(double_t v)
void gfx::blur::base::set_step_scale_x(double_t v)
{
this->set_step_scale(v, this->get_step_scale_y());
}
void gfx::blur::ibase::set_step_scale_y(double_t v)
void gfx::blur::base::set_step_scale_y(double_t v)
{
this->set_step_scale(this->get_step_scale_x(), v);
}
double_t gfx::blur::ibase::get_step_scale_x()
double_t gfx::blur::base::get_step_scale_x()
{
double_t x, y;
this->get_step_scale(x, y);
return x;
}
double_t gfx::blur::ibase::get_step_scale_y()
double_t gfx::blur::base::get_step_scale_y()
{
double_t x, y;
this->get_step_scale(x, y);
return y;
}
void gfx::blur::ibase_center::set_center_x(double_t v)
void gfx::blur::base_center::set_center_x(double_t v)
{
this->set_center(v, this->get_center_y());
}
void gfx::blur::ibase_center::set_center_y(double_t v)
void gfx::blur::base_center::set_center_y(double_t v)
{
this->set_center(this->get_center_x(), v);
}
double_t gfx::blur::ibase_center::get_center_x()
double_t gfx::blur::base_center::get_center_x()
{
double_t x, y;
this->get_center(x, y);
return x;
}
double_t gfx::blur::ibase_center::get_center_y()
double_t gfx::blur::base_center::get_center_y()
{
double_t x, y;
this->get_center(x, y);

View file

@ -31,9 +31,9 @@ namespace gfx {
Zoom,
};
class ibase {
class base {
public:
virtual ~ibase() {}
virtual ~base() {}
virtual void set_input(std::shared_ptr<::gs::texture> texture) = 0;
@ -60,18 +60,18 @@ namespace gfx {
virtual std::shared_ptr<::gs::texture> get() = 0;
};
class ibase_angle {
class base_angle {
public:
virtual ~ibase_angle() {}
virtual ~base_angle() {}
virtual double_t get_angle() = 0;
virtual void set_angle(double_t angle) = 0;
};
class ibase_center {
class base_center {
public:
virtual ~ibase_center() {}
virtual ~base_center() {}
virtual void set_center(double_t x, double_t y) = 0;
@ -92,7 +92,7 @@ namespace gfx {
virtual bool is_type_supported(::gfx::blur::type type) = 0;
virtual std::shared_ptr<::gfx::blur::ibase> create(::gfx::blur::type type) = 0;
virtual std::shared_ptr<::gfx::blur::base> create(::gfx::blur::type type) = 0;
virtual double_t get_min_size(::gfx::blur::type type) = 0;

View file

@ -38,23 +38,23 @@ gfx::blur::box_linear_data::box_linear_data()
{
auto gctx = gs::context();
try {
char* file = obs_module_file("effects/blur/box-linear.effect");
m_effect = std::make_shared<::gs::effect>(file);
char* file = obs_module_file("effects/blur/box-linear._effect");
_effect = std::make_shared<::gs::effect>(file);
bfree(file);
} catch (...) {
P_LOG_ERROR("<gfx::blur::box_linear> Failed to load effect.");
P_LOG_ERROR("<gfx::blur::box_linear> Failed to load _effect.");
}
}
gfx::blur::box_linear_data::~box_linear_data()
{
auto gctx = gs::context();
m_effect.reset();
_effect.reset();
}
std::shared_ptr<::gs::effect> gfx::blur::box_linear_data::get_effect()
{
return m_effect;
return _effect;
}
gfx::blur::box_linear_factory::box_linear_factory() {}
@ -73,7 +73,7 @@ bool gfx::blur::box_linear_factory::is_type_supported(::gfx::blur::type type)
}
}
std::shared_ptr<::gfx::blur::ibase> gfx::blur::box_linear_factory::create(::gfx::blur::type type)
std::shared_ptr<::gfx::blur::base> gfx::blur::box_linear_factory::create(::gfx::blur::type type)
{
switch (type) {
case ::gfx::blur::type::Area:
@ -171,11 +171,11 @@ double_t gfx::blur::box_linear_factory::get_max_step_scale_y(::gfx::blur::type)
std::shared_ptr<::gfx::blur::box_linear_data> gfx::blur::box_linear_factory::data()
{
std::unique_lock<std::mutex> ulock(m_data_lock);
std::shared_ptr<::gfx::blur::box_linear_data> data = m_data.lock();
std::unique_lock<std::mutex> ulock(_data_lock);
std::shared_ptr<::gfx::blur::box_linear_data> data = _data.lock();
if (!data) {
data = std::make_shared<::gfx::blur::box_linear_data>();
m_data = data;
_data = data;
}
return data;
}
@ -187,17 +187,17 @@ std::shared_ptr<::gfx::blur::box_linear_data> gfx::blur::box_linear_factory::dat
}
gfx::blur::box_linear::box_linear()
: m_data(::gfx::blur::box_linear_factory::get().data()), m_size(1.), m_step_scale({1., 1.})
: _data(::gfx::blur::box_linear_factory::get().data()), _size(1.), _step_scale({1., 1.})
{
m_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
m_rendertarget2 = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_rendertarget2 = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
}
gfx::blur::box_linear::~box_linear() {}
void gfx::blur::box_linear::set_input(std::shared_ptr<::gs::texture> texture)
{
m_input_texture = texture;
_input_texture = texture;
}
::gfx::blur::type gfx::blur::box_linear::get_type()
@ -207,46 +207,46 @@ void gfx::blur::box_linear::set_input(std::shared_ptr<::gs::texture> texture)
double_t gfx::blur::box_linear::get_size()
{
return m_size;
return _size;
}
void gfx::blur::box_linear::set_size(double_t width)
{
m_size = width;
if (m_size < 1.0) {
m_size = 1.0;
_size = width;
if (_size < 1.0) {
_size = 1.0;
}
if (m_size > MAX_BLUR_SIZE) {
m_size = MAX_BLUR_SIZE;
if (_size > MAX_BLUR_SIZE) {
_size = MAX_BLUR_SIZE;
}
}
void gfx::blur::box_linear::set_step_scale(double_t x, double_t y)
{
m_step_scale = {x, y};
_step_scale = {x, y};
}
void gfx::blur::box_linear::get_step_scale(double_t& x, double_t& y)
{
x = m_step_scale.first;
y = m_step_scale.second;
x = _step_scale.first;
y = _step_scale.second;
}
double_t gfx::blur::box_linear::get_step_scale_x()
{
return m_step_scale.first;
return _step_scale.first;
}
double_t gfx::blur::box_linear::get_step_scale_y()
{
return m_step_scale.second;
return _step_scale.second;
}
std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
{
auto gctx = gs::context();
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
gs_set_cull_mode(GS_NEITHER);
gs_enable_color(true, true, true, true);
@ -262,17 +262,17 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
// Two Pass Blur
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) {
// Pass 1
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f);
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
{
auto op = m_rendertarget2->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -280,11 +280,11 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
}
// Pass 2
effect->get_parameter("pImage").set_texture(m_rendertarget2->get_texture());
effect->get_parameter("pImage").set_texture(_rendertarget2->get_texture());
effect->get_parameter("pImageTexel").set_float2(0., float_t(1.f / height));
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -294,15 +294,15 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
gs_blend_state_pop();
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}
std::shared_ptr<::gs::texture> gfx::blur::box_linear::get()
{
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}
gfx::blur::box_linear_directional::box_linear_directional() : m_angle(0) {}
gfx::blur::box_linear_directional::box_linear_directional() : _angle(0) {}
::gfx::blur::type gfx::blur::box_linear_directional::get_type()
{
@ -311,19 +311,19 @@ gfx::blur::box_linear_directional::box_linear_directional() : m_angle(0) {}
double_t gfx::blur::box_linear_directional::get_angle()
{
return RAD_TO_DEG(m_angle);
return D_RAD_TO_DEG(_angle);
}
void gfx::blur::box_linear_directional::set_angle(double_t angle)
{
m_angle = DEG_TO_RAD(angle);
_angle = D_DEG_TO_RAD(angle);
}
std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render()
{
auto gctx = gs::context();
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
gs_blend_state_push();
gs_reset_blend_state();
@ -339,17 +339,17 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render()
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
// One Pass Blur
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) {
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel")
.set_float2(float_t(1. / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
.set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -359,5 +359,5 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render()
gs_blend_state_pop();
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}

View file

@ -27,7 +27,7 @@
namespace gfx {
namespace blur {
class box_linear_data {
std::shared_ptr<::gs::effect> m_effect;
std::shared_ptr<::gs::effect> _effect;
public:
box_linear_data();
@ -37,8 +37,8 @@ namespace gfx {
};
class box_linear_factory : public ::gfx::blur::ifactory {
std::mutex m_data_lock;
std::weak_ptr<::gfx::blur::box_linear_data> m_data;
std::mutex _data_lock;
std::weak_ptr<::gfx::blur::box_linear_data> _data;
public:
box_linear_factory();
@ -46,7 +46,7 @@ namespace gfx {
virtual bool is_type_supported(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::ibase> create(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::base> create(::gfx::blur::type type) override;
virtual double_t get_min_size(::gfx::blur::type type) override;
@ -80,17 +80,17 @@ namespace gfx {
static ::gfx::blur::box_linear_factory& get();
};
class box_linear : public ::gfx::blur::ibase {
class box_linear : public ::gfx::blur::base {
protected:
std::shared_ptr<::gfx::blur::box_linear_data> m_data;
std::shared_ptr<::gfx::blur::box_linear_data> _data;
double_t m_size;
std::pair<double_t, double_t> m_step_scale;
std::shared_ptr<::gs::texture> m_input_texture;
std::shared_ptr<::gs::rendertarget> m_rendertarget;
double_t _size;
std::pair<double_t, double_t> _step_scale;
std::shared_ptr<::gs::texture> _input_texture;
std::shared_ptr<::gs::rendertarget> _rendertarget;
private:
std::shared_ptr<::gs::rendertarget> m_rendertarget2;
std::shared_ptr<::gs::rendertarget> _rendertarget2;
public:
box_linear();
@ -112,8 +112,8 @@ namespace gfx {
virtual std::shared_ptr<::gs::texture> get() override;
};
class box_linear_directional : public ::gfx::blur::box_linear, public ::gfx::blur::ibase_angle {
double_t m_angle;
class box_linear_directional : public ::gfx::blur::box_linear, public ::gfx::blur::base_angle {
double_t _angle;
public:
box_linear_directional();

View file

@ -38,23 +38,23 @@ gfx::blur::box_data::box_data()
{
auto gctx = gs::context();
try {
char* file = obs_module_file("effects/blur/box.effect");
m_effect = std::make_shared<::gs::effect>(file);
char* file = obs_module_file("effects/blur/box._effect");
_effect = std::make_shared<::gs::effect>(file);
bfree(file);
} catch (...) {
P_LOG_ERROR("<gfx::blur::box> Failed to load effect.");
P_LOG_ERROR("<gfx::blur::box> Failed to load _effect.");
}
}
gfx::blur::box_data::~box_data()
{
auto gctx = gs::context();
m_effect.reset();
_effect.reset();
}
std::shared_ptr<::gs::effect> gfx::blur::box_data::get_effect()
{
return m_effect;
return _effect;
}
gfx::blur::box_factory::box_factory() {}
@ -77,7 +77,7 @@ bool gfx::blur::box_factory::is_type_supported(::gfx::blur::type type)
}
}
std::shared_ptr<::gfx::blur::ibase> gfx::blur::box_factory::create(::gfx::blur::type type)
std::shared_ptr<::gfx::blur::base> gfx::blur::box_factory::create(::gfx::blur::type type)
{
switch (type) {
case ::gfx::blur::type::Area:
@ -179,11 +179,11 @@ double_t gfx::blur::box_factory::get_max_step_scale_y(::gfx::blur::type)
std::shared_ptr<::gfx::blur::box_data> gfx::blur::box_factory::data()
{
std::unique_lock<std::mutex> ulock(m_data_lock);
std::shared_ptr<::gfx::blur::box_data> data = m_data.lock();
std::unique_lock<std::mutex> ulock(_data_lock);
std::shared_ptr<::gfx::blur::box_data> data = _data.lock();
if (!data) {
data = std::make_shared<::gfx::blur::box_data>();
m_data = data;
_data = data;
}
return data;
}
@ -194,18 +194,18 @@ std::shared_ptr<::gfx::blur::box_data> gfx::blur::box_factory::data()
return instance;
}
gfx::blur::box::box() : m_data(::gfx::blur::box_factory::get().data()), m_size(1.), m_step_scale({1., 1.})
gfx::blur::box::box() : _data(::gfx::blur::box_factory::get().data()), _size(1.), _step_scale({1., 1.})
{
auto gctx = gs::context();
m_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
m_rendertarget2 = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_rendertarget2 = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
}
gfx::blur::box::~box() {}
void gfx::blur::box::set_input(std::shared_ptr<::gs::texture> texture)
{
m_input_texture = texture;
_input_texture = texture;
}
::gfx::blur::type gfx::blur::box::get_type()
@ -215,46 +215,46 @@ void gfx::blur::box::set_input(std::shared_ptr<::gs::texture> texture)
double_t gfx::blur::box::get_size()
{
return m_size;
return _size;
}
void gfx::blur::box::set_size(double_t width)
{
m_size = width;
if (m_size < 1.0) {
m_size = 1.0;
_size = width;
if (_size < 1.0) {
_size = 1.0;
}
if (m_size > MAX_BLUR_SIZE) {
m_size = MAX_BLUR_SIZE;
if (_size > MAX_BLUR_SIZE) {
_size = MAX_BLUR_SIZE;
}
}
void gfx::blur::box::set_step_scale(double_t x, double_t y)
{
m_step_scale = {x, y};
_step_scale = {x, y};
}
void gfx::blur::box::get_step_scale(double_t& x, double_t& y)
{
x = m_step_scale.first;
y = m_step_scale.second;
x = _step_scale.first;
y = _step_scale.second;
}
double_t gfx::blur::box::get_step_scale_x()
{
return m_step_scale.first;
return _step_scale.first;
}
double_t gfx::blur::box::get_step_scale_y()
{
return m_step_scale.second;
return _step_scale.second;
}
std::shared_ptr<::gs::texture> gfx::blur::box::render()
{
auto gctx = gs::context();
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
gs_set_cull_mode(GS_NEITHER);
gs_enable_color(true, true, true, true);
@ -270,17 +270,17 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render()
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
// Two Pass Blur
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) {
// Pass 1
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f);
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
{
auto op = m_rendertarget2->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -288,11 +288,11 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render()
}
// Pass 2
effect->get_parameter("pImage").set_texture(m_rendertarget2->get_texture());
effect->get_parameter("pImage").set_texture(_rendertarget2->get_texture());
effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height));
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -302,15 +302,15 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render()
gs_blend_state_pop();
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}
std::shared_ptr<::gs::texture> gfx::blur::box::get()
{
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}
gfx::blur::box_directional::box_directional() : m_angle(0) {}
gfx::blur::box_directional::box_directional() : _angle(0) {}
::gfx::blur::type gfx::blur::box_directional::get_type()
{
@ -319,19 +319,19 @@ gfx::blur::box_directional::box_directional() : m_angle(0) {}
double_t gfx::blur::box_directional::get_angle()
{
return RAD_TO_DEG(m_angle);
return D_RAD_TO_DEG(_angle);
}
void gfx::blur::box_directional::set_angle(double_t angle)
{
m_angle = DEG_TO_RAD(angle);
_angle = D_DEG_TO_RAD(angle);
}
std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
{
auto gctx = gs::context();
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
gs_blend_state_push();
gs_reset_blend_state();
@ -347,17 +347,17 @@ std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
// One Pass Blur
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) {
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel")
.set_float2(float_t(1. / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
.set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -367,7 +367,7 @@ std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
gs_blend_state_pop();
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}
::gfx::blur::type gfx::blur::box_rotational::get_type()
@ -377,31 +377,31 @@ std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
void gfx::blur::box_rotational::set_center(double_t x, double_t y)
{
m_center.first = x;
m_center.second = y;
_center.first = x;
_center.second = y;
}
void gfx::blur::box_rotational::get_center(double_t& x, double_t& y)
{
x = m_center.first;
y = m_center.second;
x = _center.first;
y = _center.second;
}
double_t gfx::blur::box_rotational::get_angle()
{
return RAD_TO_DEG(m_angle);
return D_RAD_TO_DEG(_angle);
}
void gfx::blur::box_rotational::set_angle(double_t angle)
{
m_angle = DEG_TO_RAD(angle);
_angle = D_DEG_TO_RAD(angle);
}
std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
{
auto gctx = gs::context();
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
gs_blend_state_push();
gs_reset_blend_state();
@ -417,18 +417,18 @@ std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
// One Pass Blur
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) {
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height));
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
effect->get_parameter("pAngle").set_float(float_t(m_angle / m_size));
effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
effect->get_parameter("pAngle").set_float(float_t(_angle / _size));
effect->get_parameter("pCenter").set_float2(float_t(_center.first), float_t(_center.second));
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Rotate")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -438,7 +438,7 @@ std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
gs_blend_state_pop();
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}
::gfx::blur::type gfx::blur::box_zoom::get_type()
@ -448,21 +448,21 @@ std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
void gfx::blur::box_zoom::set_center(double_t x, double_t y)
{
m_center.first = x;
m_center.second = y;
_center.first = x;
_center.second = y;
}
void gfx::blur::box_zoom::get_center(double_t& x, double_t& y)
{
x = m_center.first;
y = m_center.second;
x = _center.first;
y = _center.second;
}
std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
{
auto gctx = gs::context();
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
gs_blend_state_push();
gs_reset_blend_state();
@ -478,17 +478,17 @@ std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
// One Pass Blur
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) {
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height));
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
effect->get_parameter("pCenter").set_float2(float_t(_center.first), float_t(_center.second));
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Zoom")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -498,5 +498,5 @@ std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
gs_blend_state_pop();
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}

View file

@ -27,7 +27,7 @@
namespace gfx {
namespace blur {
class box_data {
std::shared_ptr<::gs::effect> m_effect;
std::shared_ptr<::gs::effect> _effect;
public:
box_data();
@ -37,8 +37,8 @@ namespace gfx {
};
class box_factory : public ::gfx::blur::ifactory {
std::mutex m_data_lock;
std::weak_ptr<::gfx::blur::box_data> m_data;
std::mutex _data_lock;
std::weak_ptr<::gfx::blur::box_data> _data;
public:
box_factory();
@ -46,7 +46,7 @@ namespace gfx {
virtual bool is_type_supported(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::ibase> create(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::base> create(::gfx::blur::type type) override;
virtual double_t get_min_size(::gfx::blur::type type) override;
@ -80,17 +80,17 @@ namespace gfx {
static ::gfx::blur::box_factory& get();
};
class box : public ::gfx::blur::ibase {
class box : public ::gfx::blur::base {
protected:
std::shared_ptr<::gfx::blur::box_data> m_data;
std::shared_ptr<::gfx::blur::box_data> _data;
double_t m_size;
std::pair<double_t, double_t> m_step_scale;
std::shared_ptr<::gs::texture> m_input_texture;
std::shared_ptr<::gs::rendertarget> m_rendertarget;
double_t _size;
std::pair<double_t, double_t> _step_scale;
std::shared_ptr<::gs::texture> _input_texture;
std::shared_ptr<::gs::rendertarget> _rendertarget;
private:
std::shared_ptr<::gs::rendertarget> m_rendertarget2;
std::shared_ptr<::gs::rendertarget> _rendertarget2;
public:
box();
@ -112,8 +112,8 @@ namespace gfx {
virtual std::shared_ptr<::gs::texture> get() override;
};
class box_directional : public ::gfx::blur::box, public ::gfx::blur::ibase_angle {
double_t m_angle;
class box_directional : public ::gfx::blur::box, public ::gfx::blur::base_angle {
double_t _angle;
public:
box_directional();
@ -127,10 +127,10 @@ namespace gfx {
};
class box_rotational : public ::gfx::blur::box,
public ::gfx::blur::ibase_angle,
public ::gfx::blur::ibase_center {
std::pair<double_t, double_t> m_center;
double_t m_angle;
public ::gfx::blur::base_angle,
public ::gfx::blur::base_center {
std::pair<double_t, double_t> _center;
double_t _angle;
public:
virtual ::gfx::blur::type get_type() override;
@ -144,8 +144,8 @@ namespace gfx {
virtual std::shared_ptr<::gs::texture> render() override;
};
class box_zoom : public ::gfx::blur::box, public ::gfx::blur::ibase_center {
std::pair<double_t, double_t> m_center;
class box_zoom : public ::gfx::blur::box, public ::gfx::blur::base_center {
std::pair<double_t, double_t> _center;
public:
virtual ::gfx::blur::type get_type() override;

View file

@ -54,23 +54,23 @@ gfx::blur::dual_filtering_data::dual_filtering_data()
{
auto gctx = gs::context();
try {
char* file = obs_module_file("effects/blur/dual-filtering.effect");
m_effect = std::make_shared<::gs::effect>(file);
char* file = obs_module_file("effects/blur/dual-filtering._effect");
_effect = std::make_shared<::gs::effect>(file);
bfree(file);
} catch (...) {
P_LOG_ERROR("<gfx::blur::box_linear> Failed to load effect.");
P_LOG_ERROR("<gfx::blur::box_linear> Failed to load _effect.");
}
}
gfx::blur::dual_filtering_data::~dual_filtering_data()
{
auto gctx = gs::context();
m_effect.reset();
_effect.reset();
}
std::shared_ptr<::gs::effect> gfx::blur::dual_filtering_data::get_effect()
{
return m_effect;
return _effect;
}
gfx::blur::dual_filtering_factory::dual_filtering_factory() {}
@ -87,7 +87,7 @@ bool gfx::blur::dual_filtering_factory::is_type_supported(::gfx::blur::type type
}
}
std::shared_ptr<::gfx::blur::ibase> gfx::blur::dual_filtering_factory::create(::gfx::blur::type type)
std::shared_ptr<::gfx::blur::base> gfx::blur::dual_filtering_factory::create(::gfx::blur::type type)
{
switch (type) {
case ::gfx::blur::type::Area:
@ -164,11 +164,11 @@ double_t gfx::blur::dual_filtering_factory::get_max_step_scale_y(::gfx::blur::ty
std::shared_ptr<::gfx::blur::dual_filtering_data> gfx::blur::dual_filtering_factory::data()
{
std::unique_lock<std::mutex> ulock(m_data_lock);
std::shared_ptr<::gfx::blur::dual_filtering_data> data = m_data.lock();
std::unique_lock<std::mutex> ulock(_data_lock);
std::shared_ptr<::gfx::blur::dual_filtering_data> data = _data.lock();
if (!data) {
data = std::make_shared<::gfx::blur::dual_filtering_data>();
m_data = data;
_data = data;
}
return data;
}
@ -180,12 +180,12 @@ std::shared_ptr<::gfx::blur::dual_filtering_data> gfx::blur::dual_filtering_fact
}
gfx::blur::dual_filtering::dual_filtering()
: m_data(::gfx::blur::dual_filtering_factory::get().data()), m_size(0), m_size_iterations(0)
: _data(::gfx::blur::dual_filtering_factory::get().data()), _size(0), _size_iterations(0)
{
auto gctx = gs::context();
m_rendertargets.resize(MAX_LEVELS + 1);
_rendertargets.resize(MAX_LEVELS + 1);
for (size_t n = 0; n <= MAX_LEVELS; n++) {
m_rendertargets[n] = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
_rendertargets[n] = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
}
}
@ -193,7 +193,7 @@ gfx::blur::dual_filtering::~dual_filtering() {}
void gfx::blur::dual_filtering::set_input(std::shared_ptr<::gs::texture> texture)
{
m_input_texture = texture;
_input_texture = texture;
}
::gfx::blur::type gfx::blur::dual_filtering::get_type()
@ -203,15 +203,15 @@ void gfx::blur::dual_filtering::set_input(std::shared_ptr<::gs::texture> texture
double_t gfx::blur::dual_filtering::get_size()
{
return m_size;
return _size;
}
void gfx::blur::dual_filtering::set_size(double_t width)
{
m_size = width;
m_size_iterations = size_t(round(width));
if (m_size_iterations >= MAX_LEVELS) {
m_size_iterations = MAX_LEVELS;
_size = width;
_size_iterations = size_t(round(width));
if (_size_iterations >= MAX_LEVELS) {
_size_iterations = MAX_LEVELS;
}
}
@ -222,12 +222,12 @@ void gfx::blur::dual_filtering::get_step_scale(double_t&, double_t&) {}
std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
{
auto gctx = gs::context();
auto effect = m_data->get_effect();
auto effect = _data->get_effect();
if (!effect) {
return m_input_texture;
return _input_texture;
}
size_t actual_iterations = m_size_iterations;
size_t actual_iterations = _size_iterations;
gs_blend_state_push();
gs_reset_blend_state();
@ -249,9 +249,9 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
// Select Texture
std::shared_ptr<gs::texture> tex_cur;
if (n > 1) {
tex_cur = m_rendertargets[n - 1]->get_texture();
tex_cur = _rendertargets[n - 1]->get_texture();
} else {
tex_cur = m_input_texture;
tex_cur = _input_texture;
}
// Reduce Size
@ -269,7 +269,7 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
effect->get_parameter("pImageHalfTexel").set_float2(0.5f / width, 0.5f / height);
{
auto op = m_rendertargets[n]->render(width, height);
auto op = _rendertargets[n]->render(width, height);
gs_ortho(0., 1., 0., 1., 0., 1.);
while (gs_effect_loop(effect->get_object(), "Down")) {
gs_draw_sprite(tex_cur->get_object(), 0, 1, 1);
@ -280,7 +280,7 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
// Upsample
for (size_t n = actual_iterations; n > 0; n--) {
// Select Texture
std::shared_ptr<gs::texture> tex_cur = m_rendertargets[n]->get_texture();
std::shared_ptr<gs::texture> tex_cur = _rendertargets[n]->get_texture();
// Get Size
uint32_t width = tex_cur->get_width();
@ -297,7 +297,7 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
height *= 2;
{
auto op = m_rendertargets[n - 1]->render(width, height);
auto op = _rendertargets[n - 1]->render(width, height);
gs_ortho(0., 1., 0., 1., 0., 1.);
while (gs_effect_loop(effect->get_object(), "Up")) {
gs_draw_sprite(tex_cur->get_object(), 0, 1, 1);
@ -307,10 +307,10 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
gs_blend_state_pop();
return m_rendertargets[0]->get_texture();
return _rendertargets[0]->get_texture();
}
std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::get()
{
return m_rendertargets[0]->get_texture();
return _rendertargets[0]->get_texture();
}

View file

@ -28,7 +28,7 @@
namespace gfx {
namespace blur {
class dual_filtering_data {
std::shared_ptr<::gs::effect> m_effect;
std::shared_ptr<::gs::effect> _effect;
public:
dual_filtering_data();
@ -38,8 +38,8 @@ namespace gfx {
};
class dual_filtering_factory : public ::gfx::blur::ifactory {
std::mutex m_data_lock;
std::weak_ptr<::gfx::blur::dual_filtering_data> m_data;
std::mutex _data_lock;
std::weak_ptr<::gfx::blur::dual_filtering_data> _data;
public:
dual_filtering_factory();
@ -47,7 +47,7 @@ namespace gfx {
virtual bool is_type_supported(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::ibase> create(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::base> create(::gfx::blur::type type) override;
virtual double_t get_min_size(::gfx::blur::type type) override;
@ -81,15 +81,15 @@ namespace gfx {
static ::gfx::blur::dual_filtering_factory& get();
};
class dual_filtering : public ::gfx::blur::ibase {
std::shared_ptr<::gfx::blur::dual_filtering_data> m_data;
class dual_filtering : public ::gfx::blur::base {
std::shared_ptr<::gfx::blur::dual_filtering_data> _data;
double_t m_size;
size_t m_size_iterations;
double_t _size;
size_t _size_iterations;
std::shared_ptr<gs::texture> m_input_texture;
std::shared_ptr<gs::texture> _input_texture;
std::vector<std::shared_ptr<gs::rendertarget>> m_rendertargets;
std::vector<std::shared_ptr<gs::rendertarget>> _rendertargets;
public:
dual_filtering();

View file

@ -45,8 +45,8 @@ gfx::blur::gaussian_linear_data::gaussian_linear_data()
auto gctx = gs::context();
{
char* file = obs_module_file("effects/blur/gaussian-linear.effect");
m_effect = std::make_shared<gs::effect>(file);
char* file = obs_module_file("effects/blur/gaussian-linear._effect");
_effect = std::make_shared<gs::effect>(file);
bfree(file);
}
@ -77,18 +77,18 @@ gfx::blur::gaussian_linear_data::gaussian_linear_data()
kernel_data.at(p) = float_t(kernel_math[p] * inverse_sum);
}
m_kernels.push_back(std::move(kernel_data));
_kernels.push_back(std::move(kernel_data));
}
}
gfx::blur::gaussian_linear_data::~gaussian_linear_data()
{
m_effect.reset();
_effect.reset();
}
std::shared_ptr<::gs::effect> gfx::blur::gaussian_linear_data::get_effect()
{
return m_effect;
return _effect;
}
std::vector<float_t> const& gfx::blur::gaussian_linear_data::get_kernel(size_t width)
@ -98,7 +98,7 @@ std::vector<float_t> const& gfx::blur::gaussian_linear_data::get_kernel(size_t w
if (width > MAX_BLUR_SIZE)
width = MAX_BLUR_SIZE;
width -= 1;
return m_kernels[width];
return _kernels[width];
}
gfx::blur::gaussian_linear_factory::gaussian_linear_factory() {}
@ -117,7 +117,7 @@ bool gfx::blur::gaussian_linear_factory::is_type_supported(::gfx::blur::type v)
}
}
std::shared_ptr<::gfx::blur::ibase> gfx::blur::gaussian_linear_factory::create(::gfx::blur::type v)
std::shared_ptr<::gfx::blur::base> gfx::blur::gaussian_linear_factory::create(::gfx::blur::type v)
{
switch (v) {
case ::gfx::blur::type::Area:
@ -216,11 +216,11 @@ double_t gfx::blur::gaussian_linear_factory::get_max_step_scale_y(::gfx::blur::t
std::shared_ptr<::gfx::blur::gaussian_linear_data> gfx::blur::gaussian_linear_factory::data()
{
std::unique_lock<std::mutex> ulock(m_data_lock);
std::shared_ptr<::gfx::blur::gaussian_linear_data> data = m_data.lock();
std::unique_lock<std::mutex> ulock(_data_lock);
std::shared_ptr<::gfx::blur::gaussian_linear_data> data = _data.lock();
if (!data) {
data = std::make_shared<::gfx::blur::gaussian_linear_data>();
m_data = data;
_data = data;
}
return data;
}
@ -232,19 +232,19 @@ std::shared_ptr<::gfx::blur::gaussian_linear_data> gfx::blur::gaussian_linear_fa
}
gfx::blur::gaussian_linear::gaussian_linear()
: m_data(::gfx::blur::gaussian_linear_factory::get().data()), m_size(1.), m_step_scale({1., 1.})
: _data(::gfx::blur::gaussian_linear_factory::get().data()), _size(1.), _step_scale({1., 1.})
{
auto gctx = gs::context();
m_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
m_rendertarget2 = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_rendertarget2 = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
}
gfx::blur::gaussian_linear::~gaussian_linear() {}
void gfx::blur::gaussian_linear::set_input(std::shared_ptr<::gs::texture> texture)
{
m_input_texture = texture;
_input_texture = texture;
}
::gfx::blur::type gfx::blur::gaussian_linear::get_type()
@ -254,7 +254,7 @@ void gfx::blur::gaussian_linear::set_input(std::shared_ptr<::gs::texture> textur
double_t gfx::blur::gaussian_linear::get_size()
{
return m_size;
return _size;
}
void gfx::blur::gaussian_linear::set_size(double_t width)
@ -263,44 +263,44 @@ void gfx::blur::gaussian_linear::set_size(double_t width)
width = 1.;
if (width > MAX_BLUR_SIZE)
width = MAX_BLUR_SIZE;
m_size = width;
_size = width;
}
void gfx::blur::gaussian_linear::set_step_scale(double_t x, double_t y)
{
m_step_scale.first = x;
m_step_scale.second = y;
_step_scale.first = x;
_step_scale.second = y;
}
void gfx::blur::gaussian_linear::get_step_scale(double_t& x, double_t& y)
{
x = m_step_scale.first;
y = m_step_scale.second;
x = _step_scale.first;
y = _step_scale.second;
}
double_t gfx::blur::gaussian_linear::get_step_scale_x()
{
return m_step_scale.first;
return _step_scale.first;
}
double_t gfx::blur::gaussian_linear::get_step_scale_y()
{
return m_step_scale.second;
return _step_scale.second;
}
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
{
auto gctx = gs::context();
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
auto kernel = m_data->get_kernel(size_t(m_size));
std::shared_ptr<::gs::effect> effect = _data->get_effect();
auto kernel = _data->get_kernel(size_t(_size));
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return m_input_texture;
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return _input_texture;
}
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
// Setup
gs_set_cull_mode(GS_NEITHER);
@ -316,40 +316,40 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass
if (m_step_scale.first > std::numeric_limits<double_t>::epsilon()) {
if (_step_scale.first > std::numeric_limits<double_t>::epsilon()) {
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f);
{
auto op = m_rendertarget2->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
}
}
std::swap(m_rendertarget, m_rendertarget2);
effect->get_parameter("pImage").set_texture(m_rendertarget->get_texture());
std::swap(_rendertarget, _rendertarget2);
effect->get_parameter("pImage").set_texture(_rendertarget->get_texture());
}
// Second Pass
if (m_step_scale.second > std::numeric_limits<double_t>::epsilon()) {
if (_step_scale.second > std::numeric_limits<double_t>::epsilon()) {
effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height));
{
auto op = m_rendertarget2->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
}
}
std::swap(m_rendertarget, m_rendertarget2);
std::swap(_rendertarget, _rendertarget2);
}
gs_blend_state_pop();
@ -359,10 +359,10 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::get()
{
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}
gfx::blur::gaussian_linear_directional::gaussian_linear_directional() : m_angle(0.) {}
gfx::blur::gaussian_linear_directional::gaussian_linear_directional() : _angle(0.) {}
gfx::blur::gaussian_linear_directional::~gaussian_linear_directional() {}
@ -373,27 +373,27 @@ gfx::blur::gaussian_linear_directional::~gaussian_linear_directional() {}
double_t gfx::blur::gaussian_linear_directional::get_angle()
{
return RAD_TO_DEG(m_angle);
return D_RAD_TO_DEG(_angle);
}
void gfx::blur::gaussian_linear_directional::set_angle(double_t angle)
{
m_angle = DEG_TO_RAD(angle);
_angle = D_DEG_TO_RAD(angle);
}
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render()
{
auto gctx = gs::context();
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
auto kernel = m_data->get_kernel(size_t(m_size));
std::shared_ptr<::gs::effect> effect = _data->get_effect();
auto kernel = _data->get_kernel(size_t(_size));
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return m_input_texture;
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return _input_texture;
}
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
// Setup
gs_set_cull_mode(GS_NEITHER);
@ -409,16 +409,16 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel")
.set_float2(float_t(1.f / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
.set_float2(float_t(1.f / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);

View file

@ -26,8 +26,8 @@
namespace gfx {
namespace blur {
class gaussian_linear_data {
std::shared_ptr<::gs::effect> m_effect;
std::vector<std::vector<float_t>> m_kernels;
std::shared_ptr<::gs::effect> _effect;
std::vector<std::vector<float_t>> _kernels;
public:
gaussian_linear_data();
@ -39,8 +39,8 @@ namespace gfx {
};
class gaussian_linear_factory : public ::gfx::blur::ifactory {
std::mutex m_data_lock;
std::weak_ptr<::gfx::blur::gaussian_linear_data> m_data;
std::mutex _data_lock;
std::weak_ptr<::gfx::blur::gaussian_linear_data> _data;
public:
gaussian_linear_factory();
@ -48,7 +48,7 @@ namespace gfx {
virtual bool is_type_supported(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::ibase> create(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::base> create(::gfx::blur::type type) override;
virtual double_t get_min_size(::gfx::blur::type type) override;
@ -82,17 +82,17 @@ namespace gfx {
static ::gfx::blur::gaussian_linear_factory& get();
};
class gaussian_linear : public ::gfx::blur::ibase {
class gaussian_linear : public ::gfx::blur::base {
protected:
std::shared_ptr<::gfx::blur::gaussian_linear_data> m_data;
std::shared_ptr<::gfx::blur::gaussian_linear_data> _data;
double_t m_size;
std::pair<double_t, double_t> m_step_scale;
std::shared_ptr<::gs::texture> m_input_texture;
std::shared_ptr<::gs::rendertarget> m_rendertarget;
double_t _size;
std::pair<double_t, double_t> _step_scale;
std::shared_ptr<::gs::texture> _input_texture;
std::shared_ptr<::gs::rendertarget> _rendertarget;
private:
std::shared_ptr<::gs::rendertarget> m_rendertarget2;
std::shared_ptr<::gs::rendertarget> _rendertarget2;
public:
gaussian_linear();
@ -119,8 +119,8 @@ namespace gfx {
virtual std::shared_ptr<::gs::texture> get() override;
};
class gaussian_linear_directional : public ::gfx::blur::gaussian_linear, public ::gfx::blur::ibase_angle {
double_t m_angle;
class gaussian_linear_directional : public ::gfx::blur::gaussian_linear, public ::gfx::blur::base_angle {
double_t _angle;
public:
gaussian_linear_directional();

View file

@ -45,8 +45,8 @@ gfx::blur::gaussian_data::gaussian_data()
{
auto gctx = gs::context();
{
char* file = obs_module_file("effects/blur/gaussian.effect");
m_effect = std::make_shared<gs::effect>(file);
char* file = obs_module_file("effects/blur/gaussian._effect");
_effect = std::make_shared<gs::effect>(file);
bfree(file);
}
@ -77,19 +77,19 @@ gfx::blur::gaussian_data::gaussian_data()
kernel_data.at(p) = float_t(kernel_math[p] * inverse_sum);
}
m_kernels.push_back(std::move(kernel_data));
_kernels.push_back(std::move(kernel_data));
}
}
gfx::blur::gaussian_data::~gaussian_data()
{
auto gctx = gs::context();
m_effect.reset();
_effect.reset();
}
std::shared_ptr<::gs::effect> gfx::blur::gaussian_data::get_effect()
{
return m_effect;
return _effect;
}
std::vector<float_t> const& gfx::blur::gaussian_data::get_kernel(size_t width)
@ -99,7 +99,7 @@ std::vector<float_t> const& gfx::blur::gaussian_data::get_kernel(size_t width)
if (width > MAX_BLUR_SIZE)
width = MAX_BLUR_SIZE;
width -= 1;
return m_kernels[width];
return _kernels[width];
}
gfx::blur::gaussian_factory::gaussian_factory() {}
@ -122,7 +122,7 @@ bool gfx::blur::gaussian_factory::is_type_supported(::gfx::blur::type v)
}
}
std::shared_ptr<::gfx::blur::ibase> gfx::blur::gaussian_factory::create(::gfx::blur::type v)
std::shared_ptr<::gfx::blur::base> gfx::blur::gaussian_factory::create(::gfx::blur::type v)
{
switch (v) {
case ::gfx::blur::type::Area:
@ -224,11 +224,11 @@ double_t gfx::blur::gaussian_factory::get_max_step_scale_y(::gfx::blur::type)
std::shared_ptr<::gfx::blur::gaussian_data> gfx::blur::gaussian_factory::data()
{
std::unique_lock<std::mutex> ulock(m_data_lock);
std::shared_ptr<::gfx::blur::gaussian_data> data = m_data.lock();
std::unique_lock<std::mutex> ulock(_data_lock);
std::shared_ptr<::gfx::blur::gaussian_data> data = _data.lock();
if (!data) {
data = std::make_shared<::gfx::blur::gaussian_data>();
m_data = data;
_data = data;
}
return data;
}
@ -240,18 +240,18 @@ std::shared_ptr<::gfx::blur::gaussian_data> gfx::blur::gaussian_factory::data()
}
gfx::blur::gaussian::gaussian()
: m_data(::gfx::blur::gaussian_factory::get().data()), m_size(1.), m_step_scale({1., 1.})
: _data(::gfx::blur::gaussian_factory::get().data()), _size(1.), _step_scale({1., 1.})
{
auto gctx = gs::context();
m_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
m_rendertarget2 = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_rendertarget2 = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
}
gfx::blur::gaussian::~gaussian() {}
void gfx::blur::gaussian::set_input(std::shared_ptr<::gs::texture> texture)
{
m_input_texture = texture;
_input_texture = texture;
}
::gfx::blur::type gfx::blur::gaussian::get_type()
@ -261,7 +261,7 @@ void gfx::blur::gaussian::set_input(std::shared_ptr<::gs::texture> texture)
double_t gfx::blur::gaussian::get_size()
{
return m_size;
return _size;
}
void gfx::blur::gaussian::set_size(double_t width)
@ -270,44 +270,44 @@ void gfx::blur::gaussian::set_size(double_t width)
width = 1.;
if (width > MAX_BLUR_SIZE)
width = MAX_BLUR_SIZE;
m_size = width;
_size = width;
}
void gfx::blur::gaussian::set_step_scale(double_t x, double_t y)
{
m_step_scale.first = x;
m_step_scale.second = y;
_step_scale.first = x;
_step_scale.second = y;
}
void gfx::blur::gaussian::get_step_scale(double_t& x, double_t& y)
{
x = m_step_scale.first;
y = m_step_scale.second;
x = _step_scale.first;
y = _step_scale.second;
}
double_t gfx::blur::gaussian::get_step_scale_x()
{
return m_step_scale.first;
return _step_scale.first;
}
double_t gfx::blur::gaussian::get_step_scale_y()
{
return m_step_scale.second;
return _step_scale.second;
}
std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
{
auto gctx = gs::context();
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
auto kernel = m_data->get_kernel(size_t(m_size));
std::shared_ptr<::gs::effect> effect = _data->get_effect();
auto kernel = _data->get_kernel(size_t(_size));
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return m_input_texture;
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return _input_texture;
}
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
// Setup
gs_set_cull_mode(GS_NEITHER);
@ -323,40 +323,40 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass
if (m_step_scale.first > std::numeric_limits<double_t>::epsilon()) {
if (_step_scale.first > std::numeric_limits<double_t>::epsilon()) {
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f);
{
auto op = m_rendertarget2->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
}
}
std::swap(m_rendertarget, m_rendertarget2);
effect->get_parameter("pImage").set_texture(m_rendertarget->get_texture());
std::swap(_rendertarget, _rendertarget2);
effect->get_parameter("pImage").set_texture(_rendertarget->get_texture());
}
// Second Pass
if (m_step_scale.second > std::numeric_limits<double_t>::epsilon()) {
if (_step_scale.second > std::numeric_limits<double_t>::epsilon()) {
effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height));
{
auto op = m_rendertarget2->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
}
}
std::swap(m_rendertarget, m_rendertarget2);
std::swap(_rendertarget, _rendertarget2);
}
gs_blend_state_pop();
@ -366,7 +366,7 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
std::shared_ptr<::gs::texture> gfx::blur::gaussian::get()
{
return m_rendertarget->get_texture();
return _rendertarget->get_texture();
}
gfx::blur::gaussian_directional::gaussian_directional() : m_angle(0.) {}
@ -380,27 +380,27 @@ gfx::blur::gaussian_directional::~gaussian_directional() {}
double_t gfx::blur::gaussian_directional::get_angle()
{
return RAD_TO_DEG(m_angle);
return D_RAD_TO_DEG(m_angle);
}
void gfx::blur::gaussian_directional::set_angle(double_t angle)
{
m_angle = DEG_TO_RAD(angle);
m_angle = D_DEG_TO_RAD(angle);
}
std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render()
{
auto gctx = gs::context();
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
auto kernel = m_data->get_kernel(size_t(m_size));
std::shared_ptr<::gs::effect> effect = _data->get_effect();
auto kernel = _data->get_kernel(size_t(_size));
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return m_input_texture;
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return _input_texture;
}
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
// Setup
obs_enter_graphics();
@ -417,16 +417,16 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel")
.set_float2(float_t(1.f / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -447,15 +447,15 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_rotational::render()
{
auto gctx = gs::context();
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
auto kernel = m_data->get_kernel(size_t(m_size));
std::shared_ptr<::gs::effect> effect = _data->get_effect();
auto kernel = _data->get_kernel(size_t(_size));
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return m_input_texture;
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return _input_texture;
}
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
// Setup
gs_set_cull_mode(GS_NEITHER);
@ -471,17 +471,17 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_rotational::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height));
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pAngle").set_float(float_t(m_angle / m_size));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pAngle").set_float(float_t(m_angle / _size));
effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Rotate")) {
gs_draw_sprite(nullptr, 0, 1, 1);
@ -507,12 +507,12 @@ void gfx::blur::gaussian_rotational::get_center(double_t& x, double_t& y)
double_t gfx::blur::gaussian_rotational::get_angle()
{
return double_t(RAD_TO_DEG(m_angle));
return double_t(D_RAD_TO_DEG(m_angle));
}
void gfx::blur::gaussian_rotational::set_angle(double_t angle)
{
m_angle = DEG_TO_RAD(angle);
m_angle = D_DEG_TO_RAD(angle);
}
::gfx::blur::type gfx::blur::gaussian_zoom::get_type()
@ -524,15 +524,15 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_zoom::render()
{
auto gctx = gs::context();
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
auto kernel = m_data->get_kernel(size_t(m_size));
std::shared_ptr<::gs::effect> effect = _data->get_effect();
auto kernel = _data->get_kernel(size_t(_size));
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return m_input_texture;
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
return _input_texture;
}
float_t width = float_t(m_input_texture->get_width());
float_t height = float_t(m_input_texture->get_height());
float_t width = float_t(_input_texture->get_width());
float_t height = float_t(_input_texture->get_height());
// Setup
gs_set_cull_mode(GS_NEITHER);
@ -548,16 +548,16 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_zoom::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(m_input_texture);
effect->get_parameter("pImage").set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height));
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(m_size));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size));
effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass
{
auto op = m_rendertarget->render(uint32_t(width), uint32_t(height));
auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
gs_ortho(0, 1., 0, 1., 0, 1.);
while (gs_effect_loop(effect->get_object(), "Zoom")) {
gs_draw_sprite(nullptr, 0, 1, 1);

View file

@ -26,8 +26,8 @@
namespace gfx {
namespace blur {
class gaussian_data {
std::shared_ptr<::gs::effect> m_effect;
std::vector<std::vector<float_t>> m_kernels;
std::shared_ptr<::gs::effect> _effect;
std::vector<std::vector<float_t>> _kernels;
public:
gaussian_data();
@ -39,8 +39,8 @@ namespace gfx {
};
class gaussian_factory : public ::gfx::blur::ifactory {
std::mutex m_data_lock;
std::weak_ptr<::gfx::blur::gaussian_data> m_data;
std::mutex _data_lock;
std::weak_ptr<::gfx::blur::gaussian_data> _data;
public:
gaussian_factory();
@ -48,7 +48,7 @@ namespace gfx {
virtual bool is_type_supported(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::ibase> create(::gfx::blur::type type) override;
virtual std::shared_ptr<::gfx::blur::base> create(::gfx::blur::type type) override;
virtual double_t get_min_size(::gfx::blur::type type) override;
@ -82,17 +82,17 @@ namespace gfx {
static ::gfx::blur::gaussian_factory& get();
};
class gaussian : public ::gfx::blur::ibase {
class gaussian : public ::gfx::blur::base {
protected:
std::shared_ptr<::gfx::blur::gaussian_data> m_data;
std::shared_ptr<::gfx::blur::gaussian_data> _data;
double_t m_size;
std::pair<double_t, double_t> m_step_scale;
std::shared_ptr<::gs::texture> m_input_texture;
std::shared_ptr<::gs::rendertarget> m_rendertarget;
double_t _size;
std::pair<double_t, double_t> _step_scale;
std::shared_ptr<::gs::texture> _input_texture;
std::shared_ptr<::gs::rendertarget> _rendertarget;
private:
std::shared_ptr<::gs::rendertarget> m_rendertarget2;
std::shared_ptr<::gs::rendertarget> _rendertarget2;
public:
gaussian();
@ -119,7 +119,7 @@ namespace gfx {
virtual std::shared_ptr<::gs::texture> get() override;
};
class gaussian_directional : public ::gfx::blur::gaussian, public ::gfx::blur::ibase_angle {
class gaussian_directional : public ::gfx::blur::gaussian, public ::gfx::blur::base_angle {
double_t m_angle;
public:
@ -135,8 +135,8 @@ namespace gfx {
};
class gaussian_rotational : public ::gfx::blur::gaussian,
public ::gfx::blur::ibase_angle,
public ::gfx::blur::ibase_center {
public ::gfx::blur::base_angle,
public ::gfx::blur::base_center {
std::pair<double_t, double_t> m_center;
double_t m_angle;
@ -152,7 +152,7 @@ namespace gfx {
virtual std::shared_ptr<::gs::texture> render() override;
};
class gaussian_zoom : public ::gfx::blur::gaussian, public ::gfx::blur::ibase_center {
class gaussian_zoom : public ::gfx::blur::gaussian, public ::gfx::blur::base_center {
std::pair<double_t, double_t> m_center;
public:

View file

@ -133,22 +133,22 @@ void gfx::effect_source::get_properties(obs_properties_t* properties)
{
obs_property_t* p = nullptr;
p = obs_properties_add_list(properties, D_TYPE, P_TRANSLATE(T_TYPE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(T_TYPE)));
obs_property_list_add_int(p, P_TRANSLATE(T_TYPE_TEXT), (long long)InputTypes::Text);
obs_property_list_add_int(p, P_TRANSLATE(T_TYPE_FILE), (long long)InputTypes::File);
p = obs_properties_add_list(properties, D_TYPE, D_TRANSLATE(T_TYPE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(T_TYPE)));
obs_property_list_add_int(p, D_TRANSLATE(T_TYPE_TEXT), (long long)InputTypes::Text);
obs_property_list_add_int(p, D_TRANSLATE(T_TYPE_FILE), (long long)InputTypes::File);
obs_property_set_modified_callback2(p, property_type_modified, this);
p = obs_properties_add_text(properties, D_INPUT_TEXT, P_TRANSLATE(T_INPUT_TEXT), OBS_TEXT_MULTILINE);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(T_INPUT_TEXT)));
p = obs_properties_add_text(properties, D_INPUT_TEXT, D_TRANSLATE(T_INPUT_TEXT), OBS_TEXT_MULTILINE);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(T_INPUT_TEXT)));
obs_property_set_modified_callback2(p, property_input_modified, this);
{
char* tmp_path = obs_module_file(m_defaultShaderPath.c_str());
p = obs_properties_add_path(
properties, D_INPUT_FILE, P_TRANSLATE(T_INPUT_FILE), OBS_PATH_FILE,
"Any (*.effect *.shader *.hlsl);;Effect (*.effect);;Shader (*.shader);;DirectX (*.hlsl)", tmp_path);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(T_INPUT_FILE)));
properties, D_INPUT_FILE, D_TRANSLATE(T_INPUT_FILE), OBS_PATH_FILE,
"Any (*._effect *.shader *.hlsl);;Effect (*._effect);;Shader (*.shader);;DirectX (*.hlsl)", tmp_path);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(T_INPUT_FILE)));
obs_property_set_modified_callback2(p, property_input_modified, this);
bfree(tmp_path);
}
@ -178,10 +178,10 @@ void gfx::effect_source::get_properties(obs_properties_t* properties)
// Switch between File and Source Input
p = obs_properties_add_list(properties, prm.second->ui.names[0], prm.second->ui.descs[0],
obs_combo_type::OBS_COMBO_TYPE_LIST, obs_combo_format::OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(T_TEXTURE_TYPE)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(T_TEXTURE_TYPE)));
obs_property_set_modified_callback2(p, property_texture_type_modified, prm.second.get());
obs_property_list_add_int(p, P_TRANSLATE(T_TEXTURE_TYPE_FILE), 0);
obs_property_list_add_int(p, P_TRANSLATE(T_TEXTURE_TYPE_SOURCE), 1);
obs_property_list_add_int(p, D_TRANSLATE(T_TEXTURE_TYPE_FILE), 0);
obs_property_list_add_int(p, D_TRANSLATE(T_TEXTURE_TYPE_SOURCE), 1);
// Texture Path
char* defaultPath = obs_module_file("");

View file

@ -19,21 +19,21 @@
gfx::source_texture::~source_texture()
{
if (child && parent) {
obs_source_remove_active_child(parent->get(), child->get());
if (_child && _parent) {
obs_source_remove_active_child(_parent->get(), _child->get());
}
parent.reset();
child.reset();
_parent.reset();
_child.reset();
}
gfx::source_texture::source_texture(obs_source_t* _parent)
{
if (!_parent) {
throw std::invalid_argument("parent must not be null");
throw std::invalid_argument("_parent must not be null");
}
parent = std::make_shared<obs::source>(_parent, false, false);
render_target = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
_parent = std::make_shared<obs::source>(_parent, false, false);
_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
}
gfx::source_texture::source_texture(obs_source_t* _source, obs_source_t* _parent) : source_texture(_parent)
@ -42,9 +42,9 @@ gfx::source_texture::source_texture(obs_source_t* _source, obs_source_t* _parent
throw std::invalid_argument("source must not be null");
}
if (!obs_source_add_active_child(_parent, _source)) {
throw std::runtime_error("parent is contained in child");
throw std::runtime_error("_parent is contained in _child");
}
child = std::make_shared<obs::source>(_source, true, true);
_child = std::make_shared<obs::source>(_source, true, true);
}
gfx::source_texture::source_texture(const char* _name, obs_source_t* _parent) : source_texture(_parent)
@ -52,9 +52,9 @@ gfx::source_texture::source_texture(const char* _name, obs_source_t* _parent) :
if (!_name) {
throw std::invalid_argument("name must not be null");
}
child = std::make_shared<obs::source>(_name, true, true);
if (!obs_source_add_active_child(_parent, child->get())) {
throw std::runtime_error("parent is contained in child");
_child = std::make_shared<obs::source>(_name, true, true);
if (!obs_source_add_active_child(_parent, _child->get())) {
throw std::runtime_error("_parent is contained in _child");
}
}
@ -64,17 +64,17 @@ gfx::source_texture::source_texture(std::string _name, obs_source_t* _parent) :
gfx::source_texture::source_texture(std::shared_ptr<obs::source> pchild, std::shared_ptr<obs::source> pparent)
{
if (!pchild) {
throw std::invalid_argument("child must not be null");
throw std::invalid_argument("_child must not be null");
}
if (!pparent) {
throw std::invalid_argument("parent must not be null");
throw std::invalid_argument("_parent must not be null");
}
if (!obs_source_add_active_child(pparent->get(), pchild->get())) {
throw std::runtime_error("parent is contained in child");
throw std::runtime_error("_parent is contained in _child");
}
this->child = pchild;
this->parent = pparent;
this->render_target = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
this->_child = pchild;
this->_parent = pparent;
this->_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
}
gfx::source_texture::source_texture(std::shared_ptr<obs::source> _child, obs_source_t* _parent)
@ -83,24 +83,24 @@ gfx::source_texture::source_texture(std::shared_ptr<obs::source> _child, obs_sou
obs_source_t* gfx::source_texture::get_object()
{
if (child) {
return child->get();
if (_child) {
return _child->get();
}
return nullptr;
}
obs_source_t* gfx::source_texture::get_parent()
{
return parent->get();
return _parent->get();
}
void gfx::source_texture::clear()
{
if (child && parent) {
obs_source_remove_active_child(parent->get(), child->get());
if (_child && _parent) {
obs_source_remove_active_child(_parent->get(), _child->get());
}
child->clear();
child.reset();
_child->clear();
_child.reset();
}
std::shared_ptr<gs::texture> gfx::source_texture::render(size_t width, size_t height)
@ -111,22 +111,22 @@ std::shared_ptr<gs::texture> gfx::source_texture::render(size_t width, size_t he
if ((height == 0) || (height >= 16384)) {
throw std::runtime_error("Height too large or too small.");
}
if (child->destroyed() || parent->destroyed()) {
if (_child->destroyed() || _parent->destroyed()) {
return nullptr;
}
{
auto op = render_target->render((uint32_t)width, (uint32_t)height);
auto op = _rt->render((uint32_t)width, (uint32_t)height);
vec4 black;
vec4_zero(&black);
gs_ortho(0, (float_t)width, 0, (float_t)height, 0, 1);
gs_clear(GS_CLEAR_COLOR, &black, 0, 0);
if (child) {
obs_source_video_render(child->get());
if (_child) {
obs_source_video_render(_child->get());
}
}
std::shared_ptr<gs::texture> tex;
render_target->get_texture(tex);
_rt->get_texture(tex);
return tex;
}

View file

@ -34,10 +34,10 @@
namespace gfx {
class source_texture {
std::shared_ptr<obs::source> parent;
std::shared_ptr<obs::source> child;
std::shared_ptr<obs::source> _parent;
std::shared_ptr<obs::source> _child;
std::shared_ptr<gs::rendertarget> render_target;
std::shared_ptr<gs::rendertarget> _rt;
source_texture(obs_source_t* parent);

View file

@ -36,7 +36,7 @@
//#define OBS_LOAD_EFFECT_FILE
gs::effect::effect() : m_effect(nullptr) {}
gs::effect::effect() : _effect(nullptr) {}
gs::effect::effect(std::string file) : effect()
{
@ -72,8 +72,8 @@ gs::effect::effect(std::string file) : effect()
char* errorMessage = nullptr;
auto gctx = gs::context();
m_effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage);
if (!m_effect || errorMessage) {
_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);
@ -88,8 +88,8 @@ gs::effect::effect(std::string code, std::string name) : effect()
{
char* errorMessage = nullptr;
auto gctx = gs::context();
m_effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage);
if (!m_effect || errorMessage) {
_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);
@ -102,22 +102,22 @@ gs::effect::effect(std::string code, std::string name) : effect()
gs::effect::~effect()
{
auto gctx = gs::context();
gs_effect_destroy(m_effect);
gs_effect_destroy(_effect);
}
gs_effect_t* gs::effect::get_object()
{
return m_effect;
return _effect;
}
size_t gs::effect::count_parameters()
{
return (size_t)gs_effect_get_num_params(m_effect);
return (size_t)gs_effect_get_num_params(_effect);
}
std::list<gs::effect_parameter> gs::effect::get_parameters()
{
size_t num = gs_effect_get_num_params(m_effect);
size_t num = gs_effect_get_num_params(_effect);
std::list<gs::effect_parameter> ps;
for (size_t idx = 0; idx < num; idx++) {
ps.emplace_back(get_parameter(idx));
@ -127,7 +127,7 @@ std::list<gs::effect_parameter> gs::effect::get_parameters()
gs::effect_parameter gs::effect::get_parameter(size_t idx)
{
gs_eparam_t* param = gs_effect_get_param_by_idx(m_effect, idx);
gs_eparam_t* param = gs_effect_get_param_by_idx(_effect, idx);
if (!param)
throw std::invalid_argument("parameter with index not found");
return effect_parameter(param);
@ -135,13 +135,13 @@ gs::effect_parameter gs::effect::get_parameter(size_t idx)
bool gs::effect::has_parameter(std::string name)
{
gs_eparam_t* param = gs_effect_get_param_by_name(m_effect, name.c_str());
gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str());
return (param != nullptr);
}
bool gs::effect::has_parameter(std::string name, effect_parameter::type type)
{
gs_eparam_t* param = gs_effect_get_param_by_name(m_effect, name.c_str());
gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str());
if (param == nullptr)
return false;
gs::effect_parameter eprm(param);
@ -150,28 +150,28 @@ bool gs::effect::has_parameter(std::string name, effect_parameter::type type)
gs::effect_parameter gs::effect::get_parameter(std::string name)
{
gs_eparam_t* param = gs_effect_get_param_by_name(m_effect, name.c_str());
gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str());
if (!param)
throw std::invalid_argument("parameter with name not found");
return effect_parameter(param);
}
gs::effect_parameter::effect_parameter(gs_eparam_t* param) : m_param(param)
gs::effect_parameter::effect_parameter(gs_eparam_t* param) : _param(param)
{
if (!param)
throw std::invalid_argument("param is null");
gs_effect_get_param_info(m_param, &m_paramInfo);
gs_effect_get_param_info(_param, &_param_info);
}
std::string gs::effect_parameter::get_name()
{
return m_paramInfo.name;
return _param_info.name;
}
gs::effect_parameter::type gs::effect_parameter::get_type()
{
switch (m_paramInfo.type) {
switch (_param_info.type) {
case GS_SHADER_PARAM_BOOL:
return type::Boolean;
case GS_SHADER_PARAM_FLOAT:
@ -206,28 +206,28 @@ void gs::effect_parameter::set_bool(bool v)
{
if (get_type() != type::Boolean)
throw std::bad_cast();
gs_effect_set_bool(m_param, v);
gs_effect_set_bool(_param, v);
}
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(m_param, v, sz);
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(m_param, x);
gs_effect_set_float(_param, x);
}
void gs::effect_parameter::set_float2(vec2& v)
{
if (get_type() != type::Float2)
throw std::bad_cast();
gs_effect_set_vec2(m_param, &v);
gs_effect_set_vec2(_param, &v);
}
void gs::effect_parameter::set_float2(float_t x, float_t y)
@ -235,14 +235,14 @@ 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(m_param, &v);
gs_effect_set_vec2(_param, &v);
}
void gs::effect_parameter::set_float3(vec3& v)
{
if (get_type() != type::Float3)
throw std::bad_cast();
gs_effect_set_vec3(m_param, &v);
gs_effect_set_vec3(_param, &v);
}
void gs::effect_parameter::set_float3(float_t x, float_t y, float_t z)
@ -250,14 +250,14 @@ 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(m_param, &v);
gs_effect_set_vec3(_param, &v);
}
void gs::effect_parameter::set_float4(vec4& v)
{
if (get_type() != type::Float4)
throw std::bad_cast();
gs_effect_set_vec4(m_param, &v);
gs_effect_set_vec4(_param, &v);
}
void gs::effect_parameter::set_float4(float_t x, float_t y, float_t z, float_t w)
@ -265,7 +265,7 @@ 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(m_param, &v);
gs_effect_set_vec4(_param, &v);
}
void gs::effect_parameter::set_float_array(float_t v[], size_t sz)
@ -273,14 +273,14 @@ 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(m_param, v, sizeof(float_t) * sz);
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(m_param, x);
gs_effect_set_int(_param, x);
}
void gs::effect_parameter::set_int2(int32_t x, int32_t y)
@ -288,7 +288,7 @@ 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(m_param, v, sizeof(int) * 2);
gs_effect_set_val(_param, v, sizeof(int) * 2);
}
void gs::effect_parameter::set_int3(int32_t x, int32_t y, int32_t z)
@ -296,7 +296,7 @@ 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(m_param, v, sizeof(int) * 3);
gs_effect_set_val(_param, v, sizeof(int) * 3);
}
void gs::effect_parameter::set_int4(int32_t x, int32_t y, int32_t z, int32_t w)
@ -304,7 +304,7 @@ 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(m_param, v, sizeof(int) * 4);
gs_effect_set_val(_param, v, sizeof(int) * 4);
}
void gs::effect_parameter::set_int_array(int32_t v[], size_t sz)
@ -312,40 +312,40 @@ 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(m_param, v, sizeof(int) * sz);
gs_effect_set_val(_param, v, sizeof(int) * sz);
}
void gs::effect_parameter::set_matrix(matrix4& v)
{
if (get_type() != type::Matrix)
throw std::bad_cast();
gs_effect_set_matrix4(m_param, &v);
gs_effect_set_matrix4(_param, &v);
}
void gs::effect_parameter::set_texture(std::shared_ptr<gs::texture> v)
{
if (get_type() != type::Texture)
throw std::bad_cast();
gs_effect_set_texture(m_param, v->get_object());
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(m_param, v);
gs_effect_set_texture(_param, v);
}
void gs::effect_parameter::set_sampler(std::shared_ptr<gs::sampler> v)
{
if (get_type() != type::Texture)
throw std::bad_cast();
gs_effect_set_next_sampler(m_param, v->get_object());
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(m_param, v);
gs_effect_set_next_sampler(_param, v);
}

View file

@ -41,6 +41,9 @@
namespace gs {
class effect_parameter {
gs_eparam_t* _param;
gs_effect_param_info _param_info;
public:
enum class type : uint8_t {
Unknown,
@ -84,13 +87,12 @@ namespace gs {
void set_texture(gs_texture_t* v);
void set_sampler(std::shared_ptr<gs::sampler> v);
void set_sampler(gs_sampler_state* v);
private:
gs_eparam_t* m_param;
gs_effect_param_info m_paramInfo;
};
class effect {
protected:
gs_effect_t* _effect;
public:
effect();
effect(std::string file);
@ -106,7 +108,5 @@ namespace gs {
bool has_parameter(std::string name);
bool has_parameter(std::string name, effect_parameter::type type);
protected:
gs_effect_t* m_effect;
};
} // namespace gs

View file

@ -35,7 +35,7 @@ gs::index_buffer::index_buffer(uint32_t maximumVertices)
{
this->reserve(maximumVertices);
auto gctx = gs::context();
m_indexBuffer = gs_indexbuffer_create(gs_index_type::GS_UNSIGNED_LONG, this->data(), maximumVertices, GS_DYNAMIC);
_index_buffer = gs_indexbuffer_create(gs_index_type::GS_UNSIGNED_LONG, this->data(), maximumVertices, GS_DYNAMIC);
}
gs::index_buffer::index_buffer() : index_buffer(MAXIMUM_VERTICES) {}
@ -53,7 +53,7 @@ gs::index_buffer::index_buffer(std::vector<uint32_t>& other) : index_buffer((uin
gs::index_buffer::~index_buffer()
{
auto gctx = gs::context();
gs_indexbuffer_destroy(m_indexBuffer);
gs_indexbuffer_destroy(_index_buffer);
}
gs_indexbuffer_t* gs::index_buffer::get()
@ -65,7 +65,7 @@ gs_indexbuffer_t* gs::index_buffer::get(bool refreshGPU)
{
if (refreshGPU) {
auto gctx = gs::context();
gs_indexbuffer_flush(m_indexBuffer);
gs_indexbuffer_flush(_index_buffer);
}
return m_indexBuffer;
return _index_buffer;
}

View file

@ -45,6 +45,6 @@ namespace gs {
gs_indexbuffer_t* get(bool refreshGPU);
protected:
gs_indexbuffer_t* m_indexBuffer;
gs_indexbuffer_t* _index_buffer;
};
} // namespace gs

View file

@ -72,44 +72,44 @@ struct gs_d3d11_device {
gs::mipmapper::~mipmapper()
{
vertex_buffer.reset();
render_target.reset();
effect.reset();
_vb.reset();
_rt.reset();
_effect.reset();
}
gs::mipmapper::mipmapper()
{
vertex_buffer = std::make_unique<gs::vertex_buffer>(uint32_t(6u), uint8_t(1u));
auto v0 = vertex_buffer->at(0);
_vb = std::make_unique<gs::vertex_buffer>(uint32_t(6u), uint8_t(1u));
auto v0 = _vb->at(0);
v0.position->x = 0;
v0.position->y = 0;
v0.uv[0]->x = 0;
v0.uv[0]->y = 0;
auto v1 = vertex_buffer->at(1);
auto v4 = vertex_buffer->at(4);
auto v1 = _vb->at(1);
auto v4 = _vb->at(4);
v4.position->x = v1.position->x = 1.0;
v4.position->y = v1.position->y = 0;
v4.uv[0]->x = v1.uv[0]->x = 1.0;
v4.uv[0]->y = v1.uv[0]->y = 0;
auto v2 = vertex_buffer->at(2);
auto v3 = vertex_buffer->at(3);
auto v2 = _vb->at(2);
auto v3 = _vb->at(3);
v3.position->x = v2.position->x = 0;
v3.position->y = v2.position->y = 1.0;
v3.uv[0]->x = v2.uv[0]->x = 0;
v3.uv[0]->y = v2.uv[0]->y = 1.0;
auto v5 = vertex_buffer->at(5);
auto v5 = _vb->at(5);
v5.position->x = 1.0;
v5.position->y = 1.0;
v5.uv[0]->x = 1.0;
v5.uv[0]->y = 1.0;
vertex_buffer->update();
_vb->update();
char* effect_file = obs_module_file("effects/mipgen.effect");
effect = std::make_unique<gs::effect>(effect_file);
char* effect_file = obs_module_file("effects/mipgen._effect");
_effect = std::make_unique<gs::effect>(effect_file);
bfree(effect_file);
}
@ -154,8 +154,8 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
//gs_copy_texture(target->get_object(), source->get_object());
// Test if we actually need to recreate the render target for a different format or at all.
if ((!render_target) || (source->get_color_format() != render_target->get_color_format())) {
render_target = std::make_unique<gs::rendertarget>(source->get_color_format(), GS_ZS_NONE);
if ((!_rt) || (source->get_color_format() != _rt->get_color_format())) {
_rt = std::make_unique<gs::rendertarget>(source->get_color_format(), GS_ZS_NONE);
}
// Render
@ -189,7 +189,7 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
break;
}
gs_load_vertexbuffer(vertex_buffer->update());
gs_load_vertexbuffer(_vb->update());
gs_load_indexbuffer(nullptr);
if (source->get_type() == gs::texture::type::Normal) {
@ -236,7 +236,7 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
// Draw mipmap layer
try {
auto op = render_target->render(uint32_t(texture_width), uint32_t(texture_height));
auto op = _rt->render(uint32_t(texture_width), uint32_t(texture_height));
gs_set_cull_mode(GS_NEITHER);
gs_reset_blend_state();
@ -252,13 +252,13 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
vec4_zero(&black);
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0);
effect->get_parameter("image").set_texture(target);
effect->get_parameter("level").set_int(int32_t(mip - 1));
effect->get_parameter("imageTexel").set_float2(texel_width, texel_height);
effect->get_parameter("strength").set_float(strength);
_effect->get_parameter("image").set_texture(target);
_effect->get_parameter("level").set_int(int32_t(mip - 1));
_effect->get_parameter("imageTexel").set_float2(texel_width, texel_height);
_effect->get_parameter("strength").set_float(strength);
while (gs_effect_loop(effect->get_object(), technique.c_str())) {
gs_draw(gs_draw_mode::GS_TRIS, 0, vertex_buffer->size());
while (gs_effect_loop(_effect->get_object(), technique.c_str())) {
gs_draw(gs_draw_mode::GS_TRIS, 0, _vb->size());
}
} catch (...) {
P_LOG_ERROR("Failed to render mipmap layer.");
@ -268,7 +268,7 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
if (device_type == GS_DEVICE_DIRECT3D_11) {
// Copy
ID3D11Texture2D* rt =
reinterpret_cast<ID3D11Texture2D*>(gs_texture_get_obj(render_target->get_object()));
reinterpret_cast<ID3D11Texture2D*>(gs_texture_get_obj(_rt->get_object()));
uint32_t level = uint32_t(D3D11CalcSubresource(UINT(mip), 0, UINT(mip_levels)));
dev->context->CopySubresourceRegion(target_t2, level, 0, 0, 0, rt, 0, NULL);
}

View file

@ -35,9 +35,9 @@
namespace gs {
class mipmapper {
std::unique_ptr<gs::vertex_buffer> vertex_buffer;
std::unique_ptr<gs::rendertarget> render_target;
std::unique_ptr<gs::effect> effect;
std::unique_ptr<gs::vertex_buffer> _vb;
std::unique_ptr<gs::rendertarget> _rt;
std::unique_ptr<gs::effect> _effect;
public:
enum class generator : uint8_t {

View file

@ -35,16 +35,16 @@
gs::rendertarget::~rendertarget()
{
auto gctx = gs::context();
gs_texrender_destroy(render_target);
gs_texrender_destroy(_render_target);
}
gs::rendertarget::rendertarget(gs_color_format colorFormat, gs_zstencil_format zsFormat)
: color_format(colorFormat), zstencil_format(zsFormat)
: _color_format(colorFormat), _zstencil_format(zsFormat)
{
is_being_rendered = false;
_is_being_rendered = false;
auto gctx = gs::context();
render_target = gs_texrender_create(colorFormat, zsFormat);
if (!render_target) {
_render_target = gs_texrender_create(colorFormat, zsFormat);
if (!_render_target) {
throw std::runtime_error("Failed to create render target.");
}
}
@ -57,7 +57,7 @@ gs::rendertarget_op gs::rendertarget::render(uint32_t width, uint32_t height)
gs_texture_t* gs::rendertarget::get_object()
{
auto gctx = gs::context();
gs_texture_t* tex = gs_texrender_get_texture(render_target);
gs_texture_t* tex = gs_texrender_get_texture(_render_target);
return tex;
}
@ -83,27 +83,27 @@ void gs::rendertarget::get_texture(std::unique_ptr<gs::texture>& tex)
gs_color_format gs::rendertarget::get_color_format()
{
return color_format;
return _color_format;
}
gs_zstencil_format gs::rendertarget::get_zstencil_format()
{
return zstencil_format;
return _zstencil_format;
}
gs::rendertarget_op::rendertarget_op(gs::rendertarget* rt, uint32_t width, uint32_t height) : parent(rt)
{
if (parent == nullptr)
throw std::invalid_argument("rt");
if (parent->is_being_rendered)
if (parent->_is_being_rendered)
throw std::logic_error("Can't start rendering to the same render target twice.");
auto gctx = gs::context();
gs_texrender_reset(parent->render_target);
if (!gs_texrender_begin(parent->render_target, width, height)) {
gs_texrender_reset(parent->_render_target);
if (!gs_texrender_begin(parent->_render_target, width, height)) {
throw std::runtime_error("Failed to begin rendering to render target.");
}
parent->is_being_rendered = true;
parent->_is_being_rendered = true;
}
gs::rendertarget_op::rendertarget_op(gs::rendertarget_op&& r)
@ -118,6 +118,6 @@ gs::rendertarget_op::~rendertarget_op()
return;
auto gctx = gs::context();
gs_texrender_end(parent->render_target);
parent->is_being_rendered = false;
gs_texrender_end(parent->_render_target);
parent->_is_being_rendered = false;
}

View file

@ -39,11 +39,11 @@ namespace gs {
friend class rendertarget_op;
protected:
gs_texrender_t* render_target;
bool is_being_rendered;
gs_texrender_t* _render_target;
bool _is_being_rendered;
gs_color_format color_format;
gs_zstencil_format zstencil_format;
gs_color_format _color_format;
gs_zstencil_format _zstencil_format;
public:
~rendertarget();

View file

@ -21,113 +21,113 @@
gs::sampler::sampler()
{
m_dirty = true;
m_samplerInfo = {GS_FILTER_LINEAR, GS_ADDRESS_WRAP, GS_ADDRESS_WRAP, GS_ADDRESS_WRAP, 1, 0};
m_samplerState = nullptr;
_dirty = true;
_sampler_info = {GS_FILTER_LINEAR, GS_ADDRESS_WRAP, GS_ADDRESS_WRAP, GS_ADDRESS_WRAP, 1, 0};
_sampler_state = nullptr;
}
gs::sampler::~sampler()
{
if (m_samplerState)
gs_samplerstate_destroy(m_samplerState);
if (_sampler_state)
gs_samplerstate_destroy(_sampler_state);
}
void gs::sampler::set_filter(gs_sample_filter v)
{
m_dirty = true;
m_samplerInfo.filter = v;
_dirty = true;
_sampler_info.filter = v;
}
gs_sample_filter gs::sampler::get_filter()
{
return m_samplerInfo.filter;
return _sampler_info.filter;
}
void gs::sampler::set_address_mode_u(gs_address_mode v)
{
m_dirty = true;
m_samplerInfo.address_u = v;
_dirty = true;
_sampler_info.address_u = v;
}
gs_address_mode gs::sampler::get_address_mode_u()
{
return m_samplerInfo.address_u;
return _sampler_info.address_u;
}
void gs::sampler::set_address_mode_v(gs_address_mode v)
{
m_dirty = true;
m_samplerInfo.address_v = v;
_dirty = true;
_sampler_info.address_v = v;
}
gs_address_mode gs::sampler::get_address_mode_v()
{
return m_samplerInfo.address_v;
return _sampler_info.address_v;
}
void gs::sampler::set_address_mode_w(gs_address_mode v)
{
m_dirty = true;
m_samplerInfo.address_w = v;
_dirty = true;
_sampler_info.address_w = v;
}
gs_address_mode gs::sampler::get_address_mode_w()
{
return m_samplerInfo.address_w;
return _sampler_info.address_w;
}
void gs::sampler::set_max_anisotropy(int v)
{
m_dirty = true;
m_samplerInfo.max_anisotropy = v;
_dirty = true;
_sampler_info.max_anisotropy = v;
}
int gs::sampler::get_max_anisotropy()
{
return m_samplerInfo.max_anisotropy;
return _sampler_info.max_anisotropy;
}
void gs::sampler::set_border_color(uint32_t v)
{
m_dirty = true;
m_samplerInfo.border_color = v;
_dirty = true;
_sampler_info.border_color = v;
}
void gs::sampler::set_border_color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
m_dirty = true;
m_samplerInfo.border_color = a << 24 | r << 16 | g << 8 | b;
_dirty = true;
_sampler_info.border_color = a << 24 | r << 16 | g << 8 | b;
}
uint32_t gs::sampler::get_border_color()
{
return m_samplerInfo.border_color;
return _sampler_info.border_color;
}
uint8_t gs::sampler::get_border_color(bool r, bool g, bool b, bool a)
{
if (a)
return (m_samplerInfo.border_color >> 24) & 0xFF;
return (_sampler_info.border_color >> 24) & 0xFF;
if (r)
return (m_samplerInfo.border_color >> 16) & 0xFF;
return (_sampler_info.border_color >> 16) & 0xFF;
if (g)
return (m_samplerInfo.border_color >> 8) & 0xFF;
return (_sampler_info.border_color >> 8) & 0xFF;
if (b)
return m_samplerInfo.border_color & 0xFF;
return _sampler_info.border_color & 0xFF;
return 0;
}
gs_sampler_state* gs::sampler::refresh()
{
gs_samplerstate_destroy(m_samplerState);
m_samplerState = gs_samplerstate_create(&m_samplerInfo);
m_dirty = false;
return m_samplerState;
gs_samplerstate_destroy(_sampler_state);
_sampler_state = gs_samplerstate_create(&_sampler_info);
_dirty = false;
return _sampler_state;
}
gs_sampler_state* gs::sampler::get_object()
{
if (m_dirty)
if (_dirty)
return refresh();
return m_samplerState;
return _sampler_state;
}

View file

@ -61,8 +61,8 @@ namespace gs {
gs_sampler_state* get_object();
private:
bool m_dirty;
gs_sampler_info m_samplerInfo;
gs_sampler_state* m_samplerState;
bool _dirty;
gs_sampler_info _sampler_info;
gs_sampler_state* _sampler_state;
};
} // namespace gs

View file

@ -52,15 +52,15 @@ gs::texture::texture(uint32_t width, uint32_t height, gs_color_format format, ui
}
auto gctx = gs::context();
m_texture = gs_texture_create(
_texture = gs_texture_create(
width, height, format, mip_levels, mip_data,
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
if (!m_texture)
if (!_texture)
throw std::runtime_error("Failed to create texture.");
m_textureType = type::Normal;
_type = type::Normal;
}
gs::texture::texture(uint32_t width, uint32_t height, uint32_t depth, gs_color_format format, uint32_t mip_levels,
@ -84,15 +84,15 @@ gs::texture::texture(uint32_t width, uint32_t height, uint32_t depth, gs_color_f
}
auto gctx = gs::context();
m_texture = gs_voltexture_create(
_texture = gs_voltexture_create(
width, height, depth, format, mip_levels, mip_data,
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
if (!m_texture)
if (!_texture)
throw std::runtime_error("Failed to create texture.");
m_textureType = type::Volume;
_type = type::Volume;
}
gs::texture::texture(uint32_t size, gs_color_format format, uint32_t mip_levels, const uint8_t** mip_data,
@ -110,15 +110,15 @@ gs::texture::texture(uint32_t size, gs_color_format format, uint32_t mip_levels,
}
auto gctx = gs::context();
m_texture = gs_cubetexture_create(
_texture = gs_cubetexture_create(
size, format, mip_levels, mip_data,
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
if (!m_texture)
if (!_texture)
throw std::runtime_error("Failed to create texture.");
m_textureType = type::Cube;
_type = type::Cube;
}
gs::texture::texture(std::string file)
@ -128,75 +128,75 @@ gs::texture::texture(std::string file)
throw std::ios_base::failure(file);
auto gctx = gs::context();
m_texture = gs_texture_create_from_file(file.c_str());
_texture = gs_texture_create_from_file(file.c_str());
if (!m_texture)
if (!_texture)
throw std::runtime_error("Failed to load texture.");
}
gs::texture::~texture()
{
if (m_isOwner && m_texture) {
if (_is_owner && _texture) {
auto gctx = gs::context();
switch (gs_get_texture_type(m_texture)) {
switch (gs_get_texture_type(_texture)) {
case GS_TEXTURE_2D:
gs_texture_destroy(m_texture);
gs_texture_destroy(_texture);
break;
case GS_TEXTURE_3D:
gs_voltexture_destroy(m_texture);
gs_voltexture_destroy(_texture);
break;
case GS_TEXTURE_CUBE:
gs_cubetexture_destroy(m_texture);
gs_cubetexture_destroy(_texture);
break;
}
}
m_texture = nullptr;
_texture = nullptr;
}
void gs::texture::load(int unit)
{
auto gctx = gs::context();
gs_load_texture(m_texture, unit);
gs_load_texture(_texture, unit);
}
gs_texture_t* gs::texture::get_object()
{
return m_texture;
return _texture;
}
uint32_t gs::texture::get_width()
{
switch (m_textureType) {
switch (_type) {
case type::Normal:
return gs_texture_get_width(m_texture);
return gs_texture_get_width(_texture);
case type::Volume:
return gs_voltexture_get_width(m_texture);
return gs_voltexture_get_width(_texture);
case type::Cube:
return gs_cubetexture_get_size(m_texture);
return gs_cubetexture_get_size(_texture);
}
return 0;
}
uint32_t gs::texture::get_height()
{
switch (m_textureType) {
switch (_type) {
case type::Normal:
return gs_texture_get_height(m_texture);
return gs_texture_get_height(_texture);
case type::Volume:
return gs_voltexture_get_height(m_texture);
return gs_voltexture_get_height(_texture);
case type::Cube:
return gs_cubetexture_get_size(m_texture);
return gs_cubetexture_get_size(_texture);
}
return 0;
}
uint32_t gs::texture::get_depth()
{
switch (m_textureType) {
switch (_type) {
case type::Normal:
return 1;
case type::Volume:
return gs_voltexture_get_depth(m_texture);
return gs_voltexture_get_depth(_texture);
case type::Cube:
return 6;
}
@ -205,10 +205,10 @@ uint32_t gs::texture::get_depth()
gs::texture::type gs::texture::get_type()
{
return m_textureType;
return _type;
}
gs_color_format gs::texture::get_color_format()
{
return gs_texture_get_color_format(m_texture);
return gs_texture_get_color_format(_texture);
}

View file

@ -44,9 +44,9 @@ namespace gs {
};
protected:
gs_texture_t* m_texture;
bool m_isOwner = true;
type m_textureType = type::Normal;
gs_texture_t* _texture;
bool _is_owner = true;
type _type = type::Normal;
public:
~texture();
@ -105,7 +105,7 @@ namespace gs {
/*!
* \brief Create a texture from an existing gs_texture_t object.
*/
texture(gs_texture_t* tex, bool takeOwnership = false) : m_texture(tex), m_isOwner(takeOwnership) {}
texture(gs_texture_t* tex, bool takeOwnership = false) : _texture(tex), _is_owner(takeOwnership) {}
void load(int unit);
@ -123,4 +123,4 @@ namespace gs {
};
} // namespace gs
ENABLE_BITMASK_OPERATORS(gs::texture::flags)
P_ENABLE_BITMASK_OPERATORS(gs::texture::flags)

View file

@ -21,39 +21,39 @@
#include "util-memory.hpp"
gs::vertex::vertex()
: position(nullptr), normal(nullptr), tangent(nullptr), color(nullptr), hasStore(true), store(nullptr)
: position(nullptr), normal(nullptr), tangent(nullptr), color(nullptr), _has_store(true), _store(nullptr)
{
store = util::malloc_aligned(16, sizeof(vec3) * 3 + sizeof(uint32_t) + sizeof(vec4) * MAXIMUM_UVW_LAYERS);
_store = util::malloc_aligned(16, sizeof(vec3) * 3 + sizeof(uint32_t) + sizeof(vec4) * MAXIMUM_UVW_LAYERS);
size_t offset = 0;
position = reinterpret_cast<vec3*>(reinterpret_cast<char*>(store) + offset);
position = reinterpret_cast<vec3*>(reinterpret_cast<char*>(_store) + offset);
offset += sizeof(vec3);
normal = reinterpret_cast<vec3*>(reinterpret_cast<char*>(store) + offset);
normal = reinterpret_cast<vec3*>(reinterpret_cast<char*>(_store) + offset);
offset += sizeof(vec3);
tangent = reinterpret_cast<vec3*>(reinterpret_cast<char*>(store) + offset);
tangent = reinterpret_cast<vec3*>(reinterpret_cast<char*>(_store) + offset);
offset += sizeof(vec3);
color = reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(store) + offset);
color = reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(_store) + offset);
offset += sizeof(uint32_t);
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
uv[n] = reinterpret_cast<vec4*>(reinterpret_cast<char*>(store) + offset);
uv[n] = reinterpret_cast<vec4*>(reinterpret_cast<char*>(_store) + offset);
offset += sizeof(vec4);
}
}
gs::vertex::~vertex()
{
if (hasStore) {
util::free_aligned(store);
if (_has_store) {
util::free_aligned(_store);
}
}
gs::vertex::vertex(vec3* p, vec3* n, vec3* t, uint32_t* col, vec4* uvs[MAXIMUM_UVW_LAYERS])
: position(p), normal(n), tangent(t), color(col), hasStore(false)
: position(p), normal(n), tangent(t), color(col), _has_store(false)
{
if (uvs != nullptr) {
for (size_t idx = 0; idx < MAXIMUM_UVW_LAYERS; idx++) {

View file

@ -45,7 +45,7 @@ namespace gs {
~vertex();
private:
bool hasStore;
void* store;
bool _has_store;
void* _store;
};
} // namespace gs

View file

@ -34,43 +34,43 @@
gs::vertex_buffer::~vertex_buffer()
{
if (m_positions) {
util::free_aligned(m_positions);
m_positions = nullptr;
if (_positions) {
util::free_aligned(_positions);
_positions = nullptr;
}
if (m_normals) {
util::free_aligned(m_normals);
m_normals = nullptr;
if (_normals) {
util::free_aligned(_normals);
_normals = nullptr;
}
if (m_tangents) {
util::free_aligned(m_tangents);
m_tangents = nullptr;
if (_tangents) {
util::free_aligned(_tangents);
_tangents = nullptr;
}
if (m_colors) {
util::free_aligned(m_colors);
m_colors = nullptr;
if (_colors) {
util::free_aligned(_colors);
_colors = nullptr;
}
for (size_t n = 0; n < m_layers; n++) {
if (m_uvs[n]) {
util::free_aligned(m_uvs[n]);
m_uvs[n] = nullptr;
for (size_t n = 0; n < _layers; n++) {
if (_uvs[n]) {
util::free_aligned(_uvs[n]);
_uvs[n] = nullptr;
}
}
if (m_layerdata) {
util::free_aligned(m_layerdata);
m_layerdata = nullptr;
if (_layer_data) {
util::free_aligned(_layer_data);
_layer_data = nullptr;
}
if (m_vertexbufferdata) {
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
if (!m_vertexbuffer) {
gs_vbdata_destroy(m_vertexbufferdata);
m_vertexbufferdata = nullptr;
if (_data) {
memset(_data, 0, sizeof(gs_vb_data));
if (!_buffer) {
gs_vbdata_destroy(_data);
_data = nullptr;
}
}
if (m_vertexbuffer) {
if (_buffer) {
auto gctx = gs::context();
gs_vertexbuffer_destroy(m_vertexbuffer);
m_vertexbuffer = nullptr;
gs_vertexbuffer_destroy(_buffer);
_buffer = nullptr;
}
}
@ -79,8 +79,8 @@ gs::vertex_buffer::vertex_buffer() : vertex_buffer(MAXIMUM_VERTICES, MAXIMUM_UVW
gs::vertex_buffer::vertex_buffer(uint32_t vertices) : vertex_buffer(vertices, MAXIMUM_UVW_LAYERS) {}
gs::vertex_buffer::vertex_buffer(uint32_t vertices, uint8_t uvlayers)
: m_size(vertices), m_capacity(vertices), m_layers(uvlayers), m_positions(nullptr), m_normals(nullptr),
m_tangents(nullptr), m_colors(nullptr), m_vertexbufferdata(nullptr), m_vertexbuffer(nullptr), m_layerdata(nullptr)
: _size(vertices), _capacity(vertices), _layers(uvlayers), _positions(nullptr), _normals(nullptr),
_tangents(nullptr), _colors(nullptr), _data(nullptr), _buffer(nullptr), _layer_data(nullptr)
{
if (vertices > MAXIMUM_VERTICES) {
throw std::out_of_range("vertices out of range");
@ -90,41 +90,41 @@ gs::vertex_buffer::vertex_buffer(uint32_t vertices, uint8_t uvlayers)
}
// Allocate memory for data.
m_vertexbufferdata = gs_vbdata_create();
m_vertexbufferdata->num = m_capacity;
m_vertexbufferdata->points = m_positions = (vec3*)util::malloc_aligned(16, sizeof(vec3) * m_capacity);
m_vertexbufferdata->normals = m_normals = (vec3*)util::malloc_aligned(16, sizeof(vec3) * m_capacity);
m_vertexbufferdata->tangents = m_tangents = (vec3*)util::malloc_aligned(16, sizeof(vec3) * m_capacity);
m_vertexbufferdata->colors = m_colors = (uint32_t*)util::malloc_aligned(16, sizeof(uint32_t) * m_capacity);
_data = gs_vbdata_create();
_data->num = _capacity;
_data->points = _positions = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->normals = _normals = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->tangents = _tangents = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->colors = _colors = (uint32_t*)util::malloc_aligned(16, sizeof(uint32_t) * _capacity);
// cppcheck-suppress memsetClassFloat
memset(m_positions, 0, sizeof(vec3) * m_capacity);
memset(_positions, 0, sizeof(vec3) * _capacity);
// cppcheck-suppress memsetClassFloat
memset(m_normals, 0, sizeof(vec3) * m_capacity);
memset(_normals, 0, sizeof(vec3) * _capacity);
// cppcheck-suppress memsetClassFloat
memset(m_tangents, 0, sizeof(vec3) * m_capacity);
memset(m_colors, 0, sizeof(uint32_t) * m_capacity);
memset(_tangents, 0, sizeof(vec3) * _capacity);
memset(_colors, 0, sizeof(uint32_t) * _capacity);
m_vertexbufferdata->num_tex = m_layers;
if (m_layers > 0) {
m_vertexbufferdata->tvarray = m_layerdata =
(gs_tvertarray*)util::malloc_aligned(16, sizeof(gs_tvertarray) * m_layers);
for (size_t n = 0; n < m_layers; n++) {
m_layerdata[n].array = m_uvs[n] = (vec4*)util::malloc_aligned(16, sizeof(vec4) * m_capacity);
m_layerdata[n].width = 4;
memset(m_uvs[n], 0, sizeof(vec4) * m_capacity);
_data->num_tex = _layers;
if (_layers > 0) {
_data->tvarray = _layer_data =
(gs_tvertarray*)util::malloc_aligned(16, sizeof(gs_tvertarray) * _layers);
for (size_t n = 0; n < _layers; n++) {
_layer_data[n].array = _uvs[n] = (vec4*)util::malloc_aligned(16, sizeof(vec4) * _capacity);
_layer_data[n].width = 4;
memset(_uvs[n], 0, sizeof(vec4) * _capacity);
}
} else {
m_vertexbufferdata->tvarray = nullptr;
_data->tvarray = nullptr;
}
// Allocate GPU
auto gctx = gs::context();
m_vertexbuffer = gs_vertexbuffer_create(m_vertexbufferdata, GS_DYNAMIC);
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
m_vertexbufferdata->num = m_capacity;
m_vertexbufferdata->num_tex = m_layers;
if (!m_vertexbuffer) {
_buffer = gs_vertexbuffer_create(_data, GS_DYNAMIC);
memset(_data, 0, sizeof(gs_vb_data));
_data->num = _capacity;
_data->num_tex = _layers;
if (!_buffer) {
throw std::runtime_error("Failed to create vertex buffer.");
}
}
@ -141,24 +141,24 @@ gs::vertex_buffer::vertex_buffer(gs_vertbuffer_t* vb)
this->set_uv_layers((uint32_t)vbd->num_tex);
if (vbd->points != nullptr)
memcpy(m_positions, vbd->points, vbd->num * sizeof(vec3));
memcpy(_positions, vbd->points, vbd->num * sizeof(vec3));
if (vbd->normals != nullptr)
memcpy(m_normals, vbd->normals, vbd->num * sizeof(vec3));
memcpy(_normals, vbd->normals, vbd->num * sizeof(vec3));
if (vbd->tangents != nullptr)
memcpy(m_tangents, vbd->tangents, vbd->num * sizeof(vec3));
memcpy(_tangents, vbd->tangents, vbd->num * sizeof(vec3));
if (vbd->colors != nullptr)
memcpy(m_colors, vbd->colors, vbd->num * sizeof(uint32_t));
memcpy(_colors, vbd->colors, vbd->num * sizeof(uint32_t));
if (vbd->tvarray != nullptr) {
for (size_t n = 0; n < vbd->num_tex; n++) {
if (vbd->tvarray[n].array != nullptr && vbd->tvarray[n].width <= 4 && vbd->tvarray[n].width > 0) {
if (vbd->tvarray[n].width == 4) {
memcpy(m_uvs[n], vbd->tvarray[n].array, vbd->num * sizeof(vec4));
memcpy(_uvs[n], vbd->tvarray[n].array, vbd->num * sizeof(vec4));
} else {
for (size_t idx = 0; idx < m_capacity; idx++) {
for (size_t idx = 0; idx < _capacity; idx++) {
float* mem = reinterpret_cast<float*>(vbd->tvarray[n].array) + (idx * vbd->tvarray[n].width);
// cppcheck-suppress memsetClassFloat
memset(&m_uvs[n][idx], 0, sizeof(vec4));
memcpy(&m_uvs[n][idx], mem, vbd->tvarray[n].width);
memset(&_uvs[n][idx], 0, sizeof(vec4));
memcpy(&_uvs[n][idx], mem, vbd->tvarray[n].width);
}
}
}
@ -167,120 +167,120 @@ gs::vertex_buffer::vertex_buffer(gs_vertbuffer_t* vb)
}
// cppcheck-suppress uninitMemberVar
gs::vertex_buffer::vertex_buffer(vertex_buffer const& other) : vertex_buffer(other.m_capacity)
gs::vertex_buffer::vertex_buffer(vertex_buffer const& other) : vertex_buffer(other._capacity)
{
// Copy Constructor
memcpy(m_positions, other.m_positions, m_capacity * sizeof(vec3));
memcpy(m_normals, other.m_normals, m_capacity * sizeof(vec3));
memcpy(m_tangents, other.m_tangents, m_capacity * sizeof(vec3));
memcpy(m_colors, other.m_colors, m_capacity * sizeof(vec3));
memcpy(_positions, other._positions, _capacity * sizeof(vec3));
memcpy(_normals, other._normals, _capacity * sizeof(vec3));
memcpy(_tangents, other._tangents, _capacity * sizeof(vec3));
memcpy(_colors, other._colors, _capacity * sizeof(vec3));
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
memcpy(m_uvs[n], other.m_uvs[n], m_capacity * sizeof(vec3));
memcpy(_uvs[n], other._uvs[n], _capacity * sizeof(vec3));
}
}
gs::vertex_buffer::vertex_buffer(vertex_buffer const&& other)
{
// Move Constructor
m_capacity = other.m_capacity;
m_size = other.m_size;
m_layers = other.m_layers;
m_positions = other.m_positions;
m_normals = other.m_normals;
m_tangents = other.m_tangents;
_capacity = other._capacity;
_size = other._size;
_layers = other._layers;
_positions = other._positions;
_normals = other._normals;
_tangents = other._tangents;
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
m_uvs[n] = other.m_uvs[n];
_uvs[n] = other._uvs[n];
}
m_vertexbufferdata = other.m_vertexbufferdata;
m_vertexbuffer = other.m_vertexbuffer;
m_layerdata = other.m_layerdata;
_data = other._data;
_buffer = other._buffer;
_layer_data = other._layer_data;
}
void gs::vertex_buffer::operator=(vertex_buffer const&& other)
{
// Move Assignment
/// First self-destruct (semi-destruct itself).
if (m_positions) {
util::free_aligned(m_positions);
m_positions = nullptr;
if (_positions) {
util::free_aligned(_positions);
_positions = nullptr;
}
if (m_normals) {
util::free_aligned(m_normals);
m_normals = nullptr;
if (_normals) {
util::free_aligned(_normals);
_normals = nullptr;
}
if (m_tangents) {
util::free_aligned(m_tangents);
m_tangents = nullptr;
if (_tangents) {
util::free_aligned(_tangents);
_tangents = nullptr;
}
if (m_colors) {
util::free_aligned(m_colors);
m_colors = nullptr;
if (_colors) {
util::free_aligned(_colors);
_colors = nullptr;
}
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
if (m_uvs[n]) {
util::free_aligned(m_uvs[n]);
m_uvs[n] = nullptr;
if (_uvs[n]) {
util::free_aligned(_uvs[n]);
_uvs[n] = nullptr;
}
}
if (m_layerdata) {
util::free_aligned(m_layerdata);
m_layerdata = nullptr;
if (_layer_data) {
util::free_aligned(_layer_data);
_layer_data = nullptr;
}
if (m_vertexbufferdata) {
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
if (!m_vertexbuffer) {
gs_vbdata_destroy(m_vertexbufferdata);
m_vertexbufferdata = nullptr;
if (_data) {
memset(_data, 0, sizeof(gs_vb_data));
if (!_buffer) {
gs_vbdata_destroy(_data);
_data = nullptr;
}
}
if (m_vertexbuffer) {
if (_buffer) {
auto gctx = gs::context();
gs_vertexbuffer_destroy(m_vertexbuffer);
m_vertexbuffer = nullptr;
gs_vertexbuffer_destroy(_buffer);
_buffer = nullptr;
}
/// Then assign new values.
m_capacity = other.m_capacity;
m_size = other.m_size;
m_layers = other.m_layers;
m_positions = other.m_positions;
m_normals = other.m_normals;
m_tangents = other.m_tangents;
_capacity = other._capacity;
_size = other._size;
_layers = other._layers;
_positions = other._positions;
_normals = other._normals;
_tangents = other._tangents;
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
m_uvs[n] = other.m_uvs[n];
_uvs[n] = other._uvs[n];
}
m_vertexbufferdata = other.m_vertexbufferdata;
m_vertexbuffer = other.m_vertexbuffer;
m_layerdata = other.m_layerdata;
_data = other._data;
_buffer = other._buffer;
_layer_data = other._layer_data;
}
void gs::vertex_buffer::resize(uint32_t new_size)
{
if (new_size > m_capacity) {
if (new_size > _capacity) {
throw std::out_of_range("new_size out of range");
}
m_size = new_size;
_size = new_size;
}
uint32_t gs::vertex_buffer::size()
{
return m_size;
return _size;
}
bool gs::vertex_buffer::empty()
{
return m_size == 0;
return _size == 0;
}
const gs::vertex gs::vertex_buffer::at(uint32_t idx)
{
if ((idx < 0) || (idx >= m_size)) {
if ((idx < 0) || (idx >= _size)) {
throw std::out_of_range("idx out of range");
}
gs::vertex vtx(&m_positions[idx], &m_normals[idx], &m_tangents[idx], &m_colors[idx], nullptr);
for (size_t n = 0; n < m_layers; n++) {
vtx.uv[n] = &m_uvs[n][idx];
gs::vertex vtx(&_positions[idx], &_normals[idx], &_tangents[idx], &_colors[idx], nullptr);
for (size_t n = 0; n < _layers; n++) {
vtx.uv[n] = &_uvs[n][idx];
}
return vtx;
}
@ -292,78 +292,78 @@ const gs::vertex gs::vertex_buffer::operator[](uint32_t const pos)
void gs::vertex_buffer::set_uv_layers(uint32_t layers)
{
m_layers = layers;
_layers = layers;
}
uint32_t gs::vertex_buffer::get_uv_layers()
{
return m_layers;
return _layers;
}
vec3* gs::vertex_buffer::get_positions()
{
return m_positions;
return _positions;
}
vec3* gs::vertex_buffer::get_normals()
{
return m_normals;
return _normals;
}
vec3* gs::vertex_buffer::get_tangents()
{
return m_tangents;
return _tangents;
}
uint32_t* gs::vertex_buffer::get_colors()
{
return m_colors;
return _colors;
}
vec4* gs::vertex_buffer::get_uv_layer(size_t idx)
{
if ((idx < 0) || (idx >= m_layers)) {
if ((idx < 0) || (idx >= _layers)) {
throw std::out_of_range("idx out of range");
}
return m_uvs[idx];
return _uvs[idx];
}
gs_vertbuffer_t* gs::vertex_buffer::update(bool refreshGPU)
{
if (!refreshGPU)
return m_vertexbuffer;
return _buffer;
if (m_size > m_capacity)
if (_size > _capacity)
throw std::out_of_range("size is larger than capacity");
// Update VertexBuffer data.
auto gctx = gs::context();
m_vertexbufferdata = gs_vertexbuffer_get_data(m_vertexbuffer);
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
m_vertexbufferdata->num = m_capacity;
m_vertexbufferdata->points = m_positions;
m_vertexbufferdata->normals = m_normals;
m_vertexbufferdata->tangents = m_tangents;
m_vertexbufferdata->colors = m_colors;
m_vertexbufferdata->num_tex = m_layers;
m_vertexbufferdata->tvarray = m_layerdata;
for (size_t n = 0; n < m_layers; n++) {
m_layerdata[n].array = m_uvs[n];
m_layerdata[n].width = 4;
_data = gs_vertexbuffer_get_data(_buffer);
memset(_data, 0, sizeof(gs_vb_data));
_data->num = _capacity;
_data->points = _positions;
_data->normals = _normals;
_data->tangents = _tangents;
_data->colors = _colors;
_data->num_tex = _layers;
_data->tvarray = _layer_data;
for (size_t n = 0; n < _layers; n++) {
_layer_data[n].array = _uvs[n];
_layer_data[n].width = 4;
}
// Update GPU
gs_vertexbuffer_flush(m_vertexbuffer);
gs_vertexbuffer_flush(_buffer);
// WORKAROUND: OBS Studio 20.x and below incorrectly deletes data that it doesn't own.
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
m_vertexbufferdata->num = m_capacity;
m_vertexbufferdata->num_tex = m_layers;
for (uint32_t n = 0; n < m_layers; n++) {
m_layerdata[n].width = 4;
memset(_data, 0, sizeof(gs_vb_data));
_data->num = _capacity;
_data->num_tex = _layers;
for (uint32_t n = 0; n < _layers; n++) {
_layer_data[n].width = 4;
}
return m_vertexbuffer;
return _buffer;
}
gs_vertbuffer_t* gs::vertex_buffer::update()

View file

@ -36,6 +36,22 @@
namespace gs {
class vertex_buffer {
uint32_t _size;
uint32_t _capacity;
uint32_t _layers;
// Memory Storage
vec3* _positions;
vec3* _normals;
vec3* _tangents;
uint32_t* _colors;
vec4* _uvs[MAXIMUM_UVW_LAYERS];
// OBS GS Data
gs_vb_data* _data;
gs_vertbuffer_t* _buffer;
gs_tvertarray* _layer_data;
public:
virtual ~vertex_buffer();
@ -160,22 +176,5 @@ namespace gs {
gs_vertbuffer_t* update();
gs_vertbuffer_t* update(bool refreshGPU);
private:
uint32_t m_size;
uint32_t m_capacity;
uint32_t m_layers;
// Memory Storage
vec3* m_positions;
vec3* m_normals;
vec3* m_tangents;
uint32_t* m_colors;
vec4* m_uvs[MAXIMUM_UVW_LAYERS];
// OBS GS Data
gs_vb_data* m_vertexbufferdata;
gs_vertbuffer_t* m_vertexbuffer;
gs_tvertarray* m_layerdata;
};
} // namespace gs

View file

@ -43,7 +43,7 @@ void obs::source_tracker::source_create_handler(void* ptr, calldata_t* data)
return;
}
self->source_map.insert({std::string(name), weak});
self->_source_map.insert({std::string(name), weak});
}
void obs::source_tracker::source_destroy_handler(void* ptr, calldata_t* data)
@ -63,13 +63,13 @@ void obs::source_tracker::source_destroy_handler(void* ptr, calldata_t* data)
return;
}
auto found = self->source_map.find(std::string(name));
if (found == self->source_map.end()) {
auto found = self->_source_map.find(std::string(name));
if (found == self->_source_map.end()) {
return;
}
obs_weak_source_release(found->second);
self->source_map.erase(found);
self->_source_map.erase(found);
}
void obs::source_tracker::source_rename_handler(void* ptr, calldata_t* data)
@ -88,20 +88,20 @@ void obs::source_tracker::source_rename_handler(void* ptr, calldata_t* data)
return;
}
auto found = self->source_map.find(std::string(prev_name));
if (found == self->source_map.end()) {
auto found = self->_source_map.find(std::string(prev_name));
if (found == self->_source_map.end()) {
// Untracked source, insert.
obs_weak_source_t* weak = obs_source_get_weak_source(target);
if (!weak) {
return;
}
self->source_map.insert({new_name, weak});
self->_source_map.insert({new_name, weak});
return;
}
// Insert at new key, remove old pair.
self->source_map.insert({new_name, found->second});
self->source_map.erase(found);
self->_source_map.insert({new_name, found->second});
self->_source_map.erase(found);
}
void obs::source_tracker::initialize()
@ -136,17 +136,17 @@ obs::source_tracker::~source_tracker()
signal_handler_disconnect(osi, "source_rename", &source_rename_handler, this);
}
for (auto kv : this->source_map) {
for (auto kv : this->_source_map) {
obs_weak_source_release(kv.second);
}
this->source_map.clear();
this->_source_map.clear();
}
void obs::source_tracker::enumerate(enumerate_cb_t ecb, filter_cb_t fcb)
{
// Need func-local copy, otherwise we risk corruption if a new source is created or destroyed.
auto source_map_copy = this->source_map;
for (auto kv : this->source_map) {
auto source_map_copy = this->_source_map;
for (auto kv : this->_source_map) {
obs_source_t* source = obs_weak_source_get_source(kv.second);
if (!source) {
continue;

View file

@ -34,7 +34,7 @@
namespace obs {
class source_tracker {
std::map<std::string, obs_weak_source_t*> source_map;
std::map<std::string, obs_weak_source_t*> _source_map;
static void source_create_handler(void* ptr, calldata_t* data);
static void source_destroy_handler(void* ptr, calldata_t* data);

View file

@ -28,8 +28,8 @@ void obs::source::handle_destroy(void* p, calldata_t* calldata)
return;
}
if (self->self == source) {
self->self = nullptr;
if (self->_self == source) {
self->_self = nullptr;
}
if (self->events.destroy) {
@ -397,10 +397,10 @@ obs::source::~source()
auto_signal_d(transition_stop);
#undef auto_signal_d
if (this->track_ownership && this->self) {
obs_source_release(this->self);
if (this->_track_ownership && this->_self) {
obs_source_release(this->_self);
}
this->self = nullptr;
this->_self = nullptr;
}
obs::source::source()
@ -411,17 +411,17 @@ obs::source::source()
#define auto_signal_c(SIGNAL) \
{ \
this->events.SIGNAL.set_listen_callback([this] { \
if (!this->self) \
if (!this->_self) \
return; \
auto sh = obs_source_get_signal_handler(this->self); \
auto sh = obs_source_get_signal_handler(this->_self); \
if (sh) { \
signal_handler_connect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); \
} \
}); \
this->events.SIGNAL.set_silence_callback([this] { \
if (!this->self) \
if (!this->_self) \
return; \
auto sh = obs_source_get_signal_handler(this->self); \
auto sh = obs_source_get_signal_handler(this->_self); \
if (sh) { \
signal_handler_disconnect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); \
} \
@ -441,51 +441,51 @@ obs::source::source()
// things do. So instead we'll have to manually deal with it for now.
{
this->events.audio_data.set_listen_callback([this] {
if (!this->self)
if (!this->_self)
return;
obs_source_add_audio_capture_callback(this->self, obs::source::handle_audio_data, this);
obs_source_add_audio_capture_callback(this->_self, obs::source::handle_audio_data, this);
});
this->events.audio_data.set_silence_callback([this] {
if (!this->self)
if (!this->_self)
return;
obs_source_remove_audio_capture_callback(this->self, obs::source::handle_audio_data, this);
obs_source_remove_audio_capture_callback(this->_self, obs::source::handle_audio_data, this);
});
}
}
obs::source::source(std::string name, bool ptrack_ownership, bool add_reference) : ::obs::source::source()
{
this->self = obs_get_source_by_name(name.c_str());
if (!this->self) {
this->_self = obs_get_source_by_name(name.c_str());
if (!this->_self) {
throw std::runtime_error("source with name not found");
}
this->track_ownership = ptrack_ownership;
this->_track_ownership = ptrack_ownership;
if (!add_reference) {
obs_source_release(this->self);
obs_source_release(this->_self);
}
}
obs::source::source(obs_source_t* source, bool ptrack_ownership, bool add_reference) : ::obs::source::source()
{
this->self = source;
if (!this->self) {
this->_self = source;
if (!this->_self) {
throw std::invalid_argument("source must not be null");
}
this->track_ownership = ptrack_ownership;
this->_track_ownership = ptrack_ownership;
if (add_reference) {
obs_source_addref(this->self);
obs_source_addref(this->_self);
}
}
obs::source::source(source const& other)
{
this->self = other.self;
this->track_ownership = other.track_ownership;
this->_self = other._self;
this->_track_ownership = other._track_ownership;
if (this->track_ownership) {
obs_source_addref(this->self);
if (this->_track_ownership) {
obs_source_addref(this->_self);
}
#ifdef auto_signal_c
@ -529,15 +529,15 @@ obs::source& obs::source::operator=(source const& other)
}
// Release previous source.
if (this->self && this->track_ownership) {
obs_source_release(this->self);
if (this->_self && this->_track_ownership) {
obs_source_release(this->_self);
}
this->self = other.self;
this->track_ownership = other.track_ownership;
this->_self = other._self;
this->_track_ownership = other._track_ownership;
if (this->track_ownership) {
obs_source_addref(this->self);
if (this->_track_ownership) {
obs_source_addref(this->_self);
}
#ifdef auto_signal_c
@ -576,11 +576,11 @@ obs::source& obs::source::operator=(source const& other)
return *this;
}
obs::source::source(source&& other) : self(std::move(other.self)), track_ownership(std::move(other.track_ownership))
obs::source::source(source&& other) : _self(std::move(other._self)), _track_ownership(std::move(other._track_ownership))
{
// Clean out other source
other.self = nullptr;
other.track_ownership = false;
other._self = nullptr;
other._track_ownership = false;
#ifdef auto_signal_c
#undef auto_signal_c
@ -623,14 +623,14 @@ obs::source& obs::source::operator=(source&& other)
}
// Release previous source.
if (this->self && this->track_ownership) {
obs_source_release(this->self);
if (this->_self && this->_track_ownership) {
obs_source_release(this->_self);
}
this->self = std::move(other.self);
this->track_ownership = std::move(other.track_ownership);
other.self = nullptr;
other.track_ownership = false;
this->_self = std::move(other._self);
this->_track_ownership = std::move(other._track_ownership);
other._self = nullptr;
other._track_ownership = false;
#ifdef auto_signal_c
#undef auto_signal_c
@ -670,47 +670,47 @@ obs::source& obs::source::operator=(source&& other)
obs_source_type obs::source::type()
{
if (!self) {
if (!_self) {
return (obs_source_type)-1;
}
return obs_source_get_type(self);
return obs_source_get_type(_self);
}
void* obs::source::type_data()
{
if (!self) {
if (!_self) {
return nullptr;
}
return obs_source_get_type_data(self);
return obs_source_get_type_data(_self);
}
uint32_t obs::source::width()
{
if (!self) {
if (!_self) {
return 0;
}
return obs_source_get_width(self);
return obs_source_get_width(_self);
}
uint32_t obs::source::height()
{
if (!self) {
if (!_self) {
return 0;
}
return obs_source_get_height(self);
return obs_source_get_height(_self);
}
bool obs::source::destroyed()
{
return self == nullptr;
return _self == nullptr;
}
void obs::source::clear()
{
self = nullptr;
_self = nullptr;
}
obs_source_t* obs::source::get()
{
return self;
return _self;
}

View file

@ -37,8 +37,8 @@
namespace obs {
class source {
obs_source_t* self;
bool track_ownership = false;
obs_source_t* _self;
bool _track_ownership = false;
static void handle_destroy(void* p, calldata_t* calldata);
static void handle_remove(void* p, calldata_t* calldata);

View file

@ -20,15 +20,15 @@
#include "plugin.hpp"
#include "obs/obs-source-tracker.hpp"
std::list<std::function<void()>> initializerFunctions;
std::list<std::function<void()>> finalizerFunctions;
std::list<std::function<void()>> initializer_functions;
std::list<std::function<void()>> finalizer_functions;
MODULE_EXPORT bool obs_module_load(void)
{
P_LOG_INFO("Loading Version %u.%u.%u (Build %u)", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR,
PROJECT_VERSION_PATCH, PROJECT_VERSION_TWEAK);
obs::source_tracker::initialize();
for (auto func : initializerFunctions) {
for (auto func : initializer_functions) {
func();
}
return true;
@ -38,7 +38,7 @@ MODULE_EXPORT void obs_module_unload(void)
{
P_LOG_INFO("Unloading Version %u.%u.%u (Build %u)", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR,
PROJECT_VERSION_PATCH, PROJECT_VERSION_TWEAK);
for (auto func : finalizerFunctions) {
for (auto func : finalizer_functions) {
func();
}
obs::source_tracker::finalize();

View file

@ -44,5 +44,5 @@
#define P_LOG_DEBUG(...) P_LOG(LOG_DEBUG, __VA_ARGS__)
// Initializer & Finalizer
extern std::list<std::function<void()>> initializerFunctions;
extern std::list<std::function<void()>> finalizerFunctions;
extern std::list<std::function<void()>> initializer_functions;
extern std::list<std::function<void()>> finalizer_functions;

View file

@ -38,33 +38,33 @@
#pragma warning(pop)
#endif
#define S_SOURCE_MIRROR "Source.Mirror"
#define P_SOURCE "Source.Mirror.Source"
#define P_SOURCE_SIZE "Source.Mirror.Source.Size"
#define P_SOURCE_AUDIO "Source.Mirror.Source.Audio"
#define ST_AUDIO_LAYOUT S_SOURCE_MIRROR ".Audio.Layout"
#define ST "Source.Mirror"
#define ST_SOURCE "Source.Mirror.Source"
#define ST_SOURCE_SIZE "Source.Mirror.Source.Size"
#define ST_AUDIO "Source.Mirror.Source.Audio"
#define ST_AUDIO_LAYOUT ST ".Audio.Layout"
#define ST_AUDIO_LAYOUT_(x) ST_AUDIO_LAYOUT "." D_VSTR(x)
#define P_SCALING "Source.Mirror.Scaling"
#define P_SCALING_METHOD "Source.Mirror.Scaling.Method"
#define P_SCALING_METHOD_POINT "Source.Mirror.Scaling.Method.Point"
#define P_SCALING_METHOD_BILINEAR "Source.Mirror.Scaling.Method.Bilinear"
#define P_SCALING_METHOD_BICUBIC "Source.Mirror.Scaling.Method.Bicubic"
#define P_SCALING_METHOD_LANCZOS "Source.Mirror.Scaling.Method.Lanczos"
#define P_SCALING_SIZE "Source.Mirror.Scaling.Size"
#define P_SCALING_TRANSFORMKEEPORIGINAL "Source.Mirror.Scaling.TransformKeepOriginal"
#define P_SCALING_BOUNDS "Source.Mirror.Scaling.Bounds"
#define P_SCALING_BOUNDS_STRETCH "Source.Mirror.Scaling.Bounds.Stretch"
#define P_SCALING_BOUNDS_FIT "Source.Mirror.Scaling.Bounds.Fit"
#define P_SCALING_BOUNDS_FILL "Source.Mirror.Scaling.Bounds.Fill"
#define P_SCALING_BOUNDS_FILLWIDTH "Source.Mirror.Scaling.Bounds.FillWidth"
#define P_SCALING_BOUNDS_FILLHEIGHT "Source.Mirror.Scaling.Bounds.FillHeight"
#define P_SCALING_ALIGNMENT "Source.Mirror.Scaling.Alignment"
#define ST_SCALING "Source.Mirror.Scaling"
#define ST_SCALING_METHOD "Source.Mirror.Scaling.Method"
#define ST_SCALING_METHOD_POINT "Source.Mirror.Scaling.Method.Point"
#define ST_SCALING_METHOD_BILINEAR "Source.Mirror.Scaling.Method.Bilinear"
#define ST_SCALING_METHOD_BICUBIC "Source.Mirror.Scaling.Method.Bicubic"
#define ST_SCALING_METHOD_LANCZOS "Source.Mirror.Scaling.Method.Lanczos"
#define ST_SCALING_SIZE "Source.Mirror.Scaling.Size"
#define ST_SCALING_TRANSFORMKEEPORIGINAL "Source.Mirror.Scaling.TransformKeepOriginal"
#define ST_SCALING_BOUNDS "Source.Mirror.Scaling.Bounds"
#define ST_SCALING_BOUNDS_STRETCH "Source.Mirror.Scaling.Bounds.Stretch"
#define ST_SCALING_BOUNDS_FIT "Source.Mirror.Scaling.Bounds.Fit"
#define ST_SCALING_BOUNDS_FILL "Source.Mirror.Scaling.Bounds.Fill"
#define ST_SCALING_BOUNDS_FILLWIDTH "Source.Mirror.Scaling.Bounds.FillWidth"
#define ST_SCALING_BOUNDS_FILLHEIGHT "Source.Mirror.Scaling.Bounds.FillHeight"
#define ST_SCALING_ALIGNMENT "Source.Mirror.Scaling.Alignment"
// Initializer & Finalizer
INITIALIZER(SourceMirrorInit)
P_INITIALIZER(SourceMirrorInit)
{
initializerFunctions.push_back([] { source::mirror::mirror_factory::initialize(); });
finalizerFunctions.push_back([] { source::mirror::mirror_factory::finalize(); });
initializer_functions.push_back([] { source::mirror::mirror_factory::initialize(); });
finalizer_functions.push_back([] { source::mirror::mirror_factory::finalize(); });
}
static std::shared_ptr<source::mirror::mirror_factory> factory_instance = nullptr;
@ -86,101 +86,101 @@ std::shared_ptr<source::mirror::mirror_factory> source::mirror::mirror_factory::
source::mirror::mirror_factory::mirror_factory()
{
memset(&osi, 0, sizeof(obs_source_info));
osi.id = "obs-stream-effects-source-mirror";
osi.type = OBS_SOURCE_TYPE_INPUT;
osi.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_AUDIO | OBS_SOURCE_CUSTOM_DRAW;
memset(&_source_info, 0, sizeof(obs_source_info));
_source_info.id = "obs-stream-effects-source-mirror";
_source_info.type = OBS_SOURCE_TYPE_INPUT;
_source_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_AUDIO | OBS_SOURCE_CUSTOM_DRAW;
osi.get_name = get_name;
osi.get_defaults = get_defaults;
osi.get_properties = get_properties;
osi.get_width = get_width;
osi.get_height = get_height;
osi.create = create;
osi.destroy = destroy;
osi.update = update;
osi.activate = activate;
osi.deactivate = deactivate;
osi.video_tick = video_tick;
osi.video_render = video_render;
osi.enum_active_sources = enum_active_sources;
osi.load = load;
osi.save = save;
_source_info.get_name = get_name;
_source_info.get_defaults = get_defaults;
_source_info.get_properties = get_properties;
_source_info.get_width = get_width;
_source_info.get_height = get_height;
_source_info.create = create;
_source_info.destroy = destroy;
_source_info.update = update;
_source_info.activate = activate;
_source_info.deactivate = deactivate;
_source_info.video_tick = video_tick;
_source_info.video_render = video_render;
_source_info.enum_active_sources = enum_active_sources;
_source_info.load = load;
_source_info.save = save;
obs_register_source(&osi);
obs_register_source(&_source_info);
}
source::mirror::mirror_factory::~mirror_factory() {}
const char* source::mirror::mirror_factory::get_name(void*)
{
return P_TRANSLATE(S_SOURCE_MIRROR);
return D_TRANSLATE(ST);
}
void source::mirror::mirror_factory::get_defaults(obs_data_t* data)
{
obs_data_set_default_string(data, P_SOURCE, "");
obs_data_set_default_bool(data, P_SOURCE_AUDIO, false);
obs_data_set_default_string(data, ST_SOURCE, "");
obs_data_set_default_bool(data, ST_AUDIO, false);
obs_data_set_default_int(data, ST_AUDIO_LAYOUT, static_cast<int64_t>(SPEAKERS_UNKNOWN));
obs_data_set_default_bool(data, P_SCALING, false);
obs_data_set_default_string(data, P_SCALING_SIZE, "100x100");
obs_data_set_default_int(data, P_SCALING_METHOD, (int64_t)obs_scale_type::OBS_SCALE_BILINEAR);
obs_data_set_default_bool(data, P_SCALING_TRANSFORMKEEPORIGINAL, false);
obs_data_set_default_int(data, P_SCALING_BOUNDS, (int64_t)obs_bounds_type::OBS_BOUNDS_STRETCH);
obs_data_set_default_int(data, P_SCALING_ALIGNMENT, OBS_ALIGN_CENTER);
obs_data_set_default_bool(data, ST_SCALING, false);
obs_data_set_default_string(data, ST_SCALING_SIZE, "100x100");
obs_data_set_default_int(data, ST_SCALING_METHOD, (int64_t)obs_scale_type::OBS_SCALE_BILINEAR);
obs_data_set_default_bool(data, ST_SCALING_TRANSFORMKEEPORIGINAL, false);
obs_data_set_default_int(data, ST_SCALING_BOUNDS, (int64_t)obs_bounds_type::OBS_BOUNDS_STRETCH);
obs_data_set_default_int(data, ST_SCALING_ALIGNMENT, OBS_ALIGN_CENTER);
}
bool source::mirror::mirror_factory::modified_properties(obs_properties_t* pr, obs_property_t* p, obs_data_t* data)
{
if (obs_properties_get(pr, P_SOURCE) == p) {
obs_source_t* target = obs_get_source_by_name(obs_data_get_string(data, P_SOURCE));
if (obs_properties_get(pr, ST_SOURCE) == p) {
obs_source_t* target = obs_get_source_by_name(obs_data_get_string(data, ST_SOURCE));
if (target) {
std::vector<char> buf(256);
snprintf(buf.data(), buf.size(), "%" PRIu32 "x%" PRIu32, obs_source_get_width(target),
obs_source_get_height(target));
obs_data_set_string(data, P_SOURCE_SIZE, buf.data());
obs_data_set_string(data, ST_SOURCE_SIZE, buf.data());
} else {
obs_data_set_string(data, P_SOURCE_SIZE, "0x0");
obs_data_set_string(data, ST_SOURCE_SIZE, "0x0");
}
obs_source_release(target);
}
if (obs_properties_get(pr, P_SOURCE_AUDIO) == p) {
bool show = obs_data_get_bool(data, P_SOURCE_AUDIO);
if (obs_properties_get(pr, ST_AUDIO) == p) {
bool show = obs_data_get_bool(data, ST_AUDIO);
obs_property_set_visible(obs_properties_get(pr, ST_AUDIO_LAYOUT), show);
return true;
}
if (obs_properties_get(pr, P_SCALING) == p) {
bool show = obs_data_get_bool(data, P_SCALING);
obs_property_set_visible(obs_properties_get(pr, P_SCALING_METHOD), show);
obs_property_set_visible(obs_properties_get(pr, P_SCALING_SIZE), show);
obs_property_set_visible(obs_properties_get(pr, P_SCALING_BOUNDS), show);
obs_property_set_visible(obs_properties_get(pr, P_SCALING_ALIGNMENT), show);
if (obs_properties_get(pr, ST_SCALING) == p) {
bool show = obs_data_get_bool(data, ST_SCALING);
obs_property_set_visible(obs_properties_get(pr, ST_SCALING_METHOD), show);
obs_property_set_visible(obs_properties_get(pr, ST_SCALING_SIZE), show);
obs_property_set_visible(obs_properties_get(pr, ST_SCALING_BOUNDS), show);
obs_property_set_visible(obs_properties_get(pr, ST_SCALING_ALIGNMENT), show);
return true;
}
if (obs_properties_get(pr, P_SCALING_BOUNDS) == p) {
obs_bounds_type scaling_type = static_cast<obs_bounds_type>(obs_data_get_int(data, P_SCALING_BOUNDS));
obs_property_t* p2 = obs_properties_get(pr, P_SCALING_BOUNDS);
if (obs_properties_get(pr, ST_SCALING_BOUNDS) == p) {
obs_bounds_type scaling_type = static_cast<obs_bounds_type>(obs_data_get_int(data, ST_SCALING_BOUNDS));
obs_property_t* p2 = obs_properties_get(pr, ST_SCALING_BOUNDS);
switch (scaling_type) {
case obs_bounds_type::OBS_BOUNDS_STRETCH:
obs_property_set_long_description(p2, P_TRANSLATE(P_DESC(P_SCALING_BOUNDS_STRETCH)));
obs_property_set_long_description(p2, D_TRANSLATE(D_DESC(ST_SCALING_BOUNDS_STRETCH)));
break;
case obs_bounds_type::OBS_BOUNDS_SCALE_INNER:
obs_property_set_long_description(p2, P_TRANSLATE(P_DESC(P_SCALING_BOUNDS_FIT)));
obs_property_set_long_description(p2, D_TRANSLATE(D_DESC(ST_SCALING_BOUNDS_FIT)));
break;
case obs_bounds_type::OBS_BOUNDS_SCALE_OUTER:
obs_property_set_long_description(p2, P_TRANSLATE(P_DESC(P_SCALING_BOUNDS_FILL)));
obs_property_set_long_description(p2, D_TRANSLATE(D_DESC(ST_SCALING_BOUNDS_FILL)));
break;
case obs_bounds_type::OBS_BOUNDS_SCALE_TO_WIDTH:
obs_property_set_long_description(p2, P_TRANSLATE(P_DESC(P_SCALING_BOUNDS_FILLWIDTH)));
obs_property_set_long_description(p2, D_TRANSLATE(D_DESC(ST_SCALING_BOUNDS_FILLWIDTH)));
break;
case obs_bounds_type::OBS_BOUNDS_SCALE_TO_HEIGHT:
obs_property_set_long_description(p2, P_TRANSLATE(P_DESC(P_SCALING_BOUNDS_FILLHEIGHT)));
obs_property_set_long_description(p2, D_TRANSLATE(D_DESC(ST_SCALING_BOUNDS_FILLHEIGHT)));
break;
default:
obs_property_set_long_description(p2, P_TRANSLATE(P_DESC(P_SCALING_BOUNDS)));
obs_property_set_long_description(p2, D_TRANSLATE(D_DESC(ST_SCALING_BOUNDS)));
break;
}
return true;
@ -194,8 +194,8 @@ obs_properties_t* source::mirror::mirror_factory::get_properties(void*)
obs_properties_t* pr = obs_properties_create();
obs_property_t* p = nullptr;
p = obs_properties_add_list(pr, P_SOURCE, P_TRANSLATE(P_SOURCE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SOURCE)));
p = obs_properties_add_list(pr, ST_SOURCE, D_TRANSLATE(ST_SOURCE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SOURCE)));
obs_property_set_modified_callback(p, modified_properties);
obs_property_list_add_string(p, "", "");
obs::source_tracker::get()->enumerate(
@ -211,60 +211,60 @@ obs_properties_t* source::mirror::mirror_factory::get_properties(void*)
},
obs::source_tracker::filter_scenes);
p = obs_properties_add_text(pr, P_SOURCE_SIZE, P_TRANSLATE(P_SOURCE_SIZE), OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SOURCE_SIZE)));
p = obs_properties_add_text(pr, ST_SOURCE_SIZE, D_TRANSLATE(ST_SOURCE_SIZE), OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SOURCE_SIZE)));
obs_property_set_enabled(p, false);
p = obs_properties_add_bool(pr, P_SOURCE_AUDIO, P_TRANSLATE(P_SOURCE_AUDIO));
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SOURCE_AUDIO)));
p = obs_properties_add_bool(pr, ST_AUDIO, D_TRANSLATE(ST_AUDIO));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_AUDIO)));
obs_property_set_modified_callback(p, modified_properties);
p = obs_properties_add_list(pr, ST_AUDIO_LAYOUT, P_TRANSLATE(ST_AUDIO_LAYOUT), OBS_COMBO_TYPE_LIST,
p = obs_properties_add_list(pr, ST_AUDIO_LAYOUT, D_TRANSLATE(ST_AUDIO_LAYOUT), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(p, P_TRANSLATE(ST_AUDIO_LAYOUT_(Unknown)), static_cast<int64_t>(SPEAKERS_UNKNOWN));
obs_property_list_add_int(p, P_TRANSLATE(ST_AUDIO_LAYOUT_(Mono)), static_cast<int64_t>(SPEAKERS_MONO));
obs_property_list_add_int(p, P_TRANSLATE(ST_AUDIO_LAYOUT_(Stereo)), static_cast<int64_t>(SPEAKERS_STEREO));
obs_property_list_add_int(p, P_TRANSLATE(ST_AUDIO_LAYOUT_(StereoLFE)), static_cast<int64_t>(SPEAKERS_2POINT1));
obs_property_list_add_int(p, P_TRANSLATE(ST_AUDIO_LAYOUT_(Quadraphonic)), static_cast<int64_t>(SPEAKERS_4POINT0));
obs_property_list_add_int(p, P_TRANSLATE(ST_AUDIO_LAYOUT_(QuadraphonicLFE)),
obs_property_list_add_int(p, D_TRANSLATE(ST_AUDIO_LAYOUT_(Unknown)), static_cast<int64_t>(SPEAKERS_UNKNOWN));
obs_property_list_add_int(p, D_TRANSLATE(ST_AUDIO_LAYOUT_(Mono)), static_cast<int64_t>(SPEAKERS_MONO));
obs_property_list_add_int(p, D_TRANSLATE(ST_AUDIO_LAYOUT_(Stereo)), static_cast<int64_t>(SPEAKERS_STEREO));
obs_property_list_add_int(p, D_TRANSLATE(ST_AUDIO_LAYOUT_(StereoLFE)), static_cast<int64_t>(SPEAKERS_2POINT1));
obs_property_list_add_int(p, D_TRANSLATE(ST_AUDIO_LAYOUT_(Quadraphonic)), static_cast<int64_t>(SPEAKERS_4POINT0));
obs_property_list_add_int(p, D_TRANSLATE(ST_AUDIO_LAYOUT_(QuadraphonicLFE)),
static_cast<int64_t>(SPEAKERS_4POINT1));
obs_property_list_add_int(p, P_TRANSLATE(ST_AUDIO_LAYOUT_(Surround)), static_cast<int64_t>(SPEAKERS_5POINT1));
obs_property_list_add_int(p, P_TRANSLATE(ST_AUDIO_LAYOUT_(FullSurround)), static_cast<int64_t>(SPEAKERS_7POINT1));
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(ST_AUDIO_LAYOUT)));
obs_property_list_add_int(p, D_TRANSLATE(ST_AUDIO_LAYOUT_(Surround)), static_cast<int64_t>(SPEAKERS_5POINT1));
obs_property_list_add_int(p, D_TRANSLATE(ST_AUDIO_LAYOUT_(FullSurround)), static_cast<int64_t>(SPEAKERS_7POINT1));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_AUDIO_LAYOUT)));
p = obs_properties_add_bool(pr, P_SCALING, P_TRANSLATE(P_SCALING));
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING)));
p = obs_properties_add_bool(pr, ST_SCALING, D_TRANSLATE(ST_SCALING));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALING)));
obs_property_set_modified_callback(p, modified_properties);
p = obs_properties_add_list(pr, P_SCALING_METHOD, P_TRANSLATE(P_SCALING_METHOD), OBS_COMBO_TYPE_LIST,
p = obs_properties_add_list(pr, ST_SCALING_METHOD, D_TRANSLATE(ST_SCALING_METHOD), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_METHOD)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALING_METHOD)));
obs_property_set_modified_callback(p, modified_properties);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_METHOD_POINT), (int64_t)obs_scale_type::OBS_SCALE_POINT);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_METHOD_BILINEAR), (int64_t)obs_scale_type::OBS_SCALE_BILINEAR);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_METHOD_BICUBIC), (int64_t)obs_scale_type::OBS_SCALE_BICUBIC);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_METHOD_LANCZOS), (int64_t)obs_scale_type::OBS_SCALE_LANCZOS);
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_METHOD_POINT), (int64_t)obs_scale_type::OBS_SCALE_POINT);
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_METHOD_BILINEAR), (int64_t)obs_scale_type::OBS_SCALE_BILINEAR);
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_METHOD_BICUBIC), (int64_t)obs_scale_type::OBS_SCALE_BICUBIC);
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_METHOD_LANCZOS), (int64_t)obs_scale_type::OBS_SCALE_LANCZOS);
p = obs_properties_add_text(pr, P_SCALING_SIZE, P_TRANSLATE(P_SCALING_SIZE), OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_SIZE)));
p = obs_properties_add_text(pr, ST_SCALING_SIZE, D_TRANSLATE(ST_SCALING_SIZE), OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALING_SIZE)));
p = obs_properties_add_bool(pr, P_SCALING_TRANSFORMKEEPORIGINAL, P_TRANSLATE(P_SCALING_TRANSFORMKEEPORIGINAL));
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_TRANSFORMKEEPORIGINAL)));
p = obs_properties_add_bool(pr, ST_SCALING_TRANSFORMKEEPORIGINAL, D_TRANSLATE(ST_SCALING_TRANSFORMKEEPORIGINAL));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALING_TRANSFORMKEEPORIGINAL)));
p = obs_properties_add_list(pr, P_SCALING_BOUNDS, P_TRANSLATE(P_SCALING_BOUNDS), OBS_COMBO_TYPE_LIST,
p = obs_properties_add_list(pr, ST_SCALING_BOUNDS, D_TRANSLATE(ST_SCALING_BOUNDS), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_BOUNDS)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALING_BOUNDS)));
obs_property_set_modified_callback(p, modified_properties);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_BOUNDS_STRETCH), (int64_t)obs_bounds_type::OBS_BOUNDS_STRETCH);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_BOUNDS_FIT), (int64_t)obs_bounds_type::OBS_BOUNDS_SCALE_INNER);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_BOUNDS_FILL), (int64_t)obs_bounds_type::OBS_BOUNDS_SCALE_OUTER);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_BOUNDS_FILLWIDTH),
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_BOUNDS_STRETCH), (int64_t)obs_bounds_type::OBS_BOUNDS_STRETCH);
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_BOUNDS_FIT), (int64_t)obs_bounds_type::OBS_BOUNDS_SCALE_INNER);
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_BOUNDS_FILL), (int64_t)obs_bounds_type::OBS_BOUNDS_SCALE_OUTER);
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_BOUNDS_FILLWIDTH),
(int64_t)obs_bounds_type::OBS_BOUNDS_SCALE_TO_WIDTH);
obs_property_list_add_int(p, P_TRANSLATE(P_SCALING_BOUNDS_FILLHEIGHT),
obs_property_list_add_int(p, D_TRANSLATE(ST_SCALING_BOUNDS_FILLHEIGHT),
(int64_t)obs_bounds_type::OBS_BOUNDS_SCALE_TO_HEIGHT);
p = obs_properties_add_list(pr, P_SCALING_ALIGNMENT, P_TRANSLATE(P_SCALING_ALIGNMENT), OBS_COMBO_TYPE_LIST,
p = obs_properties_add_list(pr, ST_SCALING_ALIGNMENT, D_TRANSLATE(ST_SCALING_ALIGNMENT), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_ALIGNMENT)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALING_ALIGNMENT)));
obs_property_list_add_int(p, obs_module_recursive_text("\\@" S_ALIGNMENT_LEFT "\\@ \\@" S_ALIGNMENT_TOP "\\@"),
OBS_ALIGN_LEFT | OBS_ALIGN_TOP);
obs_property_list_add_int(p, obs_module_recursive_text("\\@" S_ALIGNMENT_TOP "\\@"), OBS_ALIGN_TOP);
@ -369,11 +369,11 @@ void source::mirror::mirror_factory::save(void* p, obs_data_t* d)
void source::mirror::mirror_instance::release_input()
{
// Clear any references to the previous source.
if (this->m_source_item) {
obs_sceneitem_remove(this->m_source_item);
this->m_source_item = nullptr;
if (this->_source_item) {
obs_sceneitem_remove(this->_source_item);
this->_source_item = nullptr;
}
this->m_source.reset();
this->_source.reset();
}
void source::mirror::mirror_instance::acquire_input(std::string source_name)
@ -383,14 +383,14 @@ void source::mirror::mirror_instance::acquire_input(std::string source_name)
if (!ref_source) {
// Early-Exit: Unable to find a source with this name, likely has been released.
#ifdef _DEBUG
P_LOG_DEBUG("<Source Mirror:%s> Unable to find target source '%s'.", obs_source_get_name(this->m_self),
P_LOG_DEBUG("<Source Mirror:%s> Unable to find target source '%s'.", obs_source_get_name(this->_self),
source_name.c_str());
#endif
return;
} else if (ref_source == this->m_self) {
} else if (ref_source == this->_self) {
// Early-Exit: Attempted self-mirror (recursion).
#ifdef _DEBUG
P_LOG_DEBUG("<Source Mirror:%s> Attempted to mirror self.", obs_source_get_name(this->m_self));
P_LOG_DEBUG("<Source Mirror:%s> Attempted to mirror _self.", obs_source_get_name(this->_self));
#endif
obs_source_release(ref_source);
return;
@ -399,41 +399,41 @@ void source::mirror::mirror_instance::acquire_input(std::string source_name)
std::shared_ptr<obs::source> new_source = std::make_shared<obs::source>(ref_source, true, false);
// It looks like everything is in order, so continue now.
this->m_source_item = obs_scene_add(obs_scene_from_source(this->m_scene->get()), new_source->get());
if (!this->m_source_item) {
this->_source_item = obs_scene_add(obs_scene_from_source(this->_scene->get()), new_source->get());
if (!this->_source_item) {
// Late-Exit: OBS detected something bad, so no further action will be taken.
#ifdef _DEBUG
P_LOG_DEBUG("<Source Mirror:%s> Attempted recursion with scene '%s'.", obs_source_get_name(this->m_self),
P_LOG_DEBUG("<Source Mirror:%s> Attempted recursion with scene '%s'.", obs_source_get_name(this->_self),
source_name.c_str());
#endif
return;
}
// If everything worked fine, we now set everything up.
this->m_source = new_source;
this->m_source->events.rename += std::bind(&source::mirror::mirror_instance::on_source_rename, this,
this->_source = new_source;
this->_source->events.rename += std::bind(&source::mirror::mirror_instance::on_source_rename, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
if ((obs_source_get_output_flags(this->m_source->get()) & OBS_SOURCE_AUDIO) != 0) {
this->m_source->events.audio_data +=
if ((obs_source_get_output_flags(this->_source->get()) & OBS_SOURCE_AUDIO) != 0) {
this->_source->events.audio_data +=
std::bind(&source::mirror::mirror_instance::on_audio_data, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
}
}
source::mirror::mirror_instance::mirror_instance(obs_data_t*, obs_source_t* src)
: m_self(src), m_active(true), m_tick(0), m_scene_rendered(false), m_rescale_enabled(false), m_rescale_width(1),
m_rescale_height(1), m_rescale_keep_orig_size(false), m_rescale_type(obs_scale_type::OBS_SCALE_BICUBIC),
m_rescale_bounds(obs_bounds_type::OBS_BOUNDS_STRETCH), m_audio_enabled(false), m_audio_kill_thread(false),
m_audio_have_output(false), m_source_item(nullptr)
: _self(src), _active(true), _tick(0), _scene_rendered(false), _rescale_enabled(false), _rescale_width(1),
_rescale_height(1), _rescale_keep_orig_size(false), _rescale_type(obs_scale_type::OBS_SCALE_BICUBIC),
_rescale_bounds(obs_bounds_type::OBS_BOUNDS_STRETCH), _audio_enabled(false), _audio_kill_thread(false),
_audio_have_output(false), _source_item(nullptr)
{
// Initialize Video Rendering
this->m_scene =
this->_scene =
std::make_shared<obs::source>(obs_scene_get_source(obs_scene_create_private("Source Mirror Internal Scene")));
this->m_scene_texture_renderer =
std::make_shared<gfx::source_texture>(this->m_scene, std::make_shared<obs::source>(this->m_self, false, false));
this->_scene_texture_renderer =
std::make_shared<gfx::source_texture>(this->_scene, std::make_shared<obs::source>(this->_self, false, false));
// Initialize Audio Rendering
this->m_audio_thread = std::thread(std::bind(&source::mirror::mirror_instance::audio_output_cb, this));
this->_audio_thread = std::thread(std::bind(&source::mirror::mirror_instance::audio_output_cb, this));
}
source::mirror::mirror_instance::~mirror_instance()
@ -441,27 +441,27 @@ source::mirror::mirror_instance::~mirror_instance()
release_input();
// Finalize Audio Rendering
this->m_audio_kill_thread = true;
this->m_audio_notify.notify_all();
if (this->m_audio_thread.joinable()) {
this->m_audio_thread.join();
this->_audio_kill_thread = true;
this->_audio_notify.notify_all();
if (this->_audio_thread.joinable()) {
this->_audio_thread.join();
}
// Finalize Video Rendering
this->m_scene_texture_renderer.reset();
this->m_scene.reset();
this->_scene_texture_renderer.reset();
this->_scene.reset();
}
uint32_t source::mirror::mirror_instance::get_width()
{
if (m_source) {
if ((obs_source_get_output_flags(this->m_source->get()) & OBS_SOURCE_VIDEO) == 0) {
if (_source) {
if ((obs_source_get_output_flags(this->_source->get()) & OBS_SOURCE_VIDEO) == 0) {
return 0;
}
if (this->m_rescale_enabled && this->m_rescale_width > 0 && !this->m_rescale_keep_orig_size) {
return this->m_rescale_width;
if (this->_rescale_enabled && this->_rescale_width > 0 && !this->_rescale_keep_orig_size) {
return this->_rescale_width;
} else {
return m_source->width();
return _source->width();
}
}
return 0;
@ -469,14 +469,14 @@ uint32_t source::mirror::mirror_instance::get_width()
uint32_t source::mirror::mirror_instance::get_height()
{
if (m_source) {
if ((obs_source_get_output_flags(this->m_source->get()) & OBS_SOURCE_VIDEO) == 0) {
if (_source) {
if ((obs_source_get_output_flags(this->_source->get()) & OBS_SOURCE_VIDEO) == 0) {
return 0;
}
if (this->m_rescale_enabled && this->m_rescale_height > 0 && !this->m_rescale_keep_orig_size) {
return this->m_rescale_height;
if (this->_rescale_enabled && this->_rescale_height > 0 && !this->_rescale_keep_orig_size) {
return this->_rescale_height;
} else {
return m_source->height();
return _source->height();
}
}
return 0;
@ -486,84 +486,84 @@ void source::mirror::mirror_instance::update(obs_data_t* data)
{
{ // User changed the source we are tracking.
release_input();
this->m_source_name = obs_data_get_string(data, P_SOURCE);
if (this->m_source_name.length() > 0) {
acquire_input(this->m_source_name);
this->_source_name = obs_data_get_string(data, ST_SOURCE);
if (this->_source_name.length() > 0) {
acquire_input(this->_source_name);
}
}
// Audio
this->m_audio_enabled = obs_data_get_bool(data, P_SOURCE_AUDIO);
this->m_audio_layout = static_cast<speaker_layout>(obs_data_get_int(data, ST_AUDIO_LAYOUT));
this->_audio_enabled = obs_data_get_bool(data, ST_AUDIO);
this->_audio_layout = static_cast<speaker_layout>(obs_data_get_int(data, ST_AUDIO_LAYOUT));
// Rescaling
this->m_rescale_enabled = obs_data_get_bool(data, P_SCALING);
if (this->m_rescale_enabled) { // Parse rescaling settings.
this->_rescale_enabled = obs_data_get_bool(data, ST_SCALING);
if (this->_rescale_enabled) { // Parse rescaling settings.
uint32_t width, height;
// Read value.
const char* size = obs_data_get_string(data, P_SCALING_SIZE);
const char* size = obs_data_get_string(data, ST_SCALING_SIZE);
const char* xpos = strchr(size, 'x');
if (xpos != nullptr) {
// Width
width = strtoul(size, nullptr, 10);
if (errno == ERANGE || width == 0) {
this->m_rescale_enabled = false;
this->m_rescale_width = 1;
this->_rescale_enabled = false;
this->_rescale_width = 1;
} else {
this->m_rescale_width = width;
this->_rescale_width = width;
}
height = strtoul(xpos + 1, nullptr, 10);
if (errno == ERANGE || height == 0) {
this->m_rescale_enabled = false;
this->m_rescale_height = 1;
this->_rescale_enabled = false;
this->_rescale_height = 1;
} else {
this->m_rescale_height = height;
this->_rescale_height = height;
}
} else {
this->m_rescale_enabled = false;
this->m_rescale_width = 1;
this->m_rescale_height = 1;
this->_rescale_enabled = false;
this->_rescale_width = 1;
this->_rescale_height = 1;
}
this->m_rescale_keep_orig_size = obs_data_get_bool(data, P_SCALING_TRANSFORMKEEPORIGINAL);
this->m_rescale_type = static_cast<obs_scale_type>(obs_data_get_int(data, P_SCALING_METHOD));
this->m_rescale_bounds = static_cast<obs_bounds_type>(obs_data_get_int(data, P_SCALING_BOUNDS));
this->m_rescale_alignment = static_cast<int32_t>(obs_data_get_int(data, P_SCALING_ALIGNMENT));
this->_rescale_keep_orig_size = obs_data_get_bool(data, ST_SCALING_TRANSFORMKEEPORIGINAL);
this->_rescale_type = static_cast<obs_scale_type>(obs_data_get_int(data, ST_SCALING_METHOD));
this->_rescale_bounds = static_cast<obs_bounds_type>(obs_data_get_int(data, ST_SCALING_BOUNDS));
this->_rescale_alignment = static_cast<int32_t>(obs_data_get_int(data, ST_SCALING_ALIGNMENT));
}
}
void source::mirror::mirror_instance::activate()
{
this->m_active = true;
this->_active = true;
// No source, delayed acquire.
if (!this->m_source_item && this->m_source_name.length() > 0) {
this->acquire_input(this->m_source_name.c_str());
if (!this->_source_item && this->_source_name.length() > 0) {
this->acquire_input(this->_source_name.c_str());
}
}
void source::mirror::mirror_instance::deactivate()
{
this->m_active = false;
this->_active = false;
}
void source::mirror::mirror_instance::video_tick(float time)
{
this->m_tick += time;
if (this->m_tick > 0.1f) {
this->m_tick -= 0.1f;
this->_tick += time;
if (this->_tick > 0.1f) {
this->_tick -= 0.1f;
// No source, delayed acquire.
if (!this->m_source_item && this->m_source_name.length() > 0) {
this->acquire_input(this->m_source_name.c_str());
if (!this->_source_item && this->_source_name.length() > 0) {
this->acquire_input(this->_source_name.c_str());
}
}
// Update Scene Item Boundaries
if ((this->m_source_item && this->m_source)
&& ((obs_source_get_output_flags(this->m_source->get()) & OBS_SOURCE_VIDEO) != 0)) {
if ((this->_source_item && this->_source)
&& ((obs_source_get_output_flags(this->_source->get()) & OBS_SOURCE_VIDEO) != 0)) {
obs_transform_info info;
info.pos.x = 0;
info.pos.y = 0;
@ -573,40 +573,40 @@ void source::mirror::mirror_instance::video_tick(float time)
info.alignment = OBS_ALIGN_LEFT | OBS_ALIGN_TOP;
info.bounds.x = float_t(this->get_width());
info.bounds.y = float_t(this->get_height());
info.bounds_alignment = m_rescale_alignment;
info.bounds_alignment = _rescale_alignment;
info.bounds_type = obs_bounds_type::OBS_BOUNDS_STRETCH;
if (this->m_rescale_enabled) {
info.bounds_type = this->m_rescale_bounds;
if (this->_rescale_enabled) {
info.bounds_type = this->_rescale_bounds;
}
obs_sceneitem_set_info(this->m_source_item, &info);
obs_sceneitem_force_update_transform(this->m_source_item);
obs_sceneitem_set_scale_filter(this->m_source_item, this->m_rescale_enabled ? this->m_rescale_type
obs_sceneitem_set_info(this->_source_item, &info);
obs_sceneitem_force_update_transform(this->_source_item);
obs_sceneitem_set_scale_filter(this->_source_item, this->_rescale_enabled ? this->_rescale_type
: obs_scale_type::OBS_SCALE_POINT);
}
m_scene_rendered = false;
_scene_rendered = false;
}
void source::mirror::mirror_instance::video_render(gs_effect_t* effect)
{
if ((this->m_rescale_width == 0) || (this->m_rescale_height == 0) || !this->m_source_item
|| !this->m_scene_texture_renderer || !this->m_source) {
if ((this->_rescale_width == 0) || (this->_rescale_height == 0) || !this->_source_item
|| !this->_scene_texture_renderer || !this->_source) {
return;
}
// Don't bother rendering sources that aren't video.
if ((obs_source_get_output_flags(this->m_source->get()) & OBS_SOURCE_VIDEO) == 0) {
if ((obs_source_get_output_flags(this->_source->get()) & OBS_SOURCE_VIDEO) == 0) {
return;
}
// Only re-render the scene if there was a video_tick, saves GPU cycles.
if (!m_scene_rendered) {
if (!_scene_rendered) {
// Override render size if rescaling is enabled.
uint32_t render_width = this->m_source->width();
uint32_t render_height = this->m_source->height();
if (m_rescale_enabled) {
render_width = m_rescale_width;
render_height = m_rescale_height;
uint32_t render_width = this->_source->width();
uint32_t render_height = this->_source->height();
if (_rescale_enabled) {
render_width = _rescale_width;
render_height = _rescale_height;
}
if (!render_width || !render_height) {
@ -615,56 +615,56 @@ void source::mirror::mirror_instance::video_render(gs_effect_t* effect)
}
try {
m_scene_texture = this->m_scene_texture_renderer->render(render_width, render_height);
m_scene_rendered = true;
_scene_texture = this->_scene_texture_renderer->render(render_width, render_height);
_scene_rendered = true;
} catch (...) {
// If we fail to render the source, just render nothing.
return;
}
}
if (m_scene_texture) {
if (_scene_texture) {
// Use default effect unless we are provided a different effect.
if (!effect) {
effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
}
// Render the cached scene texture.
gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), m_scene_texture->get_object());
gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), _scene_texture->get_object());
while (gs_effect_loop(effect, "Draw")) {
gs_draw_sprite(m_scene_texture->get_object(), 0, this->get_width(), this->get_height());
gs_draw_sprite(_scene_texture->get_object(), 0, this->get_width(), this->get_height());
}
}
}
void source::mirror::mirror_instance::audio_output_cb()
{
std::unique_lock<std::mutex> ulock(this->m_audio_lock_outputter);
std::unique_lock<std::mutex> ulock(this->_audio_lock_outputter);
while (!this->m_audio_kill_thread) {
this->m_audio_notify.wait(ulock, [this]() { return this->m_audio_have_output || this->m_audio_kill_thread; });
while (!this->_audio_kill_thread) {
this->_audio_notify.wait(ulock, [this]() { return this->_audio_have_output || this->_audio_kill_thread; });
if (this->m_audio_have_output) { // Get used audio element
if (this->_audio_have_output) { // Get used audio element
std::shared_ptr<mirror_audio_data> mad;
{
std::lock_guard<std::mutex> capture_lock(this->m_audio_lock_capturer);
if (m_audio_data_queue.size() > 0) {
mad = m_audio_data_queue.front();
m_audio_data_queue.pop();
std::lock_guard<std::mutex> capture_lock(this->_audio_lock_capturer);
if (_audio_data_queue.size() > 0) {
mad = _audio_data_queue.front();
_audio_data_queue.pop();
}
if (m_audio_data_queue.size() == 0) {
this->m_audio_have_output = false;
if (_audio_data_queue.size() == 0) {
this->_audio_have_output = false;
}
}
if (mad) {
ulock.unlock();
obs_source_output_audio(this->m_self, &mad->audio);
obs_source_output_audio(this->_self, &mad->audio);
ulock.lock();
{
std::lock_guard<std::mutex> capture_lock(this->m_audio_lock_capturer);
m_audio_data_free_queue.push(mad);
std::lock_guard<std::mutex> capture_lock(this->_audio_lock_capturer);
_audio_data_free_queue.push(mad);
}
}
}
@ -673,8 +673,8 @@ void source::mirror::mirror_instance::audio_output_cb()
void source::mirror::mirror_instance::enum_active_sources(obs_source_enum_proc_t enum_callback, void* param)
{
if (this->m_scene) {
enum_callback(this->m_self, this->m_scene->get(), param);
if (this->_scene) {
enum_callback(this->_self, this->_scene->get(), param);
}
}
@ -685,23 +685,23 @@ void source::mirror::mirror_instance::load(obs_data_t* data)
void source::mirror::mirror_instance::save(obs_data_t* data)
{
if (!this->m_source_item || !this->m_source) {
if (!this->_source_item || !this->_source) {
return;
}
obs_data_set_string(data, P_SOURCE, obs_source_get_name(m_source->get()));
obs_data_set_string(data, ST_SOURCE, obs_source_get_name(_source->get()));
}
void source::mirror::mirror_instance::on_source_rename(obs::source* source, std::string, std::string)
{
obs_data_t* ref = obs_source_get_settings(this->m_self);
obs_data_set_string(ref, P_SOURCE, obs_source_get_name(source->get()));
obs_source_update(this->m_self, ref);
obs_data_t* ref = obs_source_get_settings(this->_self);
obs_data_set_string(ref, ST_SOURCE, obs_source_get_name(source->get()));
obs_source_update(this->_self, ref);
obs_data_release(ref);
}
void source::mirror::mirror_instance::on_audio_data(obs::source*, const audio_data* audio, bool)
{
if (!this->m_audio_enabled) {
if (!this->_audio_enabled) {
return;
}
@ -716,10 +716,10 @@ void source::mirror::mirror_instance::on_audio_data(obs::source*, const audio_da
std::shared_ptr<mirror_audio_data> mad;
{ // Get free audio data element.
std::lock_guard<std::mutex> capture_lock(this->m_audio_lock_capturer);
if (m_audio_data_free_queue.size() > 0) {
mad = m_audio_data_free_queue.front();
m_audio_data_free_queue.pop();
std::lock_guard<std::mutex> capture_lock(this->_audio_lock_capturer);
if (_audio_data_free_queue.size() > 0) {
mad = _audio_data_free_queue.front();
_audio_data_free_queue.pop();
} else {
mad = std::make_shared<mirror_audio_data>();
mad->data.resize(MAX_AUDIO_CHANNELS);
@ -746,21 +746,21 @@ void source::mirror::mirror_instance::on_audio_data(obs::source*, const audio_da
mad->audio.frames = audio->frames;
mad->audio.timestamp = audio->timestamp;
mad->audio.samples_per_sec = aoi->samples_per_sec;
if (this->m_audio_layout != SPEAKERS_UNKNOWN) {
mad->audio.speakers = this->m_audio_layout;
if (this->_audio_layout != SPEAKERS_UNKNOWN) {
mad->audio.speakers = this->_audio_layout;
} else {
mad->audio.speakers = aoi->speakers;
}
}
{ // Push used audio data element.
std::lock_guard<std::mutex> capture_lock(this->m_audio_lock_capturer);
m_audio_data_queue.push(mad);
std::lock_guard<std::mutex> capture_lock(this->_audio_lock_capturer);
_audio_data_queue.push(mad);
}
{ // Signal other side.
std::lock_guard<std::mutex> output_lock(this->m_audio_lock_outputter);
this->m_audio_have_output = true;
std::lock_guard<std::mutex> output_lock(this->_audio_lock_outputter);
this->_audio_have_output = true;
}
this->m_audio_notify.notify_all();
this->_audio_notify.notify_all();
}

View file

@ -43,7 +43,7 @@
namespace source {
namespace mirror {
class mirror_factory {
obs_source_info osi;
obs_source_info _source_info;
public: // Singleton
static void initialize();
@ -81,41 +81,41 @@ namespace source {
};
class mirror_instance {
obs_source_t* m_self;
bool m_active;
float_t m_tick;
obs_source_t* _self;
bool _active;
float_t _tick;
// Video Rendering
std::shared_ptr<obs::source> m_scene;
std::shared_ptr<gfx::source_texture> m_scene_texture_renderer;
std::shared_ptr<gs::texture> m_scene_texture;
bool m_scene_rendered;
int m_rescale_alignment;
std::shared_ptr<obs::source> _scene;
std::shared_ptr<gfx::source_texture> _scene_texture_renderer;
std::shared_ptr<gs::texture> _scene_texture;
bool _scene_rendered;
int _rescale_alignment;
// Rescaling
bool m_rescale_enabled;
uint32_t m_rescale_width;
uint32_t m_rescale_height;
bool m_rescale_keep_orig_size;
obs_scale_type m_rescale_type;
obs_bounds_type m_rescale_bounds;
bool _rescale_enabled;
uint32_t _rescale_width;
uint32_t _rescale_height;
bool _rescale_keep_orig_size;
obs_scale_type _rescale_type;
obs_bounds_type _rescale_bounds;
// Audio Rendering
bool m_audio_enabled;
std::condition_variable m_audio_notify;
std::thread m_audio_thread;
bool m_audio_kill_thread;
bool m_audio_have_output;
std::mutex m_audio_lock_outputter;
std::mutex m_audio_lock_capturer;
std::queue<std::shared_ptr<mirror_audio_data>> m_audio_data_queue;
std::queue<std::shared_ptr<mirror_audio_data>> m_audio_data_free_queue;
speaker_layout m_audio_layout;
bool _audio_enabled;
std::condition_variable _audio_notify;
std::thread _audio_thread;
bool _audio_kill_thread;
bool _audio_have_output;
std::mutex _audio_lock_outputter;
std::mutex _audio_lock_capturer;
std::queue<std::shared_ptr<mirror_audio_data>> _audio_data_queue;
std::queue<std::shared_ptr<mirror_audio_data>> _audio_data_free_queue;
speaker_layout _audio_layout;
// Input
std::shared_ptr<obs::source> m_source;
obs_sceneitem_t* m_source_item;
std::string m_source_name;
std::shared_ptr<obs::source> _source;
obs_sceneitem_t* _source_item;
std::string _source_name;
private:
void release_input();

View file

@ -20,14 +20,14 @@
#pragma once
#include "plugin.hpp"
#define P_TRANSLATE(x) obs_module_text(x)
#define P_DESC(x) x ".Description"
#define D_TRANSLATE(x) obs_module_text(x)
#define D_DESC(x) x ".Description"
#define T_FILEFILTERS_IMAGE "*.png *.webp *.tga *.tiff *.jpeg *.jpg *.bmp"
#define T_FILEFILTERS_VIDEO "*.mkv *.webm *.mp4 *.mov *.flv"
#define T_FILEFILTERS_SOUND "*.ogg *.flac *.mp3 *.wav"
#define T_FILEFILTERS_EFFECT "*.effect *.txt"
#define T_FILEFILTERS_ANY "*.*"
#define S_FILEFILTERS_IMAGE "*.png *.webp *.tga *.tiff *.jpeg *.jpg *.bmp"
#define S_FILEFILTERS_VIDEO "*.mkv *.webm *.mp4 *.mov *.flv"
#define S_FILEFILTERS_SOUND "*.ogg *.flac *.mp3 *.wav"
#define S_FILEFILTERS_EFFECT "*.effect *.txt"
#define S_FILEFILTERS_ANY "*.*"
#define S_VERSION "Version"

View file

@ -36,14 +36,14 @@
#endif
// Constants
#define PI 3.1415926535897932384626433832795 // PI = pi
#define PI2 6.283185307179586476925286766559 // 2PI = 2 * pi
#define PI2_SQROOT 2.506628274631000502415765284811 // sqrt(2 * pi)
#define S_PI 3.1415926535897932384626433832795 // PI = pi
#define S_PI2 6.283185307179586476925286766559 // 2PI = 2 * pi
#define S_PI2_SQROOT 2.506628274631000502415765284811 // sqrt(2 * pi)
#define V_RAD 57.295779513082320876798154814105 // 180/pi
#define V_DEG 0.01745329251994329576923690768489 // pi/180
#define DEG_TO_RAD(x) (x * V_DEG)
#define RAD_TO_DEG(x) (x * V_RAD)
#define S_RAD 57.295779513082320876798154814105 // 180/pi
#define S_DEG 0.01745329251994329576923690768489 // pi/180
#define D_DEG_TO_RAD(x) (x * S_DEG)
#define D_RAD_TO_DEG(x) (x * S_RAD)
inline size_t GetNearestPowerOfTwoAbove(size_t v)
{
@ -114,23 +114,23 @@ namespace util {
return true;
}
#pragma push_macro("is_power_of_two_as_loop")
#define is_power_of_two_as_loop(x) \
#pragma push_macro("P_IS_POWER_OF_TWO_AS_LOOP")
#define P_IS_POWER_OF_TWO_AS_LOOP(x) \
template<> \
inline bool is_power_of_two(x v) \
{ \
return is_power_of_two_loop(v); \
}
is_power_of_two_as_loop(int8_t);
is_power_of_two_as_loop(uint8_t);
is_power_of_two_as_loop(int16_t);
is_power_of_two_as_loop(uint16_t);
is_power_of_two_as_loop(int32_t);
is_power_of_two_as_loop(uint32_t);
is_power_of_two_as_loop(int64_t);
is_power_of_two_as_loop(uint64_t);
#undef is_power_of_two_as_loop
#pragma pop_macro("is_power_of_two_as_loop")
P_IS_POWER_OF_TWO_AS_LOOP(int8_t);
P_IS_POWER_OF_TWO_AS_LOOP(uint8_t);
P_IS_POWER_OF_TWO_AS_LOOP(int16_t);
P_IS_POWER_OF_TWO_AS_LOOP(uint16_t);
P_IS_POWER_OF_TWO_AS_LOOP(int32_t);
P_IS_POWER_OF_TWO_AS_LOOP(uint32_t);
P_IS_POWER_OF_TWO_AS_LOOP(int64_t);
P_IS_POWER_OF_TWO_AS_LOOP(uint64_t);
#undef P_IS_POWER_OF_TWO_AS_LOOP
#pragma pop_macro("P_IS_POWER_OF_TWO_AS_LOOP")
template<typename T>
inline uint64_t get_power_of_two_exponent_floor(T v)

View file

@ -22,10 +22,18 @@
#define USE_STD_ALLOC_FREE
#ifdef _MSC_VER
#define D_ALIGNED_ALLOC(a, s) _aligned_malloc(s, a)
#define D_ALIGNED_FREE _aligned_free
#else
#define D_ALIGNED_ALLOC(a, s) aligned_alloc(s, a)
#define D_ALIGNED_FREE free
#endif
void* util::malloc_aligned(size_t align, size_t size)
{
#ifdef USE_STD_ALLOC_FREE
return aligned_alloc(align, size);
return D_ALIGNED_ALLOC(align, size);
#else
// Ensure that we have space for the pointer and the data.
size_t asize = aligned_offset(align, size + (sizeof(void*) * 2));
@ -47,7 +55,7 @@ void* util::malloc_aligned(size_t align, size_t size)
void util::free_aligned(void* mem)
{
#ifdef USE_STD_ALLOC_FREE
aligned_free(mem);
D_ALIGNED_FREE(mem);
#else
void* ptr = reinterpret_cast<void*>(*reinterpret_cast<intptr_t*>(static_cast<char*>(mem) - sizeof(void*)));
free(ptr);

View file

@ -48,7 +48,7 @@ typename std::enable_if<enable_bitmask_operators<Enum>::enable, Enum>::type oper
return static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
}
#define ENABLE_BITMASK_OPERATORS(x) \
#define P_ENABLE_BITMASK_OPERATORS(x) \
template<> \
struct enable_bitmask_operators<x> { \
static const bool enable = true; \
@ -58,7 +58,7 @@ typename std::enable_if<enable_bitmask_operators<Enum>::enable, Enum>::type oper
#define D_VSTR(s) D_STR(s)
#ifdef __cplusplus
#define INITIALIZER(f) \
#define P_INITIALIZER(f) \
static void f(void); \
struct f##_t_ { \
f##_t_(void) \
@ -75,12 +75,12 @@ typename std::enable_if<enable_bitmask_operators<Enum>::enable, Enum>::type oper
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker, "/include:" p #f "_")) static void f(void)
#ifdef _WIN64
#define INITIALIZER(f) INITIALIZER2_(f, "")
#define P_INITIALIZER(f) INITIALIZER2_(f, "")
#else
#define INITIALIZER(f) INITIALIZER2_(f, "_")
#define P_INITIALIZER(f) INITIALIZER2_(f, "_")
#endif
#else
#define INITIALIZER(f) \
#define P_INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#endif