mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-10 22:05:06 +00:00
project: Apply new coding guidelines
This commit is contained in:
parent
b6a3dea3f6
commit
0e350415b3
55 changed files with 2365 additions and 2357 deletions
File diff suppressed because it is too large
Load diff
|
@ -52,12 +52,12 @@ namespace filter {
|
||||||
};
|
};
|
||||||
|
|
||||||
class blur_factory {
|
class blur_factory {
|
||||||
obs_source_info source_info;
|
obs_source_info _source_info;
|
||||||
std::list<blur_instance*> sources;
|
std::list<blur_instance*> _sources;
|
||||||
std::shared_ptr<gs::effect> color_converter_effect;
|
std::shared_ptr<gs::effect> _color_converter_effect;
|
||||||
std::shared_ptr<gs::effect> mask_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
|
public: // Singleton
|
||||||
static void initialize();
|
static void initialize();
|
||||||
|
@ -98,25 +98,25 @@ namespace filter {
|
||||||
};
|
};
|
||||||
|
|
||||||
class blur_instance {
|
class blur_instance {
|
||||||
obs_source_t* m_self;
|
obs_source_t* _self;
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
std::shared_ptr<gs::rendertarget> m_source_rt;
|
std::shared_ptr<gs::rendertarget> _source_rt;
|
||||||
std::shared_ptr<gs::texture> m_source_texture;
|
std::shared_ptr<gs::texture> _source_texture;
|
||||||
bool m_source_rendered;
|
bool _source_rendered;
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
std::shared_ptr<gs::texture> m_output_texture;
|
std::shared_ptr<gs::texture> _output_texture;
|
||||||
std::shared_ptr<gs::rendertarget> m_output_rt;
|
std::shared_ptr<gs::rendertarget> _output_rt;
|
||||||
bool m_output_rendered;
|
bool _output_rendered;
|
||||||
|
|
||||||
// Blur
|
// Blur
|
||||||
std::shared_ptr<::gfx::blur::ibase> m_blur;
|
std::shared_ptr<::gfx::blur::base> _blur;
|
||||||
double_t m_blur_size;
|
double_t _blur_size;
|
||||||
double_t m_blur_angle;
|
double_t _blur_angle;
|
||||||
std::pair<double_t, double_t> m_blur_center;
|
std::pair<double_t, double_t> _blur_center;
|
||||||
bool m_blur_step_scaling;
|
bool _blur_step_scaling;
|
||||||
std::pair<double_t, double_t> m_blur_step_scale;
|
std::pair<double_t, double_t> _blur_step_scale;
|
||||||
|
|
||||||
// Masking
|
// Masking
|
||||||
struct {
|
struct {
|
||||||
|
@ -150,7 +150,7 @@ namespace filter {
|
||||||
float_t a;
|
float_t a;
|
||||||
} color;
|
} color;
|
||||||
float_t multiplier;
|
float_t multiplier;
|
||||||
} m_mask;
|
} _mask;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
blur_instance(obs_data_t* settings, obs_source_t* self);
|
blur_instance(obs_data_t* settings, obs_source_t* self);
|
||||||
|
|
|
@ -61,15 +61,15 @@
|
||||||
#define TONE_HIG Highlight
|
#define TONE_HIG Highlight
|
||||||
|
|
||||||
// Initializer & Finalizer
|
// Initializer & Finalizer
|
||||||
INITIALIZER(FilterColorGradeInit)
|
P_INITIALIZER(FilterColorGradeInit)
|
||||||
{
|
{
|
||||||
initializerFunctions.push_back([] { filter::color_grade::color_grade_factory::initialize(); });
|
initializer_functions.push_back([] { filter::color_grade::color_grade_factory::initialize(); });
|
||||||
finalizerFunctions.push_back([] { filter::color_grade::color_grade_factory::finalize(); });
|
finalizer_functions.push_back([] { filter::color_grade::color_grade_factory::finalize(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* get_name(void*)
|
const char* get_name(void*)
|
||||||
{
|
{
|
||||||
return P_TRANSLATE(ST);
|
return D_TRANSLATE(ST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_defaults(obs_data_t* data)
|
void get_defaults(obs_data_t* data)
|
||||||
|
@ -152,13 +152,13 @@ obs_properties_t* get_properties(void*)
|
||||||
|
|
||||||
if (util::are_property_groups_broken()) {
|
if (util::are_property_groups_broken()) {
|
||||||
auto p =
|
auto p =
|
||||||
obs_properties_add_list(pr, ST_TOOL, P_TRANSLATE(ST_TOOL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
|
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, P_TRANSLATE(ST_LIFT), ST_LIFT);
|
obs_property_list_add_string(p, D_TRANSLATE(ST_LIFT), ST_LIFT);
|
||||||
obs_property_list_add_string(p, P_TRANSLATE(ST_GAMMA), ST_GAMMA);
|
obs_property_list_add_string(p, D_TRANSLATE(ST_GAMMA), ST_GAMMA);
|
||||||
obs_property_list_add_string(p, P_TRANSLATE(ST_GAIN), ST_GAIN);
|
obs_property_list_add_string(p, D_TRANSLATE(ST_GAIN), ST_GAIN);
|
||||||
obs_property_list_add_string(p, P_TRANSLATE(ST_OFFSET), ST_OFFSET);
|
obs_property_list_add_string(p, D_TRANSLATE(ST_OFFSET), ST_OFFSET);
|
||||||
obs_property_list_add_string(p, P_TRANSLATE(ST_TINT), ST_TINT);
|
obs_property_list_add_string(p, D_TRANSLATE(ST_TINT), ST_TINT);
|
||||||
obs_property_list_add_string(p, P_TRANSLATE(ST_CORRECTION), ST_CORRECTION);
|
obs_property_list_add_string(p, D_TRANSLATE(ST_CORRECTION), ST_CORRECTION);
|
||||||
obs_property_set_modified_callback(p, &tool_modified);
|
obs_property_set_modified_callback(p, &tool_modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,80 +166,80 @@ obs_properties_t* get_properties(void*)
|
||||||
obs_properties_t* grp = pr;
|
obs_properties_t* grp = pr;
|
||||||
if (!util::are_property_groups_broken()) {
|
if (!util::are_property_groups_broken()) {
|
||||||
grp = obs_properties_create();
|
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_(RED), D_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_(GREEN), D_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_(BLUE), D_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_(ALL), D_TRANSLATE(ST_LIFT_(ALL)), -1000.0, 1000.0, 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
obs_properties_t* grp = pr;
|
obs_properties_t* grp = pr;
|
||||||
if (!util::are_property_groups_broken()) {
|
if (!util::are_property_groups_broken()) {
|
||||||
grp = obs_properties_create();
|
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_(RED), D_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_(GREEN), D_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_(BLUE), D_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_(ALL), D_TRANSLATE(ST_GAMMA_(ALL)), -1000.0, 1000.0, 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
obs_properties_t* grp = pr;
|
obs_properties_t* grp = pr;
|
||||||
if (!util::are_property_groups_broken()) {
|
if (!util::are_property_groups_broken()) {
|
||||||
grp = obs_properties_create();
|
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_(RED), D_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_(GREEN), D_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_(BLUE), D_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_(ALL), D_TRANSLATE(ST_GAIN_(ALL)), 0.01, 1000.0, 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
obs_properties_t* grp = pr;
|
obs_properties_t* grp = pr;
|
||||||
if (!util::are_property_groups_broken()) {
|
if (!util::are_property_groups_broken()) {
|
||||||
grp = obs_properties_create();
|
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_(RED), D_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_(GREEN), D_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_(BLUE), D_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_(ALL), D_TRANSLATE(ST_OFFSET_(ALL)), -1000.0, 1000.0, 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
obs_properties_t* grp = pr;
|
obs_properties_t* grp = pr;
|
||||||
if (!util::are_property_groups_broken()) {
|
if (!util::are_property_groups_broken()) {
|
||||||
grp = obs_properties_create();
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,15 +247,15 @@ obs_properties_t* get_properties(void*)
|
||||||
obs_properties_t* grp = pr;
|
obs_properties_t* grp = pr;
|
||||||
if (!util::are_property_groups_broken()) {
|
if (!util::are_property_groups_broken()) {
|
||||||
grp = obs_properties_create();
|
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_(HUE), D_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_(SATURATION), D_TRANSLATE(ST_CORRECTION_(SATURATION)), 0.0,
|
||||||
1000.0, 0.01);
|
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);
|
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);
|
1000.0, 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,12 +374,12 @@ filter::color_grade::color_grade_instance::color_grade_instance(obs_data_t* data
|
||||||
update(data);
|
update(data);
|
||||||
|
|
||||||
{
|
{
|
||||||
char* file = obs_module_file("effects/color-grade.effect");
|
char* file = obs_module_file("effects/color-grade._effect");
|
||||||
try {
|
try {
|
||||||
_effect = std::make_shared<gs::effect>(file);
|
_effect = std::make_shared<gs::effect>(file);
|
||||||
bfree(file);
|
bfree(file);
|
||||||
} catch (std::runtime_error& ex) {
|
} 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);
|
bfree(file);
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,10 +59,10 @@
|
||||||
enum class ShaderType : int64_t { Text, File };
|
enum class ShaderType : int64_t { Text, File };
|
||||||
|
|
||||||
static filter::CustomShader* handler;
|
static filter::CustomShader* handler;
|
||||||
INITIALIZER(HandlerInit)
|
P_INITIALIZER(HandlerInit)
|
||||||
{
|
{
|
||||||
initializerFunctions.push_back([] { handler = new filter::CustomShader(); });
|
initializer_functions.push_back([] { handler = new filter::CustomShader(); });
|
||||||
finalizerFunctions.push_back([] { delete handler; });
|
finalizer_functions.push_back([] { delete handler; });
|
||||||
}
|
}
|
||||||
|
|
||||||
filter::CustomShader::CustomShader()
|
filter::CustomShader::CustomShader()
|
||||||
|
@ -91,7 +91,7 @@ filter::CustomShader::~CustomShader() {}
|
||||||
|
|
||||||
const char* filter::CustomShader::get_name(void*)
|
const char* filter::CustomShader::get_name(void*)
|
||||||
{
|
{
|
||||||
return P_TRANSLATE(S);
|
return D_TRANSLATE(S);
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::CustomShader::get_defaults(obs_data_t* data)
|
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)
|
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);
|
m_renderTarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
update(data);
|
update(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,17 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "strings.hpp"
|
#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 & Finalizer
|
||||||
INITIALIZER(FilterDisplacementInit)
|
P_INITIALIZER(FilterDisplacementInit)
|
||||||
{
|
{
|
||||||
initializerFunctions.push_back([] { filter::displacement::displacement_factory::initialize(); });
|
initializer_functions.push_back([] { filter::displacement::displacement_factory::initialize(); });
|
||||||
finalizerFunctions.push_back([] { filter::displacement::displacement_factory::finalize(); });
|
finalizer_functions.push_back([] { filter::displacement::displacement_factory::finalize(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<filter::displacement::displacement_factory> factory_instance = nullptr;
|
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()
|
filter::displacement::displacement_factory::displacement_factory()
|
||||||
{
|
{
|
||||||
memset(&sourceInfo, 0, sizeof(obs_source_info));
|
memset(&_source_info, 0, sizeof(obs_source_info));
|
||||||
sourceInfo.id = "obs-stream-effects-filter-displacement";
|
_source_info.id = "obs-stream-effects-filter-displacement";
|
||||||
sourceInfo.type = OBS_SOURCE_TYPE_FILTER;
|
_source_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
sourceInfo.output_flags = OBS_SOURCE_VIDEO;
|
_source_info.output_flags = OBS_SOURCE_VIDEO;
|
||||||
sourceInfo.get_name = get_name;
|
_source_info.get_name = get_name;
|
||||||
sourceInfo.get_defaults = get_defaults;
|
_source_info.get_defaults = get_defaults;
|
||||||
sourceInfo.get_properties = get_properties;
|
_source_info.get_properties = get_properties;
|
||||||
|
|
||||||
sourceInfo.create = create;
|
_source_info.create = create;
|
||||||
sourceInfo.destroy = destroy;
|
_source_info.destroy = destroy;
|
||||||
sourceInfo.update = update;
|
_source_info.update = update;
|
||||||
sourceInfo.activate = activate;
|
_source_info.activate = activate;
|
||||||
sourceInfo.deactivate = deactivate;
|
_source_info.deactivate = deactivate;
|
||||||
sourceInfo.show = show;
|
_source_info.show = show;
|
||||||
sourceInfo.hide = hide;
|
_source_info.hide = hide;
|
||||||
sourceInfo.video_tick = video_tick;
|
_source_info.video_tick = video_tick;
|
||||||
sourceInfo.video_render = video_render;
|
_source_info.video_render = video_render;
|
||||||
|
|
||||||
obs_register_source(&sourceInfo);
|
obs_register_source(&_source_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
filter::displacement::displacement_factory::~displacement_factory() {}
|
filter::displacement::displacement_factory::~displacement_factory() {}
|
||||||
|
|
||||||
const char* filter::displacement::displacement_factory::get_name(void*)
|
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)
|
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)
|
void filter::displacement::displacement_factory::get_defaults(obs_data_t* data)
|
||||||
{
|
{
|
||||||
char* disp = obs_module_file("filter-displacement/neutral.png");
|
char* disp = obs_module_file("filter-displacement/neutral.png");
|
||||||
obs_data_set_default_string(data, S_FILTER_DISPLACEMENT_FILE, disp);
|
obs_data_set_default_string(data, ST_FILE, disp);
|
||||||
obs_data_set_default_double(data, S_FILTER_DISPLACEMENT_RATIO, 0);
|
obs_data_set_default_double(data, ST_RATIO, 0);
|
||||||
obs_data_set_default_double(data, S_FILTER_DISPLACEMENT_SCALE, 0);
|
obs_data_set_default_double(data, ST_SCALE, 0);
|
||||||
bfree(disp);
|
bfree(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,11 +118,11 @@ obs_properties_t* filter::displacement::displacement_factory::get_properties(voi
|
||||||
if (ptr)
|
if (ptr)
|
||||||
path = reinterpret_cast<displacement_instance*>(ptr)->get_file();
|
path = reinterpret_cast<displacement_instance*>(ptr)->get_file();
|
||||||
|
|
||||||
obs_properties_add_path(pr, S_FILTER_DISPLACEMENT_FILE, P_TRANSLATE(S_FILTER_DISPLACEMENT_FILE),
|
obs_properties_add_path(pr, ST_FILE, D_TRANSLATE(ST_FILE),
|
||||||
obs_path_type::OBS_PATH_FILE, P_TRANSLATE(S_FILTER_DISPLACEMENT_FILE_TYPES), path.c_str());
|
obs_path_type::OBS_PATH_FILE, D_TRANSLATE(ST_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_float_slider(pr, ST_RATIO, D_TRANSLATE(ST_RATIO), 0, 1,
|
||||||
0.01);
|
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);
|
1000, 0.01);
|
||||||
return pr;
|
return pr;
|
||||||
}
|
}
|
||||||
|
@ -166,41 +172,41 @@ void filter::displacement::displacement_instance::validate_file_texture(std::str
|
||||||
}
|
}
|
||||||
|
|
||||||
// File name different
|
// File name different
|
||||||
if (file != m_file_name) {
|
if (file != _file_name) {
|
||||||
do_update = true;
|
do_update = true;
|
||||||
m_file_name = file;
|
_file_name = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timestamp verification
|
// Timestamp verification
|
||||||
struct stat stats;
|
struct stat stats;
|
||||||
if (os_stat(m_file_name.c_str(), &stats) != 0) {
|
if (os_stat(_file_name.c_str(), &stats) != 0) {
|
||||||
do_update = do_update || (stats.st_ctime != m_file_create_time);
|
do_update = do_update || (stats.st_ctime != _file_create_time);
|
||||||
do_update = do_update || (stats.st_mtime != m_file_modified_time);
|
do_update = do_update || (stats.st_mtime != _file_modified_time);
|
||||||
do_update = do_update || (static_cast<size_t>(stats.st_size) != m_file_size);
|
do_update = do_update || (static_cast<size_t>(stats.st_size) != _file_size);
|
||||||
m_file_create_time = stats.st_ctime;
|
_file_create_time = stats.st_ctime;
|
||||||
m_file_modified_time = stats.st_mtime;
|
_file_modified_time = stats.st_mtime;
|
||||||
m_file_size = static_cast<size_t>(stats.st_size);
|
_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) {
|
if (do_update) {
|
||||||
try {
|
try {
|
||||||
m_file_texture = std::make_shared<gs::texture>(m_file_name);
|
_file_texture = std::make_shared<gs::texture>(_file_name);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filter::displacement::displacement_instance::displacement_instance(obs_data_t* data, obs_source_t* context)
|
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),
|
: _self(context), _timer(0), _effect(nullptr), _distance(0), _file_create_time(0), _file_modified_time(0),
|
||||||
m_file_size(0)
|
_file_size(0)
|
||||||
{
|
{
|
||||||
char* effectFile = obs_module_file("effects/displace.effect");
|
char* effectFile = obs_module_file("effects/displace._effect");
|
||||||
try {
|
try {
|
||||||
m_effect = std::make_shared<gs::effect>(effectFile);
|
_effect = std::make_shared<gs::effect>(effectFile);
|
||||||
} catch (...) {
|
} 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);
|
bfree(effectFile);
|
||||||
|
|
||||||
|
@ -209,17 +215,17 @@ filter::displacement::displacement_instance::displacement_instance(obs_data_t* d
|
||||||
|
|
||||||
filter::displacement::displacement_instance::~displacement_instance()
|
filter::displacement::displacement_instance::~displacement_instance()
|
||||||
{
|
{
|
||||||
m_effect.reset();
|
_effect.reset();
|
||||||
m_file_texture.reset();
|
_file_texture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::displacement::displacement_instance::update(obs_data_t* data)
|
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));
|
_distance = float_t(obs_data_get_double(data, ST_RATIO));
|
||||||
vec2_set(&m_displacement_scale, float_t(obs_data_get_double(data, S_FILTER_DISPLACEMENT_SCALE)),
|
vec2_set(&_displacement_scale, float_t(obs_data_get_double(data, ST_SCALE)),
|
||||||
float_t(obs_data_get_double(data, S_FILTER_DISPLACEMENT_SCALE)));
|
float_t(obs_data_get_double(data, ST_SCALE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t filter::displacement::displacement_instance::get_width()
|
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)
|
void filter::displacement::displacement_instance::video_tick(float time)
|
||||||
{
|
{
|
||||||
m_timer += time;
|
_timer += time;
|
||||||
if (m_timer >= 1.0f) {
|
if (_timer >= 1.0f) {
|
||||||
m_timer -= 1.0f;
|
_timer -= 1.0f;
|
||||||
validate_file_texture(m_file_name);
|
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*)
|
void filter::displacement::displacement_instance::video_render(gs_effect_t*)
|
||||||
{
|
{
|
||||||
obs_source_t* parent = obs_filter_get_parent(m_self);
|
obs_source_t* parent = obs_filter_get_parent(_self);
|
||||||
obs_source_t* target = obs_filter_get_target(m_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);
|
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.
|
// Skip rendering if our target, parent or context is not valid.
|
||||||
if (!parent || !target || !baseW || !baseH || !m_file_texture) {
|
if (!parent || !target || !baseW || !baseH || !_file_texture) {
|
||||||
obs_source_skip_video_filter(m_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obs_source_process_filter_begin(m_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
if (!obs_source_process_filter_begin(_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
||||||
obs_source_skip_video_filter(m_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_effect->has_parameter("texelScale")) {
|
if (_effect->has_parameter("texelScale")) {
|
||||||
m_effect->get_parameter("texelScale")
|
_effect->get_parameter("texelScale")
|
||||||
.set_float2(interp((1.0f / baseW), 1.0f, m_distance), interp((1.0f / baseH), 1.0f, m_distance));
|
.set_float2(interp((1.0f / baseW), 1.0f, _distance), interp((1.0f / baseH), 1.0f, _distance));
|
||||||
}
|
}
|
||||||
if (m_effect->has_parameter("displacementScale")) {
|
if (_effect->has_parameter("displacementScale")) {
|
||||||
m_effect->get_parameter("displacementScale").set_float2(m_displacement_scale);
|
_effect->get_parameter("displacementScale").set_float2(_displacement_scale);
|
||||||
}
|
}
|
||||||
if (m_effect->has_parameter("displacementMap")) {
|
if (_effect->has_parameter("displacementMap")) {
|
||||||
m_effect->get_parameter("displacementMap").set_texture(m_file_texture);
|
_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()
|
std::string filter::displacement::displacement_instance::get_file()
|
||||||
{
|
{
|
||||||
return m_file_name;
|
return _file_name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,16 +34,10 @@
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#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 filter {
|
||||||
namespace displacement {
|
namespace displacement {
|
||||||
class displacement_factory {
|
class displacement_factory {
|
||||||
obs_source_info sourceInfo;
|
obs_source_info _source_info;
|
||||||
|
|
||||||
public: // Singleton
|
public: // Singleton
|
||||||
static void initialize();
|
static void initialize();
|
||||||
|
@ -72,20 +66,20 @@ namespace filter {
|
||||||
};
|
};
|
||||||
|
|
||||||
class displacement_instance {
|
class displacement_instance {
|
||||||
obs_source_t* m_self;
|
obs_source_t* _self;
|
||||||
float_t m_timer;
|
float_t _timer;
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
std::shared_ptr<gs::effect> m_effect;
|
std::shared_ptr<gs::effect> _effect;
|
||||||
float_t m_distance;
|
float_t _distance;
|
||||||
vec2 m_displacement_scale;
|
vec2 _displacement_scale;
|
||||||
|
|
||||||
// Displacement Map
|
// Displacement Map
|
||||||
std::string m_file_name;
|
std::string _file_name;
|
||||||
std::shared_ptr<gs::texture> m_file_texture;
|
std::shared_ptr<gs::texture> _file_texture;
|
||||||
time_t m_file_create_time;
|
time_t _file_create_time;
|
||||||
time_t m_file_modified_time;
|
time_t _file_modified_time;
|
||||||
size_t m_file_size;
|
size_t _file_size;
|
||||||
|
|
||||||
void validate_file_texture(std::string file);
|
void validate_file_texture(std::string file);
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,13 @@
|
||||||
// - Green Mask Output
|
// - Green Mask Output
|
||||||
// - Alpha Mask Output
|
// - Alpha Mask Output
|
||||||
|
|
||||||
#define SOURCE_NAME "Filter.DynamicMask"
|
#define ST "Filter.DynamicMask"
|
||||||
|
|
||||||
#define S_INPUT "Filter.DynamicMask.Input"
|
#define ST_INPUT "Filter.DynamicMask.Input"
|
||||||
#define S_CHANNEL "Filter.DynamicMask.Channel"
|
#define ST_CHANNEL "Filter.DynamicMask.Channel"
|
||||||
#define S_CHANNEL_VALUE "Filter.DynamicMask.Channel.Value"
|
#define ST_CHANNEL_VALUE "Filter.DynamicMask.Channel.Value"
|
||||||
#define S_CHANNEL_MULTIPLIER "Filter.DynamicMask.Channel.Multiplier"
|
#define ST_CHANNEL_MULTIPLIER "Filter.DynamicMask.Channel.Multiplier"
|
||||||
#define S_CHANNEL_INPUT "Filter.DynamicMask.Channel.Input"
|
#define ST_CHANNEL_INPUT "Filter.DynamicMask.Channel.Input"
|
||||||
|
|
||||||
static std::pair<filter::dynamic_mask::channel, const char*> channel_translations[] = {
|
static std::pair<filter::dynamic_mask::channel, const char*> channel_translations[] = {
|
||||||
{filter::dynamic_mask::channel::Red, S_CHANNEL_RED},
|
{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},
|
{filter::dynamic_mask::channel::Alpha, S_CHANNEL_ALPHA},
|
||||||
};
|
};
|
||||||
|
|
||||||
INITIALIZER(FilterDynamicMaskInit)
|
P_INITIALIZER(FilterDynamicMaskInit)
|
||||||
{
|
{
|
||||||
initializerFunctions.push_back([] { filter::dynamic_mask::dynamic_mask_factory::initialize(); });
|
initializer_functions.push_back([] { filter::dynamic_mask::dynamic_mask_factory::initialize(); });
|
||||||
finalizerFunctions.push_back([] { filter::dynamic_mask::dynamic_mask_factory::finalize(); });
|
finalizer_functions.push_back([] { filter::dynamic_mask::dynamic_mask_factory::finalize(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<filter::dynamic_mask::dynamic_mask_factory> factory_instance = nullptr;
|
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()
|
filter::dynamic_mask::dynamic_mask_factory::dynamic_mask_factory()
|
||||||
{
|
{
|
||||||
memset(&sourceInfo, 0, sizeof(obs_source_info));
|
memset(&_source_info, 0, sizeof(obs_source_info));
|
||||||
sourceInfo.id = "obs-stream-effects-filter-dynamic-mask";
|
_source_info.id = "obs-stream-effects-filter-dynamic-mask";
|
||||||
sourceInfo.type = OBS_SOURCE_TYPE_FILTER;
|
_source_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
sourceInfo.output_flags = OBS_SOURCE_VIDEO;
|
_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));
|
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);
|
delete reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
sourceInfo.get_defaults2 = [](void*, obs_data_t* settings) {
|
_source_info.get_defaults2 = [](void*, obs_data_t* settings) {
|
||||||
obs_data_set_default_int(settings, S_CHANNEL, static_cast<int64_t>(channel::Red));
|
obs_data_set_default_int(settings, ST_CHANNEL, static_cast<int64_t>(channel::Red));
|
||||||
for (auto kv : channel_translations) {
|
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(ST_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_MULTIPLIER) + "." + kv.second).c_str(), 1.0);
|
||||||
for (auto kv2 : channel_translations) {
|
for (auto kv2 : channel_translations) {
|
||||||
obs_data_set_default_double(
|
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);
|
obs_properties_t* props = obs_properties_create_param(_type_data_ptr, nullptr);
|
||||||
reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr)->get_properties(props);
|
reinterpret_cast<filter::dynamic_mask::dynamic_mask_instance*>(_ptr)->get_properties(props);
|
||||||
return 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);
|
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);
|
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);
|
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);
|
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);
|
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_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->update(data);
|
||||||
|
|
||||||
this->filter_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);
|
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 {
|
try {
|
||||||
this->effect = std::make_shared<gs::effect>(file);
|
this->_effect = std::make_shared<gs::effect>(file);
|
||||||
} catch (std::exception& ex) {
|
} 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);
|
bfree(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,17 +157,17 @@ void filter::dynamic_mask::dynamic_mask_instance::get_properties(obs_properties_
|
||||||
{
|
{
|
||||||
obs_property_t* p;
|
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_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_property_list_add_string(p, "", "");
|
||||||
obs::source_tracker::get()->enumerate(
|
obs::source_tracker::get()->enumerate(
|
||||||
[&p](std::string name, obs_source_t*) {
|
[&p](std::string name, obs_source_t*) {
|
||||||
std::stringstream sstr;
|
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());
|
obs_property_list_add_string(p, sstr.str().c_str(), name.c_str());
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
@ -175,7 +175,7 @@ void filter::dynamic_mask::dynamic_mask_instance::get_properties(obs_properties_
|
||||||
obs::source_tracker::get()->enumerate(
|
obs::source_tracker::get()->enumerate(
|
||||||
[&p](std::string name, obs_source_t*) {
|
[&p](std::string name, obs_source_t*) {
|
||||||
std::stringstream sstr;
|
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());
|
obs_property_list_add_string(p, sstr.str().c_str(), name.c_str());
|
||||||
return false;
|
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_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) {
|
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);
|
obs_property_set_modified_callback2(p, modified, this);
|
||||||
|
|
||||||
for (auto kv : channel_translations) {
|
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');
|
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());
|
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)};
|
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())});
|
_translation_map.insert({_chv_key, std::string(_chv_data.begin(), _chv_data.end())});
|
||||||
auto chv = translation_map.find(_chv_key);
|
auto chv = _translation_map.find(_chv_key);
|
||||||
std::string chv_key = std::string(S_CHANNEL_VALUE) + "." + kv.second;
|
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,
|
p = obs_properties_add_float_slider(properties, chv_key.c_str(), chv->second.c_str(), -100.0, 100.0,
|
||||||
0.01);
|
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');
|
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());
|
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)};
|
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())});
|
_translation_map.insert({_chm_key, std::string(_chm_data.begin(), _chm_data.end())});
|
||||||
auto chm = translation_map.find(_chm_key);
|
auto chm = _translation_map.find(_chm_key);
|
||||||
std::string chm_key = std::string(S_CHANNEL_MULTIPLIER) + "." + kv.second;
|
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,
|
p = obs_properties_add_float_slider(properties, chm_key.c_str(), chm->second.c_str(), -100.0, 100.0,
|
||||||
0.01);
|
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) {
|
for (auto kv1 : channel_translations) {
|
||||||
std::string color1 = P_TRANSLATE(kv1.second);
|
std::string color1 = D_TRANSLATE(kv1.second);
|
||||||
for (auto kv2 : channel_translations) {
|
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');
|
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());
|
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)};
|
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())});
|
_translation_map.insert({_chm_key, std::string(_chm_data.begin(), _chm_data.end())});
|
||||||
auto chm = translation_map.find(_chm_key);
|
auto chm = _translation_map.find(_chm_key);
|
||||||
std::string chm_key = std::string(S_CHANNEL_INPUT) + "." + kv1.second + "." + kv2.second;
|
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,
|
p = obs_properties_add_float_slider(properties, chm_key.c_str(), chm->second.c_str(), -100.0, 100.0,
|
||||||
0.01);
|
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.
|
// Update source.
|
||||||
try {
|
try {
|
||||||
this->input = std::make_shared<obs::source>(obs_data_get_string(settings, S_INPUT));
|
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_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->events.rename += std::bind(&filter::dynamic_mask::dynamic_mask_instance::input_renamed, this,
|
||||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
this->input.reset();
|
this->_input.reset();
|
||||||
this->input_capture.reset();
|
this->_input_capture.reset();
|
||||||
this->input_texture.reset();
|
this->_input_texture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update data store
|
// Update data store
|
||||||
for (auto kv1 : channel_translations) {
|
for (auto kv1 : channel_translations) {
|
||||||
auto found = this->channels.find(kv1.first);
|
auto found = this->_channels.find(kv1.first);
|
||||||
if (found == this->channels.end()) {
|
if (found == this->_channels.end()) {
|
||||||
this->channels.insert({kv1.first, channel_data()});
|
this->_channels.insert({kv1.first, channel_data()});
|
||||||
found = this->channels.find(kv1.first);
|
found = this->_channels.find(kv1.first);
|
||||||
if (found == this->channels.end()) {
|
if (found == this->_channels.end()) {
|
||||||
assert(found != this->channels.end());
|
assert(found != this->_channels.end());
|
||||||
throw std::exception("Unable to insert element into data store.");
|
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()));
|
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()));
|
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;
|
vec4* ch = nullptr;
|
||||||
switch (kv1.first) {
|
switch (kv1.first) {
|
||||||
case channel::Red:
|
case channel::Red:
|
||||||
ch = &this->precalc.matrix.x;
|
ch = &this->_precalc.matrix.x;
|
||||||
break;
|
break;
|
||||||
case channel::Green:
|
case channel::Green:
|
||||||
ch = &this->precalc.matrix.y;
|
ch = &this->_precalc.matrix.y;
|
||||||
break;
|
break;
|
||||||
case channel::Blue:
|
case channel::Blue:
|
||||||
ch = &this->precalc.matrix.z;
|
ch = &this->_precalc.matrix.z;
|
||||||
break;
|
break;
|
||||||
case channel::Alpha:
|
case channel::Alpha:
|
||||||
ch = &this->precalc.matrix.t;
|
ch = &this->_precalc.matrix.t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto kv2 : channel_translations) {
|
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)] =
|
found->second.values.ptr[static_cast<size_t>(kv2.first)] =
|
||||||
static_cast<float_t>(obs_data_get_double(settings, ab_key.c_str()));
|
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)];
|
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)
|
void filter::dynamic_mask::dynamic_mask_instance::save(obs_data_t* settings)
|
||||||
{
|
{
|
||||||
if (this->input) {
|
if (this->_input) {
|
||||||
obs_data_set_string(settings, S_INPUT, obs_source_get_name(this->input->get()));
|
obs_data_set_string(settings, ST_INPUT, obs_source_get_name(this->_input->get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto kv1 : channel_translations) {
|
for (auto kv1 : channel_translations) {
|
||||||
auto found = this->channels.find(kv1.first);
|
auto found = this->_channels.find(kv1.first);
|
||||||
if (found == this->channels.end()) {
|
if (found == this->_channels.end()) {
|
||||||
this->channels.insert({kv1.first, channel_data()});
|
this->_channels.insert({kv1.first, channel_data()});
|
||||||
found = this->channels.find(kv1.first);
|
found = this->_channels.find(kv1.first);
|
||||||
if (found == this->channels.end()) {
|
if (found == this->_channels.end()) {
|
||||||
assert(found != this->channels.end());
|
assert(found != this->_channels.end());
|
||||||
throw std::exception("Unable to insert element into data store.");
|
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));
|
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));
|
obs_data_set_double(settings, chm_key.c_str(), static_cast<double_t>(found->second.scale));
|
||||||
|
|
||||||
for (auto kv2 : channel_translations) {
|
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(),
|
obs_data_set_double(settings, ab_key.c_str(),
|
||||||
static_cast<double_t>(found->second.values.ptr[static_cast<size_t>(kv2.first)]));
|
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,
|
void filter::dynamic_mask::dynamic_mask_instance::input_renamed(obs::source*, std::string old_name,
|
||||||
std::string new_name)
|
std::string new_name)
|
||||||
{
|
{
|
||||||
obs_data_t* settings = obs_source_get_settings(self);
|
obs_data_t* settings = obs_source_get_settings(_self);
|
||||||
obs_data_set_string(settings, S_INPUT, new_name.c_str());
|
obs_data_set_string(settings, ST_INPUT, new_name.c_str());
|
||||||
obs_source_update(self, settings);
|
obs_source_update(_self, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool filter::dynamic_mask::dynamic_mask_instance::modified(void*, obs_properties_t* properties, obs_property_t*,
|
bool filter::dynamic_mask::dynamic_mask_instance::modified(void*, obs_properties_t* properties, obs_property_t*,
|
||||||
obs_data_t* settings)
|
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) {
|
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));
|
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));
|
obs_property_set_visible(obs_properties_get(properties, chm_key.c_str()), (mask == kv1.first));
|
||||||
|
|
||||||
for (auto kv2 : channel_translations) {
|
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));
|
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)
|
void filter::dynamic_mask::dynamic_mask_instance::video_tick(float)
|
||||||
{
|
{
|
||||||
have_input_texture = false;
|
_have_input_texture = false;
|
||||||
have_filter_texture = false;
|
_have_filter_texture = false;
|
||||||
have_final_texture = false;
|
_have_final_texture = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_effect)
|
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* parent = obs_filter_get_parent(this->_self);
|
||||||
obs_source_t* target = obs_filter_get_target(this->self);
|
obs_source_t* target = obs_filter_get_target(this->_self);
|
||||||
uint32_t width = obs_source_get_base_width(target);
|
uint32_t width = obs_source_get_base_width(target);
|
||||||
uint32_t height = obs_source_get_base_height(target);
|
uint32_t height = obs_source_get_base_height(target);
|
||||||
|
|
||||||
if (!self || !parent || !target || !width || !height || !input || !input_capture || !effect) {
|
if (!_self || !parent || !target || !width || !height || !_input || !_input_capture || !_effect) {
|
||||||
obs_source_skip_video_filter(self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
} else if (!input->width() || !input->height()) {
|
} else if (!_input->width() || !_input->height()) {
|
||||||
obs_source_skip_video_filter(self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_effect_t* default_effect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
|
gs_effect_t* default_effect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
|
||||||
|
|
||||||
try { // Capture filter and input
|
try { // Capture filter and input
|
||||||
if (!have_filter_texture) {
|
if (!_have_filter_texture) {
|
||||||
if (obs_source_process_filter_begin(this->self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
if (obs_source_process_filter_begin(this->_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
||||||
auto op = this->filter_rt->render(width, height);
|
auto op = this->_filter_rt->render(width, height);
|
||||||
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
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_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
|
||||||
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
|
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();
|
gs_blend_state_pop();
|
||||||
} else {
|
} else {
|
||||||
throw std::exception("Failed to render filter.");
|
throw std::exception("Failed to render filter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->filter_texture = this->filter_rt->get_texture();
|
this->_filter_texture = this->_filter_rt->get_texture();
|
||||||
this->have_filter_texture = true;
|
this->_have_filter_texture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!have_input_texture) {
|
if (!_have_input_texture) {
|
||||||
this->input_texture = this->input_capture->render(input->width(), input->height());
|
this->_input_texture = this->_input_capture->render(_input->width(), _input->height());
|
||||||
this->have_input_texture = true;
|
this->_have_input_texture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw source
|
// 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_blend_state_push();
|
||||||
gs_reset_blend_state();
|
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_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
|
||||||
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
|
gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
|
||||||
|
|
||||||
this->effect->get_parameter("pMaskInputA").set_texture(this->filter_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("pMaskInputB").set_texture(this->_input_texture);
|
||||||
|
|
||||||
this->effect->get_parameter("pMaskBase").set_float4(this->precalc.base);
|
this->_effect->get_parameter("pMaskBase").set_float4(this->_precalc.base);
|
||||||
this->effect->get_parameter("pMaskMatrix").set_matrix(this->precalc.matrix);
|
this->_effect->get_parameter("pMaskMatrix").set_matrix(this->_precalc.matrix);
|
||||||
this->effect->get_parameter("pMaskMultiplier").set_float4(this->precalc.scale);
|
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_draw_sprite(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->final_texture = this->final_rt->get_texture();
|
this->_final_texture = this->_final_rt->get_texture();
|
||||||
this->have_final_texture = true;
|
this->_have_final_texture = true;
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
obs_source_skip_video_filter(this->self);
|
obs_source_skip_video_filter(this->_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!have_filter_texture || !have_input_texture || !have_final_texture) {
|
if (!_have_filter_texture || !_have_input_texture || !_have_final_texture) {
|
||||||
obs_source_skip_video_filter(this->self);
|
obs_source_skip_video_filter(this->_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this->filter_texture->get_object() || !this->input_texture->get_object() || !this->final_texture->get_object()) {
|
if (!this->_filter_texture->get_object() || !this->_input_texture->get_object() || !this->_final_texture->get_object()) {
|
||||||
obs_source_skip_video_filter(this->self);
|
obs_source_skip_video_filter(this->_self);
|
||||||
return;
|
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_effect_t* final_effect = in_effect ? in_effect : default_effect;
|
||||||
gs_eparam_t* param = gs_effect_get_param_by_name(final_effect, "image");
|
gs_eparam_t* param = gs_effect_get_param_by_name(final_effect, "image");
|
||||||
if (!param) {
|
if (!param) {
|
||||||
P_LOG_ERROR("<filter-dynamic-mask:%s> Failed to set image param.", obs_source_get_name(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);
|
obs_source_skip_video_filter(this->_self);
|
||||||
return;
|
return;
|
||||||
} else {
|
} 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")) {
|
while (gs_effect_loop(final_effect, "Draw")) {
|
||||||
gs_draw_sprite(0, 0, width, height);
|
gs_draw_sprite(0, 0, width, height);
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace filter {
|
||||||
enum class channel : int8_t { Invalid = -1, Red, Green, Blue, Alpha };
|
enum class channel : int8_t { Invalid = -1, Red, Green, Blue, Alpha };
|
||||||
|
|
||||||
class dynamic_mask_factory {
|
class dynamic_mask_factory {
|
||||||
obs_source_info sourceInfo;
|
obs_source_info _source_info;
|
||||||
|
|
||||||
public: // Singleton
|
public: // Singleton
|
||||||
static void initialize();
|
static void initialize();
|
||||||
|
@ -55,37 +55,37 @@ namespace filter {
|
||||||
};
|
};
|
||||||
|
|
||||||
class dynamic_mask_instance {
|
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;
|
bool _have_filter_texture;
|
||||||
std::shared_ptr<gs::rendertarget> filter_rt;
|
std::shared_ptr<gs::rendertarget> _filter_rt;
|
||||||
std::shared_ptr<gs::texture> filter_texture;
|
std::shared_ptr<gs::texture> _filter_texture;
|
||||||
|
|
||||||
bool have_input_texture;
|
bool _have_input_texture;
|
||||||
std::shared_ptr<obs::source> input;
|
std::shared_ptr<obs::source> _input;
|
||||||
std::shared_ptr<gfx::source_texture> input_capture;
|
std::shared_ptr<gfx::source_texture> _input_capture;
|
||||||
std::shared_ptr<gs::texture> input_texture;
|
std::shared_ptr<gs::texture> _input_texture;
|
||||||
|
|
||||||
bool have_final_texture;
|
bool _have_final_texture;
|
||||||
std::shared_ptr<gs::rendertarget> final_rt;
|
std::shared_ptr<gs::rendertarget> _final_rt;
|
||||||
std::shared_ptr<gs::texture> final_texture;
|
std::shared_ptr<gs::texture> _final_texture;
|
||||||
|
|
||||||
struct channel_data {
|
struct channel_data {
|
||||||
float_t value = 0.0;
|
float_t value = 0.0;
|
||||||
float_t scale = 1.0;
|
float_t scale = 1.0;
|
||||||
vec4 values = {0};
|
vec4 values = {0};
|
||||||
};
|
};
|
||||||
std::map<channel, channel_data> channels;
|
std::map<channel, channel_data> _channels;
|
||||||
|
|
||||||
struct _precalc {
|
struct _precalc {
|
||||||
vec4 base;
|
vec4 base;
|
||||||
vec4 scale;
|
vec4 scale;
|
||||||
matrix4 matrix;
|
matrix4 matrix;
|
||||||
} precalc;
|
} _precalc;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dynamic_mask_instance(obs_data_t* data, obs_source_t* self);
|
dynamic_mask_instance(obs_data_t* data, obs_source_t* self);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,12 +41,12 @@ namespace filter {
|
||||||
class sdf_effects_instance;
|
class sdf_effects_instance;
|
||||||
|
|
||||||
class sdf_effects_factory {
|
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_producer_effect;
|
||||||
std::shared_ptr<gs::effect> sdf_consumer_effect;
|
std::shared_ptr<gs::effect> _sdf_consumer_effect;
|
||||||
|
|
||||||
public: // Singleton
|
public: // Singleton
|
||||||
static void initialize();
|
static void initialize();
|
||||||
|
@ -83,56 +83,57 @@ namespace filter {
|
||||||
};
|
};
|
||||||
|
|
||||||
class sdf_effects_instance {
|
class sdf_effects_instance {
|
||||||
obs_source_t* m_self;
|
obs_source_t* _self;
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
std::shared_ptr<gs::rendertarget> m_source_rt;
|
std::shared_ptr<gs::rendertarget> _source_rt;
|
||||||
std::shared_ptr<gs::texture> m_source_texture;
|
std::shared_ptr<gs::texture> _source_texture;
|
||||||
bool m_source_rendered;
|
bool _source_rendered;
|
||||||
|
|
||||||
// Distance Field
|
// Distance Field
|
||||||
std::shared_ptr<gs::rendertarget> m_sdf_write, m_sdf_read;
|
std::shared_ptr<gs::rendertarget> _sdf_write;
|
||||||
std::shared_ptr<gs::texture> m_sdf_texture;
|
std::shared_ptr<gs::rendertarget> _sdf_read;
|
||||||
double_t m_sdf_scale;
|
std::shared_ptr<gs::texture> _sdf_texture;
|
||||||
float_t m_sdf_threshold;
|
double_t _sdf_scale;
|
||||||
|
float_t _sdf_threshold;
|
||||||
|
|
||||||
// Effects
|
// Effects
|
||||||
bool m_output_rendered;
|
bool _output_rendered;
|
||||||
std::shared_ptr<gs::texture> m_output_texture;
|
std::shared_ptr<gs::texture> _output_texture;
|
||||||
std::shared_ptr<gs::rendertarget> m_output_rt;
|
std::shared_ptr<gs::rendertarget> _output_rt;
|
||||||
/// Inner Shadow
|
/// Inner Shadow
|
||||||
bool m_inner_shadow;
|
bool _inner_shadow;
|
||||||
vec4 m_inner_shadow_color;
|
vec4 _inner_shadow_color;
|
||||||
float_t m_inner_shadow_range_min;
|
float_t _inner_shadow_range_min;
|
||||||
float_t m_inner_shadow_range_max;
|
float_t _inner_shadow_range_max;
|
||||||
float_t m_inner_shadow_offset_x;
|
float_t _inner_shadow_offset_x;
|
||||||
float_t m_inner_shadow_offset_y;
|
float_t _inner_shadow_offset_y;
|
||||||
/// Outer Shadow
|
/// Outer Shadow
|
||||||
bool m_outer_shadow;
|
bool _outer_shadow;
|
||||||
vec4 m_outer_shadow_color;
|
vec4 _outer_shadow_color;
|
||||||
float_t m_outer_shadow_range_min;
|
float_t _outer_shadow_range_min;
|
||||||
float_t m_outer_shadow_range_max;
|
float_t _outer_shadow_range_max;
|
||||||
float_t m_outer_shadow_offset_x;
|
float_t _outer_shadow_offset_x;
|
||||||
float_t m_outer_shadow_offset_y;
|
float_t _outer_shadow_offset_y;
|
||||||
/// Inner Glow
|
/// Inner Glow
|
||||||
bool m_inner_glow;
|
bool _inner_glow;
|
||||||
vec4 m_inner_glow_color;
|
vec4 _inner_glow_color;
|
||||||
float_t m_inner_glow_width;
|
float_t _inner_glow_width;
|
||||||
float_t m_inner_glow_sharpness;
|
float_t _inner_glow_sharpness;
|
||||||
float_t m_inner_glow_sharpness_inv;
|
float_t _inner_glow_sharpness_inv;
|
||||||
/// Outer Glow
|
/// Outer Glow
|
||||||
bool m_outer_glow;
|
bool _outer_glow;
|
||||||
vec4 m_outer_glow_color;
|
vec4 _outer_glow_color;
|
||||||
float_t m_outer_glow_width;
|
float_t _outer_glow_width;
|
||||||
float_t m_outer_glow_sharpness;
|
float_t _outer_glow_sharpness;
|
||||||
float_t m_outer_glow_sharpness_inv;
|
float_t _outer_glow_sharpness_inv;
|
||||||
/// Outline
|
/// Outline
|
||||||
bool m_outline;
|
bool _outline;
|
||||||
vec4 m_outline_color;
|
vec4 _outline_color;
|
||||||
float_t m_outline_width;
|
float_t _outline_width;
|
||||||
float_t m_outline_offset;
|
float_t _outline_offset;
|
||||||
float_t m_outline_sharpness;
|
float_t _outline_sharpness;
|
||||||
float_t m_outline_sharpness_inv;
|
float_t _outline_sharpness_inv;
|
||||||
|
|
||||||
static bool cb_modified_shadow_inside(void* ptr, obs_properties_t* props, obs_property* prop,
|
static bool cb_modified_shadow_inside(void* ptr, obs_properties_t* props, obs_property* prop,
|
||||||
obs_data_t* settings);
|
obs_data_t* settings);
|
||||||
|
|
|
@ -76,10 +76,10 @@ enum RotationOrder : int64_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initializer & Finalizer
|
// Initializer & Finalizer
|
||||||
INITIALIZER(FilterTransformInit)
|
P_INITIALIZER(FilterTransformInit)
|
||||||
{
|
{
|
||||||
initializerFunctions.push_back([] { filter::transform::transform_factory::initialize(); });
|
initializer_functions.push_back([] { filter::transform::transform_factory::initialize(); });
|
||||||
finalizerFunctions.push_back([] { filter::transform::transform_factory::finalize(); });
|
finalizer_functions.push_back([] { filter::transform::transform_factory::finalize(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<filter::transform::transform_factory> factory_instance = nullptr;
|
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()
|
filter::transform::transform_factory::transform_factory()
|
||||||
{
|
{
|
||||||
memset(&sourceInfo, 0, sizeof(obs_source_info));
|
memset(&_source_info, 0, sizeof(obs_source_info));
|
||||||
sourceInfo.id = "obs-stream-effects-filter-transform";
|
_source_info.id = "obs-stream-effects-filter-transform";
|
||||||
sourceInfo.type = OBS_SOURCE_TYPE_FILTER;
|
_source_info.type = OBS_SOURCE_TYPE_FILTER;
|
||||||
sourceInfo.output_flags = OBS_SOURCE_VIDEO;
|
_source_info.output_flags = OBS_SOURCE_VIDEO;
|
||||||
sourceInfo.get_name = get_name;
|
_source_info.get_name = get_name;
|
||||||
sourceInfo.get_defaults = get_defaults;
|
_source_info.get_defaults = get_defaults;
|
||||||
sourceInfo.get_properties = get_properties;
|
_source_info.get_properties = get_properties;
|
||||||
|
|
||||||
sourceInfo.create = create;
|
_source_info.create = create;
|
||||||
sourceInfo.destroy = destroy;
|
_source_info.destroy = destroy;
|
||||||
sourceInfo.update = update;
|
_source_info.update = update;
|
||||||
sourceInfo.activate = activate;
|
_source_info.activate = activate;
|
||||||
sourceInfo.deactivate = deactivate;
|
_source_info.deactivate = deactivate;
|
||||||
sourceInfo.video_tick = video_tick;
|
_source_info.video_tick = video_tick;
|
||||||
sourceInfo.video_render = video_render;
|
_source_info.video_render = video_render;
|
||||||
|
|
||||||
obs_register_source(&sourceInfo);
|
obs_register_source(&_source_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
filter::transform::transform_factory::~transform_factory() {}
|
filter::transform::transform_factory::~transform_factory() {}
|
||||||
|
|
||||||
const char* filter::transform::transform_factory::get_name(void*)
|
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)
|
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
|
// Camera
|
||||||
/// Projection Mode
|
/// Projection Mode
|
||||||
p = obs_properties_add_list(pr, ST_CAMERA, P_TRANSLATE(ST_CAMERA), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
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, P_TRANSLATE(P_DESC(ST_CAMERA)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA)));
|
||||||
obs_property_list_add_int(p, P_TRANSLATE(ST_CAMERA_ORTHOGRAPHIC), (int64_t)CameraMode::Orthographic);
|
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_ORTHOGRAPHIC), (int64_t)CameraMode::Orthographic);
|
||||||
obs_property_list_add_int(p, P_TRANSLATE(ST_CAMERA_PERSPECTIVE), (int64_t)CameraMode::Perspective);
|
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_PERSPECTIVE), (int64_t)CameraMode::Perspective);
|
||||||
obs_property_set_modified_callback(p, modified_properties);
|
obs_property_set_modified_callback(p, modified_properties);
|
||||||
/// Field Of View
|
/// 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);
|
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
|
// Mesh
|
||||||
/// Position
|
/// Position
|
||||||
{
|
{
|
||||||
std::pair<const char*, const char*> entries[] = {
|
std::pair<const char*, const char*> entries[] = {
|
||||||
std::make_pair(ST_POSITION_X, P_DESC(ST_POSITION)),
|
std::make_pair(ST_POSITION_X, D_DESC(ST_POSITION)),
|
||||||
std::make_pair(ST_POSITION_Y, P_DESC(ST_POSITION)),
|
std::make_pair(ST_POSITION_Y, D_DESC(ST_POSITION)),
|
||||||
std::make_pair(ST_POSITION_Z, P_DESC(ST_POSITION)),
|
std::make_pair(ST_POSITION_Z, D_DESC(ST_POSITION)),
|
||||||
};
|
};
|
||||||
for (auto kv : entries) {
|
for (auto kv : entries) {
|
||||||
p = obs_properties_add_float(pr, kv.first, P_TRANSLATE(kv.first), -10000, 10000, 0.01);
|
p = obs_properties_add_float(pr, kv.first, D_TRANSLATE(kv.first), -10000, 10000, 0.01);
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(kv.second));
|
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Rotation
|
/// Rotation
|
||||||
{
|
{
|
||||||
std::pair<const char*, const char*> entries[] = {
|
std::pair<const char*, const char*> entries[] = {
|
||||||
std::make_pair(ST_ROTATION_X, P_DESC(ST_ROTATION)),
|
std::make_pair(ST_ROTATION_X, D_DESC(ST_ROTATION)),
|
||||||
std::make_pair(ST_ROTATION_Y, P_DESC(ST_ROTATION)),
|
std::make_pair(ST_ROTATION_Y, D_DESC(ST_ROTATION)),
|
||||||
std::make_pair(ST_ROTATION_Z, P_DESC(ST_ROTATION)),
|
std::make_pair(ST_ROTATION_Z, D_DESC(ST_ROTATION)),
|
||||||
};
|
};
|
||||||
for (auto kv : entries) {
|
for (auto kv : entries) {
|
||||||
p = obs_properties_add_float_slider(pr, kv.first, P_TRANSLATE(kv.first), -180, 180, 0.01);
|
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -180, 180, 0.01);
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(kv.second));
|
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Scale
|
/// Scale
|
||||||
{
|
{
|
||||||
std::pair<const char*, const char*> entries[] = {
|
std::pair<const char*, const char*> entries[] = {
|
||||||
std::make_pair(ST_SCALE_X, P_DESC(ST_SCALE)),
|
std::make_pair(ST_SCALE_X, D_DESC(ST_SCALE)),
|
||||||
std::make_pair(ST_SCALE_Y, P_DESC(ST_SCALE)),
|
std::make_pair(ST_SCALE_Y, D_DESC(ST_SCALE)),
|
||||||
};
|
};
|
||||||
for (auto kv : entries) {
|
for (auto kv : entries) {
|
||||||
p = obs_properties_add_float_slider(pr, kv.first, P_TRANSLATE(kv.first), -1000, 1000, 0.01);
|
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -1000, 1000, 0.01);
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(kv.second));
|
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Shear
|
/// Shear
|
||||||
{
|
{
|
||||||
std::pair<const char*, const char*> entries[] = {
|
std::pair<const char*, const char*> entries[] = {
|
||||||
std::make_pair(ST_SHEAR_X, P_DESC(ST_SHEAR)),
|
std::make_pair(ST_SHEAR_X, D_DESC(ST_SHEAR)),
|
||||||
std::make_pair(ST_SHEAR_Y, P_DESC(ST_SHEAR)),
|
std::make_pair(ST_SHEAR_Y, D_DESC(ST_SHEAR)),
|
||||||
};
|
};
|
||||||
for (auto kv : entries) {
|
for (auto kv : entries) {
|
||||||
p = obs_properties_add_float_slider(pr, kv.first, P_TRANSLATE(kv.first), -100.0, 100.0, 0.01);
|
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, P_TRANSLATE(kv.second));
|
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);
|
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_COMBO_FORMAT_INT);
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(ST_ROTATION_ORDER)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROTATION_ORDER)));
|
||||||
obs_property_list_add_int(p, P_TRANSLATE(ST_ROTATION_ORDER_XYZ), RotationOrder::XYZ);
|
obs_property_list_add_int(p, D_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, D_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, D_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, D_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, D_TRANSLATE(ST_ROTATION_ORDER_ZXY), RotationOrder::ZXY);
|
||||||
obs_property_list_add_int(p, P_TRANSLATE(ST_ROTATION_ORDER_ZYX), RotationOrder::ZYX);
|
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_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_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, D_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, D_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, D_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, D_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, D_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_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);
|
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;
|
return pr;
|
||||||
}
|
}
|
||||||
|
@ -316,34 +316,34 @@ void filter::transform::transform_factory::video_render(void* ptr, gs_effect_t*
|
||||||
|
|
||||||
filter::transform::transform_instance::~transform_instance()
|
filter::transform::transform_instance::~transform_instance()
|
||||||
{
|
{
|
||||||
m_shear.reset();
|
_shear.reset();
|
||||||
m_scale.reset();
|
_scale.reset();
|
||||||
m_rotation.reset();
|
_rotation.reset();
|
||||||
m_position.reset();
|
_position.reset();
|
||||||
m_vertex_buffer.reset();
|
_vertex_buffer.reset();
|
||||||
m_shape_texture.reset();
|
_shape_texture.reset();
|
||||||
m_shape_rendertarget.reset();
|
_shape_rendertarget.reset();
|
||||||
m_source_texture.reset();
|
_source_texture.reset();
|
||||||
m_source_rendertarget.reset();
|
_source_rendertarget.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
filter::transform::transform_instance::transform_instance(obs_data_t* data, obs_source_t* context)
|
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),
|
: _active(true), _self(context), _source_rendered(false), _mipmap_enabled(false), _mipmap_strength(50.0),
|
||||||
m_mipmap_generator(gs::mipmapper::generator::Linear), m_update_mesh(false), m_rotation_order(RotationOrder::ZXY),
|
_mipmap_generator(gs::mipmapper::generator::Linear), _update_mesh(false), _rotation_order(RotationOrder::ZXY),
|
||||||
m_camera_orthographic(true), m_camera_fov(90.0)
|
_camera_orthographic(true), _camera_fov(90.0)
|
||||||
{
|
{
|
||||||
m_source_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_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);
|
_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));
|
_vertex_buffer = std::make_shared<gs::vertex_buffer>(uint32_t(4u), uint8_t(1u));
|
||||||
|
|
||||||
m_position = std::make_unique<util::vec3a>();
|
_position = std::make_unique<util::vec3a>();
|
||||||
m_rotation = std::make_unique<util::vec3a>();
|
_rotation = std::make_unique<util::vec3a>();
|
||||||
m_scale = std::make_unique<util::vec3a>();
|
_scale = std::make_unique<util::vec3a>();
|
||||||
m_shear = std::make_unique<util::vec3a>();
|
_shear = std::make_unique<util::vec3a>();
|
||||||
|
|
||||||
vec3_set(m_position.get(), 0, 0, 0);
|
vec3_set(_position.get(), 0, 0, 0);
|
||||||
vec3_set(m_rotation.get(), 0, 0, 0);
|
vec3_set(_rotation.get(), 0, 0, 0);
|
||||||
vec3_set(m_scale.get(), 1, 1, 1);
|
vec3_set(_scale.get(), 1, 1, 1);
|
||||||
|
|
||||||
update(data);
|
update(data);
|
||||||
}
|
}
|
||||||
|
@ -361,40 +361,40 @@ uint32_t filter::transform::transform_instance::get_height()
|
||||||
void filter::transform::transform_instance::update(obs_data_t* data)
|
void filter::transform::transform_instance::update(obs_data_t* data)
|
||||||
{
|
{
|
||||||
// Camera
|
// Camera
|
||||||
m_camera_orthographic = obs_data_get_int(data, ST_CAMERA) == 0;
|
_camera_orthographic = obs_data_get_int(data, ST_CAMERA) == 0;
|
||||||
m_camera_fov = (float)obs_data_get_double(data, ST_CAMERA_FIELDOFVIEW);
|
_camera_fov = (float)obs_data_get_double(data, ST_CAMERA_FIELDOFVIEW);
|
||||||
|
|
||||||
// Source
|
// Source
|
||||||
m_position->x = static_cast<float_t>(obs_data_get_double(data, ST_POSITION_X) / 100.0);
|
_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);
|
_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);
|
_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);
|
_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);
|
_scale->y = static_cast<float_t>(obs_data_get_double(data, ST_SCALE_Y) / 100.0);
|
||||||
m_scale->z = 1.0f;
|
_scale->z = 1.0f;
|
||||||
m_rotation_order = static_cast<uint32_t>(obs_data_get_int(data, ST_ROTATION_ORDER));
|
_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);
|
_rotation->x = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_X) / 180.0 * S_PI);
|
||||||
m_rotation->y = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_Y) / 180.0 * PI);
|
_rotation->y = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_Y) / 180.0 * S_PI);
|
||||||
m_rotation->z = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_Z) / 180.0 * PI);
|
_rotation->z = static_cast<float_t>(obs_data_get_double(data, ST_ROTATION_Z) / 180.0 * S_PI);
|
||||||
m_shear->x = static_cast<float_t>(obs_data_get_double(data, ST_SHEAR_X) / 100.0);
|
_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);
|
_shear->y = static_cast<float_t>(obs_data_get_double(data, ST_SHEAR_Y) / 100.0);
|
||||||
m_shear->z = 0.0f;
|
_shear->z = 0.0f;
|
||||||
|
|
||||||
// Mipmapping
|
// Mipmapping
|
||||||
m_mipmap_enabled = obs_data_get_bool(data, ST_MIPMAPPING);
|
_mipmap_enabled = obs_data_get_bool(data, ST_MIPMAPPING);
|
||||||
m_mipmap_strength = obs_data_get_double(data, S_MIPGENERATOR_INTENSITY);
|
_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_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()
|
void filter::transform::transform_instance::activate()
|
||||||
{
|
{
|
||||||
m_active = true;
|
_active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::transform::transform_instance::deactivate()
|
void filter::transform::transform_instance::deactivate()
|
||||||
{
|
{
|
||||||
m_active = false;
|
_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::transform::transform_instance::video_tick(float)
|
void filter::transform::transform_instance::video_tick(float)
|
||||||
|
@ -403,7 +403,7 @@ void filter::transform::transform_instance::video_tick(float)
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
|
|
||||||
// Grab parent and target.
|
// 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) {
|
if (target) {
|
||||||
// Grab width an height of the target source (child filter or source).
|
// Grab width an height of the target source (child filter or source).
|
||||||
width = obs_source_get_base_width(target);
|
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 size mismatch, force an update.
|
||||||
if (width != m_source_size.first) {
|
if (width != _source_size.first) {
|
||||||
m_update_mesh = true;
|
_update_mesh = true;
|
||||||
} else if (height != m_source_size.second) {
|
} else if (height != _source_size.second) {
|
||||||
m_update_mesh = true;
|
_update_mesh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Mesh
|
// Update Mesh
|
||||||
if (m_update_mesh) {
|
if (_update_mesh) {
|
||||||
m_source_size.first = width;
|
_source_size.first = width;
|
||||||
m_source_size.second = height;
|
_source_size.second = height;
|
||||||
|
|
||||||
if (width == 0) {
|
if (width == 0) {
|
||||||
width = 1;
|
width = 1;
|
||||||
|
@ -431,99 +431,99 @@ void filter::transform::transform_instance::video_tick(float)
|
||||||
|
|
||||||
// Calculate Aspect Ratio
|
// Calculate Aspect Ratio
|
||||||
float_t aspectRatioX = float_t(width) / float_t(height);
|
float_t aspectRatioX = float_t(width) / float_t(height);
|
||||||
if (m_camera_orthographic)
|
if (_camera_orthographic)
|
||||||
aspectRatioX = 1.0;
|
aspectRatioX = 1.0;
|
||||||
|
|
||||||
// Mesh
|
// Mesh
|
||||||
matrix4 ident;
|
matrix4 ident;
|
||||||
matrix4_identity(&ident);
|
matrix4_identity(&ident);
|
||||||
switch (m_rotation_order) {
|
switch (_rotation_order) {
|
||||||
case RotationOrder::XYZ: // XYZ
|
case RotationOrder::XYZ: // XYZ
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
|
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
|
||||||
break;
|
break;
|
||||||
case RotationOrder::XZY: // XZY
|
case RotationOrder::XZY: // XZY
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
|
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
|
||||||
break;
|
break;
|
||||||
case RotationOrder::YXZ: // YXZ
|
case RotationOrder::YXZ: // YXZ
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
|
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
|
||||||
break;
|
break;
|
||||||
case RotationOrder::YZX: // YZX
|
case RotationOrder::YZX: // YZX
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
|
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
|
||||||
break;
|
break;
|
||||||
case RotationOrder::ZXY: // ZXY
|
case RotationOrder::ZXY: // ZXY
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
|
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
|
||||||
break;
|
break;
|
||||||
case RotationOrder::ZYX: // ZYX
|
case RotationOrder::ZYX: // ZYX
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, m_rotation->z);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 0, 1, _rotation->z);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, m_rotation->y);
|
matrix4_rotate_aa4f(&ident, &ident, 0, 1, 0, _rotation->y);
|
||||||
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, m_rotation->x);
|
matrix4_rotate_aa4f(&ident, &ident, 1, 0, 0, _rotation->x);
|
||||||
break;
|
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.
|
/// Calculate vertex position once only.
|
||||||
float_t p_x = aspectRatioX * m_scale->x;
|
float_t p_x = aspectRatioX * _scale->x;
|
||||||
float_t p_y = 1.0f * m_scale->y;
|
float_t p_y = 1.0f * _scale->y;
|
||||||
|
|
||||||
/// Generate mesh
|
/// Generate mesh
|
||||||
{
|
{
|
||||||
auto vtx = m_vertex_buffer->at(0);
|
auto vtx = _vertex_buffer->at(0);
|
||||||
*vtx.color = 0xFFFFFFFF;
|
*vtx.color = 0xFFFFFFFF;
|
||||||
vec4_set(vtx.uv[0], 0, 0, 0, 0);
|
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);
|
vec3_transform(vtx.position, vtx.position, &ident);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto vtx = m_vertex_buffer->at(1);
|
auto vtx = _vertex_buffer->at(1);
|
||||||
*vtx.color = 0xFFFFFFFF;
|
*vtx.color = 0xFFFFFFFF;
|
||||||
vec4_set(vtx.uv[0], 1, 0, 0, 0);
|
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);
|
vec3_transform(vtx.position, vtx.position, &ident);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto vtx = m_vertex_buffer->at(2);
|
auto vtx = _vertex_buffer->at(2);
|
||||||
*vtx.color = 0xFFFFFFFF;
|
*vtx.color = 0xFFFFFFFF;
|
||||||
vec4_set(vtx.uv[0], 0, 1, 0, 0);
|
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);
|
vec3_transform(vtx.position, vtx.position, &ident);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto vtx = m_vertex_buffer->at(3);
|
auto vtx = _vertex_buffer->at(3);
|
||||||
*vtx.color = 0xFFFFFFFF;
|
*vtx.color = 0xFFFFFFFF;
|
||||||
vec4_set(vtx.uv[0], 1, 1, 0, 0);
|
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);
|
vec3_transform(vtx.position, vtx.position, &ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vertex_buffer->update(true);
|
_vertex_buffer->update(true);
|
||||||
m_update_mesh = false;
|
_update_mesh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->m_source_rendered = false;
|
this->_source_rendered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::transform::transform_instance::video_render(gs_effect_t* paramEffect)
|
void filter::transform::transform_instance::video_render(gs_effect_t* paramEffect)
|
||||||
{
|
{
|
||||||
if (!m_active) {
|
if (!_active) {
|
||||||
obs_source_skip_video_filter(m_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab parent and target.
|
// Grab parent and target.
|
||||||
obs_source_t* parent = obs_filter_get_parent(m_self);
|
obs_source_t* parent = obs_filter_get_parent(_self);
|
||||||
obs_source_t* target = obs_filter_get_target(m_self);
|
obs_source_t* target = obs_filter_get_target(_self);
|
||||||
if (!parent || !target) {
|
if (!parent || !target) {
|
||||||
obs_source_skip_video_filter(m_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
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 width = obs_source_get_base_width(target);
|
||||||
uint32_t height = obs_source_get_base_height(target);
|
uint32_t height = obs_source_get_base_height(target);
|
||||||
if ((width == 0) || (height == 0)) {
|
if ((width == 0) || (height == 0)) {
|
||||||
obs_source_skip_video_filter(m_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_effect_t* default_effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
|
gs_effect_t* default_effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
|
||||||
|
|
||||||
// Only render if we didn't already render.
|
// Only render if we didn't already render.
|
||||||
if (!this->m_source_rendered) {
|
if (!this->_source_rendered) {
|
||||||
std::shared_ptr<gs::texture> source_tex;
|
std::shared_ptr<gs::texture> source_tex;
|
||||||
uint32_t real_width = width;
|
uint32_t real_width = width;
|
||||||
uint32_t real_height = height;
|
uint32_t real_height = height;
|
||||||
|
|
||||||
// If MipMapping is enabled, resize Render Target to be a Power of Two.
|
// 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_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)));
|
real_height = uint32_t(pow(2, util::math::get_power_of_two_exponent_ceil(height)));
|
||||||
if ((real_width >= 8192) || (real_height >= 8192)) {
|
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.
|
// Draw previous filters to texture.
|
||||||
try {
|
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_set_cull_mode(GS_NEITHER);
|
||||||
gs_reset_blend_state();
|
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);
|
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0);
|
||||||
|
|
||||||
/// Render original source
|
/// Render original source
|
||||||
if (obs_source_process_filter_begin(m_self, GS_RGBA, OBS_NO_DIRECT_RENDERING)) {
|
if (obs_source_process_filter_begin(_self, GS_RGBA, OBS_NO_DIRECT_RENDERING)) {
|
||||||
obs_source_process_filter_end(m_self, paramEffect ? paramEffect : default_effect, width, height);
|
obs_source_process_filter_end(_self, paramEffect ? paramEffect : default_effect, width, height);
|
||||||
} else {
|
} else {
|
||||||
obs_source_skip_video_filter(m_self);
|
obs_source_skip_video_filter(_self);
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
obs_source_skip_video_filter(m_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_source_rendertarget->get_texture(source_tex);
|
_source_rendertarget->get_texture(source_tex);
|
||||||
|
|
||||||
if (m_mipmap_enabled) {
|
if (_mipmap_enabled) {
|
||||||
if ((!m_source_texture) || (m_source_texture->get_width() != real_width)
|
if ((!_source_texture) || (_source_texture->get_width() != real_width)
|
||||||
|| (m_source_texture->get_height() != real_height)) {
|
|| (_source_texture->get_height() != real_height)) {
|
||||||
size_t mip_levels = 0;
|
size_t mip_levels = 0;
|
||||||
if (util::math::is_power_of_two(real_width) && util::math::is_power_of_two(real_height)) {
|
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);
|
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,
|
std::make_shared<gs::texture>(real_width, real_height, GS_RGBA, uint32_t(1u + mip_levels), nullptr,
|
||||||
gs::texture::flags::BuildMipMaps);
|
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
|
// Draw shape to texture
|
||||||
try {
|
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);
|
gs_ortho(-1.0, 1.0, -1.0, 1.0, -farZ, farZ);
|
||||||
} else {
|
} 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.
|
// Fix camera pointing at -Z instead of +Z.
|
||||||
gs_matrix_scale3f(1.0, 1.0, -1.0);
|
gs_matrix_scale3f(1.0, 1.0, -1.0);
|
||||||
// Move backwards so we can actually see stuff.
|
// 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_test(false);
|
||||||
gs_enable_stencil_write(false);
|
gs_enable_stencil_write(false);
|
||||||
gs_enable_color(true, true, true, true);
|
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);
|
gs_load_indexbuffer(nullptr);
|
||||||
while (gs_effect_loop(default_effect, "Draw")) {
|
while (gs_effect_loop(default_effect, "Draw")) {
|
||||||
gs_effect_set_texture(gs_effect_get_param_by_name(default_effect, "image"),
|
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_draw(GS_TRISTRIP, 0, 4);
|
||||||
}
|
}
|
||||||
gs_load_vertexbuffer(nullptr);
|
gs_load_vertexbuffer(nullptr);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
obs_source_skip_video_filter(m_self);
|
obs_source_skip_video_filter(_self);
|
||||||
return;
|
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
|
// Draw final shape
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
gs_enable_depth_test(false);
|
gs_enable_depth_test(false);
|
||||||
while (gs_effect_loop(default_effect, "Draw")) {
|
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_effect_set_texture(gs_effect_get_param_by_name(default_effect, "image"), _shape_texture->get_object());
|
||||||
gs_draw_sprite(m_shape_texture->get_object(), 0, 0, 0);
|
gs_draw_sprite(_shape_texture->get_object(), 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
namespace filter {
|
namespace filter {
|
||||||
namespace transform {
|
namespace transform {
|
||||||
class transform_factory {
|
class transform_factory {
|
||||||
obs_source_info sourceInfo;
|
obs_source_info _source_info;
|
||||||
|
|
||||||
public: // Singleton
|
public: // Singleton
|
||||||
static void initialize();
|
static void initialize();
|
||||||
|
@ -59,37 +59,37 @@ namespace filter {
|
||||||
};
|
};
|
||||||
|
|
||||||
class transform_instance {
|
class transform_instance {
|
||||||
bool m_active;
|
bool _active;
|
||||||
obs_source_t* m_self;
|
obs_source_t* _self;
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
std::shared_ptr<gs::rendertarget> m_source_rendertarget;
|
std::shared_ptr<gs::rendertarget> _source_rendertarget;
|
||||||
std::shared_ptr<gs::texture> m_source_texture;
|
std::shared_ptr<gs::texture> _source_texture;
|
||||||
bool m_source_rendered;
|
bool _source_rendered;
|
||||||
std::pair<uint32_t, uint32_t> m_source_size;
|
std::pair<uint32_t, uint32_t> _source_size;
|
||||||
|
|
||||||
// Mipmapping
|
// Mipmapping
|
||||||
bool m_mipmap_enabled;
|
bool _mipmap_enabled;
|
||||||
double_t m_mipmap_strength;
|
double_t _mipmap_strength;
|
||||||
gs::mipmapper::generator m_mipmap_generator;
|
gs::mipmapper::generator _mipmap_generator;
|
||||||
gs::mipmapper m_mipmapper;
|
gs::mipmapper _mipmapper;
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
std::shared_ptr<gs::rendertarget> m_shape_rendertarget;
|
std::shared_ptr<gs::rendertarget> _shape_rendertarget;
|
||||||
std::shared_ptr<gs::texture> m_shape_texture;
|
std::shared_ptr<gs::texture> _shape_texture;
|
||||||
|
|
||||||
// Mesh
|
// Mesh
|
||||||
bool m_update_mesh;
|
bool _update_mesh;
|
||||||
std::shared_ptr<gs::vertex_buffer> m_vertex_buffer;
|
std::shared_ptr<gs::vertex_buffer> _vertex_buffer;
|
||||||
uint32_t m_rotation_order;
|
uint32_t _rotation_order;
|
||||||
std::unique_ptr<util::vec3a> m_position;
|
std::unique_ptr<util::vec3a> _position;
|
||||||
std::unique_ptr<util::vec3a> m_rotation;
|
std::unique_ptr<util::vec3a> _rotation;
|
||||||
std::unique_ptr<util::vec3a> m_scale;
|
std::unique_ptr<util::vec3a> _scale;
|
||||||
std::unique_ptr<util::vec3a> m_shear;
|
std::unique_ptr<util::vec3a> _shear;
|
||||||
|
|
||||||
// Camera
|
// Camera
|
||||||
bool m_camera_orthographic;
|
bool _camera_orthographic;
|
||||||
float_t m_camera_fov;
|
float_t _camera_fov;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~transform_instance();
|
~transform_instance();
|
||||||
|
|
|
@ -17,48 +17,48 @@
|
||||||
|
|
||||||
#include "gfx-blur-base.hpp"
|
#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());
|
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);
|
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;
|
double_t x, y;
|
||||||
this->get_step_scale(x, y);
|
this->get_step_scale(x, y);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
double_t gfx::blur::ibase::get_step_scale_y()
|
double_t gfx::blur::base::get_step_scale_y()
|
||||||
{
|
{
|
||||||
double_t x, y;
|
double_t x, y;
|
||||||
this->get_step_scale(x, y);
|
this->get_step_scale(x, y);
|
||||||
return 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());
|
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);
|
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;
|
double_t x, y;
|
||||||
this->get_center(x, y);
|
this->get_center(x, y);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
double_t gfx::blur::ibase_center::get_center_y()
|
double_t gfx::blur::base_center::get_center_y()
|
||||||
{
|
{
|
||||||
double_t x, y;
|
double_t x, y;
|
||||||
this->get_center(x, y);
|
this->get_center(x, y);
|
||||||
|
|
|
@ -31,9 +31,9 @@ namespace gfx {
|
||||||
Zoom,
|
Zoom,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ibase {
|
class base {
|
||||||
public:
|
public:
|
||||||
virtual ~ibase() {}
|
virtual ~base() {}
|
||||||
|
|
||||||
virtual void set_input(std::shared_ptr<::gs::texture> texture) = 0;
|
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;
|
virtual std::shared_ptr<::gs::texture> get() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ibase_angle {
|
class base_angle {
|
||||||
public:
|
public:
|
||||||
virtual ~ibase_angle() {}
|
virtual ~base_angle() {}
|
||||||
|
|
||||||
virtual double_t get_angle() = 0;
|
virtual double_t get_angle() = 0;
|
||||||
|
|
||||||
virtual void set_angle(double_t angle) = 0;
|
virtual void set_angle(double_t angle) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ibase_center {
|
class base_center {
|
||||||
public:
|
public:
|
||||||
virtual ~ibase_center() {}
|
virtual ~base_center() {}
|
||||||
|
|
||||||
virtual void set_center(double_t x, double_t y) = 0;
|
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 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;
|
virtual double_t get_min_size(::gfx::blur::type type) = 0;
|
||||||
|
|
||||||
|
|
|
@ -38,23 +38,23 @@ gfx::blur::box_linear_data::box_linear_data()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
try {
|
try {
|
||||||
char* file = obs_module_file("effects/blur/box-linear.effect");
|
char* file = obs_module_file("effects/blur/box-linear._effect");
|
||||||
m_effect = std::make_shared<::gs::effect>(file);
|
_effect = std::make_shared<::gs::effect>(file);
|
||||||
bfree(file);
|
bfree(file);
|
||||||
} catch (...) {
|
} 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()
|
gfx::blur::box_linear_data::~box_linear_data()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_effect.reset();
|
_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> gfx::blur::box_linear_data::get_effect()
|
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() {}
|
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) {
|
switch (type) {
|
||||||
case ::gfx::blur::type::Area:
|
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::shared_ptr<::gfx::blur::box_linear_data> gfx::blur::box_linear_factory::data()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ulock(m_data_lock);
|
std::unique_lock<std::mutex> ulock(_data_lock);
|
||||||
std::shared_ptr<::gfx::blur::box_linear_data> data = m_data.lock();
|
std::shared_ptr<::gfx::blur::box_linear_data> data = _data.lock();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = std::make_shared<::gfx::blur::box_linear_data>();
|
data = std::make_shared<::gfx::blur::box_linear_data>();
|
||||||
m_data = data;
|
_data = data;
|
||||||
}
|
}
|
||||||
return 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()
|
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);
|
_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
m_rendertarget2 = 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() {}
|
gfx::blur::box_linear::~box_linear() {}
|
||||||
|
|
||||||
void gfx::blur::box_linear::set_input(std::shared_ptr<::gs::texture> texture)
|
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()
|
::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()
|
double_t gfx::blur::box_linear::get_size()
|
||||||
{
|
{
|
||||||
return m_size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::box_linear::set_size(double_t width)
|
void gfx::blur::box_linear::set_size(double_t width)
|
||||||
{
|
{
|
||||||
m_size = width;
|
_size = width;
|
||||||
if (m_size < 1.0) {
|
if (_size < 1.0) {
|
||||||
m_size = 1.0;
|
_size = 1.0;
|
||||||
}
|
}
|
||||||
if (m_size > MAX_BLUR_SIZE) {
|
if (_size > MAX_BLUR_SIZE) {
|
||||||
m_size = MAX_BLUR_SIZE;
|
_size = MAX_BLUR_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::box_linear::set_step_scale(double_t x, double_t y)
|
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)
|
void gfx::blur::box_linear::get_step_scale(double_t& x, double_t& y)
|
||||||
{
|
{
|
||||||
x = m_step_scale.first;
|
x = _step_scale.first;
|
||||||
y = m_step_scale.second;
|
y = _step_scale.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
double_t gfx::blur::box_linear::get_step_scale_x()
|
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()
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
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);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
||||||
|
|
||||||
// Two Pass Blur
|
// Two Pass Blur
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
if (effect) {
|
if (effect) {
|
||||||
// Pass 1
|
// 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("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("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
|
||||||
effect->get_parameter("pSize").set_float(float_t(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
|
@ -280,11 +280,11 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass 2
|
// 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));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
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();
|
gs_blend_state_pop();
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return _rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box_linear::get()
|
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()
|
::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()
|
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)
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
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);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
||||||
|
|
||||||
// One Pass Blur
|
// One Pass Blur
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
if (effect) {
|
if (effect) {
|
||||||
effect->get_parameter("pImage").set_texture(m_input_texture);
|
effect->get_parameter("pImage").set_texture(_input_texture);
|
||||||
effect->get_parameter("pImageTexel")
|
effect->get_parameter("pImageTexel")
|
||||||
.set_float2(float_t(1. / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
|
.set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
|
||||||
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.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(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
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();
|
gs_blend_state_pop();
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return _rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
namespace blur {
|
namespace blur {
|
||||||
class box_linear_data {
|
class box_linear_data {
|
||||||
std::shared_ptr<::gs::effect> m_effect;
|
std::shared_ptr<::gs::effect> _effect;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
box_linear_data();
|
box_linear_data();
|
||||||
|
@ -37,8 +37,8 @@ namespace gfx {
|
||||||
};
|
};
|
||||||
|
|
||||||
class box_linear_factory : public ::gfx::blur::ifactory {
|
class box_linear_factory : public ::gfx::blur::ifactory {
|
||||||
std::mutex m_data_lock;
|
std::mutex _data_lock;
|
||||||
std::weak_ptr<::gfx::blur::box_linear_data> m_data;
|
std::weak_ptr<::gfx::blur::box_linear_data> _data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
box_linear_factory();
|
box_linear_factory();
|
||||||
|
@ -46,7 +46,7 @@ namespace gfx {
|
||||||
|
|
||||||
virtual bool is_type_supported(::gfx::blur::type type) override;
|
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;
|
virtual double_t get_min_size(::gfx::blur::type type) override;
|
||||||
|
|
||||||
|
@ -80,17 +80,17 @@ namespace gfx {
|
||||||
static ::gfx::blur::box_linear_factory& get();
|
static ::gfx::blur::box_linear_factory& get();
|
||||||
};
|
};
|
||||||
|
|
||||||
class box_linear : public ::gfx::blur::ibase {
|
class box_linear : public ::gfx::blur::base {
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<::gfx::blur::box_linear_data> m_data;
|
std::shared_ptr<::gfx::blur::box_linear_data> _data;
|
||||||
|
|
||||||
double_t m_size;
|
double_t _size;
|
||||||
std::pair<double_t, double_t> m_step_scale;
|
std::pair<double_t, double_t> _step_scale;
|
||||||
std::shared_ptr<::gs::texture> m_input_texture;
|
std::shared_ptr<::gs::texture> _input_texture;
|
||||||
std::shared_ptr<::gs::rendertarget> m_rendertarget;
|
std::shared_ptr<::gs::rendertarget> _rendertarget;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<::gs::rendertarget> m_rendertarget2;
|
std::shared_ptr<::gs::rendertarget> _rendertarget2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
box_linear();
|
box_linear();
|
||||||
|
@ -112,8 +112,8 @@ namespace gfx {
|
||||||
virtual std::shared_ptr<::gs::texture> get() override;
|
virtual std::shared_ptr<::gs::texture> get() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class box_linear_directional : public ::gfx::blur::box_linear, public ::gfx::blur::ibase_angle {
|
class box_linear_directional : public ::gfx::blur::box_linear, public ::gfx::blur::base_angle {
|
||||||
double_t m_angle;
|
double_t _angle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
box_linear_directional();
|
box_linear_directional();
|
||||||
|
|
|
@ -38,23 +38,23 @@ gfx::blur::box_data::box_data()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
try {
|
try {
|
||||||
char* file = obs_module_file("effects/blur/box.effect");
|
char* file = obs_module_file("effects/blur/box._effect");
|
||||||
m_effect = std::make_shared<::gs::effect>(file);
|
_effect = std::make_shared<::gs::effect>(file);
|
||||||
bfree(file);
|
bfree(file);
|
||||||
} catch (...) {
|
} 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()
|
gfx::blur::box_data::~box_data()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_effect.reset();
|
_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> gfx::blur::box_data::get_effect()
|
std::shared_ptr<::gs::effect> gfx::blur::box_data::get_effect()
|
||||||
{
|
{
|
||||||
return m_effect;
|
return _effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::blur::box_factory::box_factory() {}
|
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) {
|
switch (type) {
|
||||||
case ::gfx::blur::type::Area:
|
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::shared_ptr<::gfx::blur::box_data> gfx::blur::box_factory::data()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ulock(m_data_lock);
|
std::unique_lock<std::mutex> ulock(_data_lock);
|
||||||
std::shared_ptr<::gfx::blur::box_data> data = m_data.lock();
|
std::shared_ptr<::gfx::blur::box_data> data = _data.lock();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = std::make_shared<::gfx::blur::box_data>();
|
data = std::make_shared<::gfx::blur::box_data>();
|
||||||
m_data = data;
|
_data = data;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -194,18 +194,18 @@ std::shared_ptr<::gfx::blur::box_data> gfx::blur::box_factory::data()
|
||||||
return instance;
|
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();
|
auto gctx = gs::context();
|
||||||
m_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
m_rendertarget2 = 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() {}
|
gfx::blur::box::~box() {}
|
||||||
|
|
||||||
void gfx::blur::box::set_input(std::shared_ptr<::gs::texture> texture)
|
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()
|
::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()
|
double_t gfx::blur::box::get_size()
|
||||||
{
|
{
|
||||||
return m_size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::box::set_size(double_t width)
|
void gfx::blur::box::set_size(double_t width)
|
||||||
{
|
{
|
||||||
m_size = width;
|
_size = width;
|
||||||
if (m_size < 1.0) {
|
if (_size < 1.0) {
|
||||||
m_size = 1.0;
|
_size = 1.0;
|
||||||
}
|
}
|
||||||
if (m_size > MAX_BLUR_SIZE) {
|
if (_size > MAX_BLUR_SIZE) {
|
||||||
m_size = MAX_BLUR_SIZE;
|
_size = MAX_BLUR_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::box::set_step_scale(double_t x, double_t y)
|
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)
|
void gfx::blur::box::get_step_scale(double_t& x, double_t& y)
|
||||||
{
|
{
|
||||||
x = m_step_scale.first;
|
x = _step_scale.first;
|
||||||
y = m_step_scale.second;
|
y = _step_scale.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
double_t gfx::blur::box::get_step_scale_x()
|
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()
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::box::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
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);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
||||||
|
|
||||||
// Two Pass Blur
|
// Two Pass Blur
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
if (effect) {
|
if (effect) {
|
||||||
// Pass 1
|
// 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("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("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
|
||||||
effect->get_parameter("pSize").set_float(float_t(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
|
@ -288,11 +288,11 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass 2
|
// 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));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
|
@ -302,15 +302,15 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render()
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return _rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box::get()
|
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()
|
::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()
|
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)
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
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);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
||||||
|
|
||||||
// One Pass Blur
|
// One Pass Blur
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
if (effect) {
|
if (effect) {
|
||||||
effect->get_parameter("pImage").set_texture(m_input_texture);
|
effect->get_parameter("pImage").set_texture(_input_texture);
|
||||||
effect->get_parameter("pImageTexel")
|
effect->get_parameter("pImageTexel")
|
||||||
.set_float2(float_t(1. / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
|
.set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
|
||||||
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.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(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
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();
|
gs_blend_state_pop();
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return _rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
::gfx::blur::type gfx::blur::box_rotational::get_type()
|
::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)
|
void gfx::blur::box_rotational::set_center(double_t x, double_t y)
|
||||||
{
|
{
|
||||||
m_center.first = x;
|
_center.first = x;
|
||||||
m_center.second = y;
|
_center.second = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::box_rotational::get_center(double_t& x, double_t& y)
|
void gfx::blur::box_rotational::get_center(double_t& x, double_t& y)
|
||||||
{
|
{
|
||||||
x = m_center.first;
|
x = _center.first;
|
||||||
y = m_center.second;
|
y = _center.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
double_t gfx::blur::box_rotational::get_angle()
|
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)
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
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);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
||||||
|
|
||||||
// One Pass Blur
|
// One Pass Blur
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
if (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("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("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
|
||||||
effect->get_parameter("pSize").set_float(float_t(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
|
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(m_angle / m_size));
|
effect->get_parameter("pAngle").set_float(float_t(_angle / _size));
|
||||||
effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Rotate")) {
|
while (gs_effect_loop(effect->get_object(), "Rotate")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
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();
|
gs_blend_state_pop();
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return _rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
::gfx::blur::type gfx::blur::box_zoom::get_type()
|
::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)
|
void gfx::blur::box_zoom::set_center(double_t x, double_t y)
|
||||||
{
|
{
|
||||||
m_center.first = x;
|
_center.first = x;
|
||||||
m_center.second = y;
|
_center.second = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::box_zoom::get_center(double_t& x, double_t& y)
|
void gfx::blur::box_zoom::get_center(double_t& x, double_t& y)
|
||||||
{
|
{
|
||||||
x = m_center.first;
|
x = _center.first;
|
||||||
y = m_center.second;
|
y = _center.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
|
std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
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);
|
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
||||||
|
|
||||||
// One Pass Blur
|
// One Pass Blur
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
if (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("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("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
|
||||||
effect->get_parameter("pSize").set_float(float_t(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(m_size) * 2.0f + 1.0f)));
|
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(m_center.first), float_t(m_center.second));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Zoom")) {
|
while (gs_effect_loop(effect->get_object(), "Zoom")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
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();
|
gs_blend_state_pop();
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return _rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
namespace blur {
|
namespace blur {
|
||||||
class box_data {
|
class box_data {
|
||||||
std::shared_ptr<::gs::effect> m_effect;
|
std::shared_ptr<::gs::effect> _effect;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
box_data();
|
box_data();
|
||||||
|
@ -37,8 +37,8 @@ namespace gfx {
|
||||||
};
|
};
|
||||||
|
|
||||||
class box_factory : public ::gfx::blur::ifactory {
|
class box_factory : public ::gfx::blur::ifactory {
|
||||||
std::mutex m_data_lock;
|
std::mutex _data_lock;
|
||||||
std::weak_ptr<::gfx::blur::box_data> m_data;
|
std::weak_ptr<::gfx::blur::box_data> _data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
box_factory();
|
box_factory();
|
||||||
|
@ -46,7 +46,7 @@ namespace gfx {
|
||||||
|
|
||||||
virtual bool is_type_supported(::gfx::blur::type type) override;
|
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;
|
virtual double_t get_min_size(::gfx::blur::type type) override;
|
||||||
|
|
||||||
|
@ -80,17 +80,17 @@ namespace gfx {
|
||||||
static ::gfx::blur::box_factory& get();
|
static ::gfx::blur::box_factory& get();
|
||||||
};
|
};
|
||||||
|
|
||||||
class box : public ::gfx::blur::ibase {
|
class box : public ::gfx::blur::base {
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<::gfx::blur::box_data> m_data;
|
std::shared_ptr<::gfx::blur::box_data> _data;
|
||||||
|
|
||||||
double_t m_size;
|
double_t _size;
|
||||||
std::pair<double_t, double_t> m_step_scale;
|
std::pair<double_t, double_t> _step_scale;
|
||||||
std::shared_ptr<::gs::texture> m_input_texture;
|
std::shared_ptr<::gs::texture> _input_texture;
|
||||||
std::shared_ptr<::gs::rendertarget> m_rendertarget;
|
std::shared_ptr<::gs::rendertarget> _rendertarget;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<::gs::rendertarget> m_rendertarget2;
|
std::shared_ptr<::gs::rendertarget> _rendertarget2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
box();
|
box();
|
||||||
|
@ -112,8 +112,8 @@ namespace gfx {
|
||||||
virtual std::shared_ptr<::gs::texture> get() override;
|
virtual std::shared_ptr<::gs::texture> get() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class box_directional : public ::gfx::blur::box, public ::gfx::blur::ibase_angle {
|
class box_directional : public ::gfx::blur::box, public ::gfx::blur::base_angle {
|
||||||
double_t m_angle;
|
double_t _angle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
box_directional();
|
box_directional();
|
||||||
|
@ -127,10 +127,10 @@ namespace gfx {
|
||||||
};
|
};
|
||||||
|
|
||||||
class box_rotational : public ::gfx::blur::box,
|
class box_rotational : public ::gfx::blur::box,
|
||||||
public ::gfx::blur::ibase_angle,
|
public ::gfx::blur::base_angle,
|
||||||
public ::gfx::blur::ibase_center {
|
public ::gfx::blur::base_center {
|
||||||
std::pair<double_t, double_t> m_center;
|
std::pair<double_t, double_t> _center;
|
||||||
double_t m_angle;
|
double_t _angle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ::gfx::blur::type get_type() override;
|
virtual ::gfx::blur::type get_type() override;
|
||||||
|
@ -144,8 +144,8 @@ namespace gfx {
|
||||||
virtual std::shared_ptr<::gs::texture> render() override;
|
virtual std::shared_ptr<::gs::texture> render() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class box_zoom : public ::gfx::blur::box, public ::gfx::blur::ibase_center {
|
class box_zoom : public ::gfx::blur::box, public ::gfx::blur::base_center {
|
||||||
std::pair<double_t, double_t> m_center;
|
std::pair<double_t, double_t> _center;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ::gfx::blur::type get_type() override;
|
virtual ::gfx::blur::type get_type() override;
|
||||||
|
|
|
@ -54,23 +54,23 @@ gfx::blur::dual_filtering_data::dual_filtering_data()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
try {
|
try {
|
||||||
char* file = obs_module_file("effects/blur/dual-filtering.effect");
|
char* file = obs_module_file("effects/blur/dual-filtering._effect");
|
||||||
m_effect = std::make_shared<::gs::effect>(file);
|
_effect = std::make_shared<::gs::effect>(file);
|
||||||
bfree(file);
|
bfree(file);
|
||||||
} catch (...) {
|
} 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()
|
gfx::blur::dual_filtering_data::~dual_filtering_data()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_effect.reset();
|
_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> gfx::blur::dual_filtering_data::get_effect()
|
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() {}
|
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) {
|
switch (type) {
|
||||||
case ::gfx::blur::type::Area:
|
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::shared_ptr<::gfx::blur::dual_filtering_data> gfx::blur::dual_filtering_factory::data()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ulock(m_data_lock);
|
std::unique_lock<std::mutex> ulock(_data_lock);
|
||||||
std::shared_ptr<::gfx::blur::dual_filtering_data> data = m_data.lock();
|
std::shared_ptr<::gfx::blur::dual_filtering_data> data = _data.lock();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = std::make_shared<::gfx::blur::dual_filtering_data>();
|
data = std::make_shared<::gfx::blur::dual_filtering_data>();
|
||||||
m_data = data;
|
_data = data;
|
||||||
}
|
}
|
||||||
return 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()
|
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();
|
auto gctx = gs::context();
|
||||||
m_rendertargets.resize(MAX_LEVELS + 1);
|
_rendertargets.resize(MAX_LEVELS + 1);
|
||||||
for (size_t n = 0; n <= MAX_LEVELS; n++) {
|
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)
|
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()
|
::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()
|
double_t gfx::blur::dual_filtering::get_size()
|
||||||
{
|
{
|
||||||
return m_size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::dual_filtering::set_size(double_t width)
|
void gfx::blur::dual_filtering::set_size(double_t width)
|
||||||
{
|
{
|
||||||
m_size = width;
|
_size = width;
|
||||||
m_size_iterations = size_t(round(width));
|
_size_iterations = size_t(round(width));
|
||||||
if (m_size_iterations >= MAX_LEVELS) {
|
if (_size_iterations >= MAX_LEVELS) {
|
||||||
m_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()
|
std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
auto effect = m_data->get_effect();
|
auto effect = _data->get_effect();
|
||||||
if (!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_blend_state_push();
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
|
@ -249,9 +249,9 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
|
||||||
// Select Texture
|
// Select Texture
|
||||||
std::shared_ptr<gs::texture> tex_cur;
|
std::shared_ptr<gs::texture> tex_cur;
|
||||||
if (n > 1) {
|
if (n > 1) {
|
||||||
tex_cur = m_rendertargets[n - 1]->get_texture();
|
tex_cur = _rendertargets[n - 1]->get_texture();
|
||||||
} else {
|
} else {
|
||||||
tex_cur = m_input_texture;
|
tex_cur = _input_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reduce Size
|
// 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);
|
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.);
|
gs_ortho(0., 1., 0., 1., 0., 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Down")) {
|
while (gs_effect_loop(effect->get_object(), "Down")) {
|
||||||
gs_draw_sprite(tex_cur->get_object(), 0, 1, 1);
|
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
|
// Upsample
|
||||||
for (size_t n = actual_iterations; n > 0; n--) {
|
for (size_t n = actual_iterations; n > 0; n--) {
|
||||||
// Select Texture
|
// 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
|
// Get Size
|
||||||
uint32_t width = tex_cur->get_width();
|
uint32_t width = tex_cur->get_width();
|
||||||
|
@ -297,7 +297,7 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
|
||||||
height *= 2;
|
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.);
|
gs_ortho(0., 1., 0., 1., 0., 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Up")) {
|
while (gs_effect_loop(effect->get_object(), "Up")) {
|
||||||
gs_draw_sprite(tex_cur->get_object(), 0, 1, 1);
|
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();
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::get()
|
||||||
{
|
{
|
||||||
return m_rendertargets[0]->get_texture();
|
return _rendertargets[0]->get_texture();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
namespace blur {
|
namespace blur {
|
||||||
class dual_filtering_data {
|
class dual_filtering_data {
|
||||||
std::shared_ptr<::gs::effect> m_effect;
|
std::shared_ptr<::gs::effect> _effect;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dual_filtering_data();
|
dual_filtering_data();
|
||||||
|
@ -38,8 +38,8 @@ namespace gfx {
|
||||||
};
|
};
|
||||||
|
|
||||||
class dual_filtering_factory : public ::gfx::blur::ifactory {
|
class dual_filtering_factory : public ::gfx::blur::ifactory {
|
||||||
std::mutex m_data_lock;
|
std::mutex _data_lock;
|
||||||
std::weak_ptr<::gfx::blur::dual_filtering_data> m_data;
|
std::weak_ptr<::gfx::blur::dual_filtering_data> _data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dual_filtering_factory();
|
dual_filtering_factory();
|
||||||
|
@ -47,7 +47,7 @@ namespace gfx {
|
||||||
|
|
||||||
virtual bool is_type_supported(::gfx::blur::type type) override;
|
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;
|
virtual double_t get_min_size(::gfx::blur::type type) override;
|
||||||
|
|
||||||
|
@ -81,15 +81,15 @@ namespace gfx {
|
||||||
static ::gfx::blur::dual_filtering_factory& get();
|
static ::gfx::blur::dual_filtering_factory& get();
|
||||||
};
|
};
|
||||||
|
|
||||||
class dual_filtering : public ::gfx::blur::ibase {
|
class dual_filtering : public ::gfx::blur::base {
|
||||||
std::shared_ptr<::gfx::blur::dual_filtering_data> m_data;
|
std::shared_ptr<::gfx::blur::dual_filtering_data> _data;
|
||||||
|
|
||||||
double_t m_size;
|
double_t _size;
|
||||||
size_t m_size_iterations;
|
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:
|
public:
|
||||||
dual_filtering();
|
dual_filtering();
|
||||||
|
|
|
@ -45,8 +45,8 @@ gfx::blur::gaussian_linear_data::gaussian_linear_data()
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
{
|
{
|
||||||
char* file = obs_module_file("effects/blur/gaussian-linear.effect");
|
char* file = obs_module_file("effects/blur/gaussian-linear._effect");
|
||||||
m_effect = std::make_shared<gs::effect>(file);
|
_effect = std::make_shared<gs::effect>(file);
|
||||||
bfree(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);
|
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()
|
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()
|
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)
|
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)
|
if (width > MAX_BLUR_SIZE)
|
||||||
width = MAX_BLUR_SIZE;
|
width = MAX_BLUR_SIZE;
|
||||||
width -= 1;
|
width -= 1;
|
||||||
return m_kernels[width];
|
return _kernels[width];
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::blur::gaussian_linear_factory::gaussian_linear_factory() {}
|
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) {
|
switch (v) {
|
||||||
case ::gfx::blur::type::Area:
|
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::shared_ptr<::gfx::blur::gaussian_linear_data> gfx::blur::gaussian_linear_factory::data()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ulock(m_data_lock);
|
std::unique_lock<std::mutex> ulock(_data_lock);
|
||||||
std::shared_ptr<::gfx::blur::gaussian_linear_data> data = m_data.lock();
|
std::shared_ptr<::gfx::blur::gaussian_linear_data> data = _data.lock();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = std::make_shared<::gfx::blur::gaussian_linear_data>();
|
data = std::make_shared<::gfx::blur::gaussian_linear_data>();
|
||||||
m_data = data;
|
_data = data;
|
||||||
}
|
}
|
||||||
return 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()
|
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();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
m_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
m_rendertarget2 = 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() {}
|
gfx::blur::gaussian_linear::~gaussian_linear() {}
|
||||||
|
|
||||||
void gfx::blur::gaussian_linear::set_input(std::shared_ptr<::gs::texture> texture)
|
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()
|
::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()
|
double_t gfx::blur::gaussian_linear::get_size()
|
||||||
{
|
{
|
||||||
return m_size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::gaussian_linear::set_size(double_t width)
|
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.;
|
width = 1.;
|
||||||
if (width > MAX_BLUR_SIZE)
|
if (width > MAX_BLUR_SIZE)
|
||||||
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)
|
void gfx::blur::gaussian_linear::set_step_scale(double_t x, double_t y)
|
||||||
{
|
{
|
||||||
m_step_scale.first = x;
|
_step_scale.first = x;
|
||||||
m_step_scale.second = y;
|
_step_scale.second = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::gaussian_linear::get_step_scale(double_t& x, double_t& y)
|
void gfx::blur::gaussian_linear::get_step_scale(double_t& x, double_t& y)
|
||||||
{
|
{
|
||||||
x = m_step_scale.first;
|
x = _step_scale.first;
|
||||||
y = m_step_scale.second;
|
y = _step_scale.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
double_t gfx::blur::gaussian_linear::get_step_scale_x()
|
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()
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = _data->get_kernel(size_t(_size));
|
||||||
|
|
||||||
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
||||||
return m_input_texture;
|
return _input_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
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_function(GS_STENCIL_BOTH, GS_ALWAYS);
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
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("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.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(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
||||||
|
|
||||||
// First Pass
|
// 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);
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::swap(m_rendertarget, m_rendertarget2);
|
std::swap(_rendertarget, _rendertarget2);
|
||||||
effect->get_parameter("pImage").set_texture(m_rendertarget->get_texture());
|
effect->get_parameter("pImage").set_texture(_rendertarget->get_texture());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second Pass
|
// 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));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::swap(m_rendertarget, m_rendertarget2);
|
std::swap(_rendertarget, _rendertarget2);
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
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()
|
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() {}
|
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()
|
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)
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = _data->get_kernel(size_t(_size));
|
||||||
|
|
||||||
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
||||||
return m_input_texture;
|
return _input_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
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_function(GS_STENCIL_BOTH, GS_ALWAYS);
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
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")
|
effect->get_parameter("pImageTexel")
|
||||||
.set_float2(float_t(1.f / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
|
.set_float2(float_t(1.f / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
|
||||||
effect->get_parameter("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.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(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
||||||
|
|
||||||
// First Pass
|
// 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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
namespace blur {
|
namespace blur {
|
||||||
class gaussian_linear_data {
|
class gaussian_linear_data {
|
||||||
std::shared_ptr<::gs::effect> m_effect;
|
std::shared_ptr<::gs::effect> _effect;
|
||||||
std::vector<std::vector<float_t>> m_kernels;
|
std::vector<std::vector<float_t>> _kernels;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gaussian_linear_data();
|
gaussian_linear_data();
|
||||||
|
@ -39,8 +39,8 @@ namespace gfx {
|
||||||
};
|
};
|
||||||
|
|
||||||
class gaussian_linear_factory : public ::gfx::blur::ifactory {
|
class gaussian_linear_factory : public ::gfx::blur::ifactory {
|
||||||
std::mutex m_data_lock;
|
std::mutex _data_lock;
|
||||||
std::weak_ptr<::gfx::blur::gaussian_linear_data> m_data;
|
std::weak_ptr<::gfx::blur::gaussian_linear_data> _data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gaussian_linear_factory();
|
gaussian_linear_factory();
|
||||||
|
@ -48,7 +48,7 @@ namespace gfx {
|
||||||
|
|
||||||
virtual bool is_type_supported(::gfx::blur::type type) override;
|
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;
|
virtual double_t get_min_size(::gfx::blur::type type) override;
|
||||||
|
|
||||||
|
@ -82,17 +82,17 @@ namespace gfx {
|
||||||
static ::gfx::blur::gaussian_linear_factory& get();
|
static ::gfx::blur::gaussian_linear_factory& get();
|
||||||
};
|
};
|
||||||
|
|
||||||
class gaussian_linear : public ::gfx::blur::ibase {
|
class gaussian_linear : public ::gfx::blur::base {
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<::gfx::blur::gaussian_linear_data> m_data;
|
std::shared_ptr<::gfx::blur::gaussian_linear_data> _data;
|
||||||
|
|
||||||
double_t m_size;
|
double_t _size;
|
||||||
std::pair<double_t, double_t> m_step_scale;
|
std::pair<double_t, double_t> _step_scale;
|
||||||
std::shared_ptr<::gs::texture> m_input_texture;
|
std::shared_ptr<::gs::texture> _input_texture;
|
||||||
std::shared_ptr<::gs::rendertarget> m_rendertarget;
|
std::shared_ptr<::gs::rendertarget> _rendertarget;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<::gs::rendertarget> m_rendertarget2;
|
std::shared_ptr<::gs::rendertarget> _rendertarget2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gaussian_linear();
|
gaussian_linear();
|
||||||
|
@ -119,8 +119,8 @@ namespace gfx {
|
||||||
virtual std::shared_ptr<::gs::texture> get() override;
|
virtual std::shared_ptr<::gs::texture> get() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class gaussian_linear_directional : public ::gfx::blur::gaussian_linear, public ::gfx::blur::ibase_angle {
|
class gaussian_linear_directional : public ::gfx::blur::gaussian_linear, public ::gfx::blur::base_angle {
|
||||||
double_t m_angle;
|
double_t _angle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gaussian_linear_directional();
|
gaussian_linear_directional();
|
||||||
|
|
|
@ -45,8 +45,8 @@ gfx::blur::gaussian_data::gaussian_data()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
{
|
{
|
||||||
char* file = obs_module_file("effects/blur/gaussian.effect");
|
char* file = obs_module_file("effects/blur/gaussian._effect");
|
||||||
m_effect = std::make_shared<gs::effect>(file);
|
_effect = std::make_shared<gs::effect>(file);
|
||||||
bfree(file);
|
bfree(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,19 +77,19 @@ gfx::blur::gaussian_data::gaussian_data()
|
||||||
kernel_data.at(p) = float_t(kernel_math[p] * inverse_sum);
|
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()
|
gfx::blur::gaussian_data::~gaussian_data()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_effect.reset();
|
_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> gfx::blur::gaussian_data::get_effect()
|
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)
|
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)
|
if (width > MAX_BLUR_SIZE)
|
||||||
width = MAX_BLUR_SIZE;
|
width = MAX_BLUR_SIZE;
|
||||||
width -= 1;
|
width -= 1;
|
||||||
return m_kernels[width];
|
return _kernels[width];
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::blur::gaussian_factory::gaussian_factory() {}
|
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) {
|
switch (v) {
|
||||||
case ::gfx::blur::type::Area:
|
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::shared_ptr<::gfx::blur::gaussian_data> gfx::blur::gaussian_factory::data()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ulock(m_data_lock);
|
std::unique_lock<std::mutex> ulock(_data_lock);
|
||||||
std::shared_ptr<::gfx::blur::gaussian_data> data = m_data.lock();
|
std::shared_ptr<::gfx::blur::gaussian_data> data = _data.lock();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = std::make_shared<::gfx::blur::gaussian_data>();
|
data = std::make_shared<::gfx::blur::gaussian_data>();
|
||||||
m_data = data;
|
_data = data;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -240,18 +240,18 @@ std::shared_ptr<::gfx::blur::gaussian_data> gfx::blur::gaussian_factory::data()
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::blur::gaussian::gaussian()
|
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();
|
auto gctx = gs::context();
|
||||||
m_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
m_rendertarget2 = 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() {}
|
gfx::blur::gaussian::~gaussian() {}
|
||||||
|
|
||||||
void gfx::blur::gaussian::set_input(std::shared_ptr<::gs::texture> texture)
|
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()
|
::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()
|
double_t gfx::blur::gaussian::get_size()
|
||||||
{
|
{
|
||||||
return m_size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::gaussian::set_size(double_t width)
|
void gfx::blur::gaussian::set_size(double_t width)
|
||||||
|
@ -270,44 +270,44 @@ void gfx::blur::gaussian::set_size(double_t width)
|
||||||
width = 1.;
|
width = 1.;
|
||||||
if (width > MAX_BLUR_SIZE)
|
if (width > MAX_BLUR_SIZE)
|
||||||
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)
|
void gfx::blur::gaussian::set_step_scale(double_t x, double_t y)
|
||||||
{
|
{
|
||||||
m_step_scale.first = x;
|
_step_scale.first = x;
|
||||||
m_step_scale.second = y;
|
_step_scale.second = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::blur::gaussian::get_step_scale(double_t& x, double_t& y)
|
void gfx::blur::gaussian::get_step_scale(double_t& x, double_t& y)
|
||||||
{
|
{
|
||||||
x = m_step_scale.first;
|
x = _step_scale.first;
|
||||||
y = m_step_scale.second;
|
y = _step_scale.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
double_t gfx::blur::gaussian::get_step_scale_x()
|
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()
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = _data->get_kernel(size_t(_size));
|
||||||
|
|
||||||
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
||||||
return m_input_texture;
|
return _input_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
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_function(GS_STENCIL_BOTH, GS_ALWAYS);
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
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("pStepScale").set_float2(float_t(m_step_scale.first), float_t(m_step_scale.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(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
||||||
|
|
||||||
// First Pass
|
// 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);
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::swap(m_rendertarget, m_rendertarget2);
|
std::swap(_rendertarget, _rendertarget2);
|
||||||
effect->get_parameter("pImage").set_texture(m_rendertarget->get_texture());
|
effect->get_parameter("pImage").set_texture(_rendertarget->get_texture());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second Pass
|
// 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));
|
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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::swap(m_rendertarget, m_rendertarget2);
|
std::swap(_rendertarget, _rendertarget2);
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
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()
|
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.) {}
|
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()
|
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)
|
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()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = _data->get_kernel(size_t(_size));
|
||||||
|
|
||||||
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
||||||
return m_input_texture;
|
return _input_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
obs_enter_graphics();
|
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_function(GS_STENCIL_BOTH, GS_ALWAYS);
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
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")
|
effect->get_parameter("pImageTexel")
|
||||||
.set_float2(float_t(1.f / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
|
.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("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
|
||||||
effect->get_parameter("pSize").set_float(float_t(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
||||||
|
|
||||||
// First Pass
|
// 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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
while (gs_effect_loop(effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
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();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = _data->get_kernel(size_t(_size));
|
||||||
|
|
||||||
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
||||||
return m_input_texture;
|
return _input_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
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_function(GS_STENCIL_BOTH, GS_ALWAYS);
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
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("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("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
|
||||||
effect->get_parameter("pSize").set_float(float_t(m_size));
|
effect->get_parameter("pSize").set_float(float_t(_size));
|
||||||
effect->get_parameter("pAngle").set_float(float_t(m_angle / m_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("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);
|
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
||||||
|
|
||||||
// First Pass
|
// 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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Rotate")) {
|
while (gs_effect_loop(effect->get_object(), "Rotate")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
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()
|
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)
|
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()
|
::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();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = _data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = _data->get_kernel(size_t(_size));
|
||||||
|
|
||||||
if (!effect || ((m_step_scale.first + m_step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
if (!effect || ((_step_scale.first + _step_scale.second) < std::numeric_limits<double_t>::epsilon())) {
|
||||||
return m_input_texture;
|
return _input_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t width = float_t(m_input_texture->get_width());
|
float_t width = float_t(_input_texture->get_width());
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
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_function(GS_STENCIL_BOTH, GS_ALWAYS);
|
||||||
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
|
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("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("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
|
||||||
effect->get_parameter("pSize").set_float(float_t(m_size));
|
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("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);
|
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE);
|
||||||
|
|
||||||
// First Pass
|
// 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.);
|
gs_ortho(0, 1., 0, 1., 0, 1.);
|
||||||
while (gs_effect_loop(effect->get_object(), "Zoom")) {
|
while (gs_effect_loop(effect->get_object(), "Zoom")) {
|
||||||
gs_draw_sprite(nullptr, 0, 1, 1);
|
gs_draw_sprite(nullptr, 0, 1, 1);
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
namespace blur {
|
namespace blur {
|
||||||
class gaussian_data {
|
class gaussian_data {
|
||||||
std::shared_ptr<::gs::effect> m_effect;
|
std::shared_ptr<::gs::effect> _effect;
|
||||||
std::vector<std::vector<float_t>> m_kernels;
|
std::vector<std::vector<float_t>> _kernels;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gaussian_data();
|
gaussian_data();
|
||||||
|
@ -39,8 +39,8 @@ namespace gfx {
|
||||||
};
|
};
|
||||||
|
|
||||||
class gaussian_factory : public ::gfx::blur::ifactory {
|
class gaussian_factory : public ::gfx::blur::ifactory {
|
||||||
std::mutex m_data_lock;
|
std::mutex _data_lock;
|
||||||
std::weak_ptr<::gfx::blur::gaussian_data> m_data;
|
std::weak_ptr<::gfx::blur::gaussian_data> _data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gaussian_factory();
|
gaussian_factory();
|
||||||
|
@ -48,7 +48,7 @@ namespace gfx {
|
||||||
|
|
||||||
virtual bool is_type_supported(::gfx::blur::type type) override;
|
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;
|
virtual double_t get_min_size(::gfx::blur::type type) override;
|
||||||
|
|
||||||
|
@ -82,17 +82,17 @@ namespace gfx {
|
||||||
static ::gfx::blur::gaussian_factory& get();
|
static ::gfx::blur::gaussian_factory& get();
|
||||||
};
|
};
|
||||||
|
|
||||||
class gaussian : public ::gfx::blur::ibase {
|
class gaussian : public ::gfx::blur::base {
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<::gfx::blur::gaussian_data> m_data;
|
std::shared_ptr<::gfx::blur::gaussian_data> _data;
|
||||||
|
|
||||||
double_t m_size;
|
double_t _size;
|
||||||
std::pair<double_t, double_t> m_step_scale;
|
std::pair<double_t, double_t> _step_scale;
|
||||||
std::shared_ptr<::gs::texture> m_input_texture;
|
std::shared_ptr<::gs::texture> _input_texture;
|
||||||
std::shared_ptr<::gs::rendertarget> m_rendertarget;
|
std::shared_ptr<::gs::rendertarget> _rendertarget;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<::gs::rendertarget> m_rendertarget2;
|
std::shared_ptr<::gs::rendertarget> _rendertarget2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gaussian();
|
gaussian();
|
||||||
|
@ -119,7 +119,7 @@ namespace gfx {
|
||||||
virtual std::shared_ptr<::gs::texture> get() override;
|
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;
|
double_t m_angle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -135,8 +135,8 @@ namespace gfx {
|
||||||
};
|
};
|
||||||
|
|
||||||
class gaussian_rotational : public ::gfx::blur::gaussian,
|
class gaussian_rotational : public ::gfx::blur::gaussian,
|
||||||
public ::gfx::blur::ibase_angle,
|
public ::gfx::blur::base_angle,
|
||||||
public ::gfx::blur::ibase_center {
|
public ::gfx::blur::base_center {
|
||||||
std::pair<double_t, double_t> m_center;
|
std::pair<double_t, double_t> m_center;
|
||||||
double_t m_angle;
|
double_t m_angle;
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ namespace gfx {
|
||||||
virtual std::shared_ptr<::gs::texture> render() override;
|
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;
|
std::pair<double_t, double_t> m_center;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -133,22 +133,22 @@ void gfx::effect_source::get_properties(obs_properties_t* properties)
|
||||||
{
|
{
|
||||||
obs_property_t* p = nullptr;
|
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);
|
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, P_TRANSLATE(P_DESC(T_TYPE)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(T_TYPE)));
|
||||||
obs_property_list_add_int(p, P_TRANSLATE(T_TYPE_TEXT), (long long)InputTypes::Text);
|
obs_property_list_add_int(p, D_TRANSLATE(T_TYPE_TEXT), (long long)InputTypes::Text);
|
||||||
obs_property_list_add_int(p, P_TRANSLATE(T_TYPE_FILE), (long long)InputTypes::File);
|
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);
|
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);
|
p = obs_properties_add_text(properties, D_INPUT_TEXT, D_TRANSLATE(T_INPUT_TEXT), OBS_TEXT_MULTILINE);
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(T_INPUT_TEXT)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(T_INPUT_TEXT)));
|
||||||
obs_property_set_modified_callback2(p, property_input_modified, this);
|
obs_property_set_modified_callback2(p, property_input_modified, this);
|
||||||
|
|
||||||
{
|
{
|
||||||
char* tmp_path = obs_module_file(m_defaultShaderPath.c_str());
|
char* tmp_path = obs_module_file(m_defaultShaderPath.c_str());
|
||||||
p = obs_properties_add_path(
|
p = obs_properties_add_path(
|
||||||
properties, D_INPUT_FILE, P_TRANSLATE(T_INPUT_FILE), OBS_PATH_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);
|
"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)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(T_INPUT_FILE)));
|
||||||
obs_property_set_modified_callback2(p, property_input_modified, this);
|
obs_property_set_modified_callback2(p, property_input_modified, this);
|
||||||
bfree(tmp_path);
|
bfree(tmp_path);
|
||||||
}
|
}
|
||||||
|
@ -178,10 +178,10 @@ void gfx::effect_source::get_properties(obs_properties_t* properties)
|
||||||
// Switch between File and Source Input
|
// Switch between File and Source Input
|
||||||
p = obs_properties_add_list(properties, prm.second->ui.names[0], prm.second->ui.descs[0],
|
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_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_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, D_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_SOURCE), 1);
|
||||||
|
|
||||||
// Texture Path
|
// Texture Path
|
||||||
char* defaultPath = obs_module_file("");
|
char* defaultPath = obs_module_file("");
|
||||||
|
|
|
@ -19,21 +19,21 @@
|
||||||
|
|
||||||
gfx::source_texture::~source_texture()
|
gfx::source_texture::~source_texture()
|
||||||
{
|
{
|
||||||
if (child && parent) {
|
if (_child && _parent) {
|
||||||
obs_source_remove_active_child(parent->get(), child->get());
|
obs_source_remove_active_child(_parent->get(), _child->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.reset();
|
_parent.reset();
|
||||||
child.reset();
|
_child.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::source_texture::source_texture(obs_source_t* _parent)
|
gfx::source_texture::source_texture(obs_source_t* _parent)
|
||||||
{
|
{
|
||||||
if (!_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);
|
_parent = std::make_shared<obs::source>(_parent, false, false);
|
||||||
render_target = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
_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)
|
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");
|
throw std::invalid_argument("source must not be null");
|
||||||
}
|
}
|
||||||
if (!obs_source_add_active_child(_parent, _source)) {
|
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)
|
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) {
|
if (!_name) {
|
||||||
throw std::invalid_argument("name must not be null");
|
throw std::invalid_argument("name must not be null");
|
||||||
}
|
}
|
||||||
child = std::make_shared<obs::source>(_name, true, true);
|
_child = std::make_shared<obs::source>(_name, true, true);
|
||||||
if (!obs_source_add_active_child(_parent, child->get())) {
|
if (!obs_source_add_active_child(_parent, _child->get())) {
|
||||||
throw std::runtime_error("parent is contained in child");
|
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)
|
gfx::source_texture::source_texture(std::shared_ptr<obs::source> pchild, std::shared_ptr<obs::source> pparent)
|
||||||
{
|
{
|
||||||
if (!pchild) {
|
if (!pchild) {
|
||||||
throw std::invalid_argument("child must not be null");
|
throw std::invalid_argument("_child must not be null");
|
||||||
}
|
}
|
||||||
if (!pparent) {
|
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())) {
|
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->_child = pchild;
|
||||||
this->parent = pparent;
|
this->_parent = pparent;
|
||||||
this->render_target = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
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)
|
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()
|
obs_source_t* gfx::source_texture::get_object()
|
||||||
{
|
{
|
||||||
if (child) {
|
if (_child) {
|
||||||
return child->get();
|
return _child->get();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_t* gfx::source_texture::get_parent()
|
obs_source_t* gfx::source_texture::get_parent()
|
||||||
{
|
{
|
||||||
return parent->get();
|
return _parent->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::source_texture::clear()
|
void gfx::source_texture::clear()
|
||||||
{
|
{
|
||||||
if (child && parent) {
|
if (_child && _parent) {
|
||||||
obs_source_remove_active_child(parent->get(), child->get());
|
obs_source_remove_active_child(_parent->get(), _child->get());
|
||||||
}
|
}
|
||||||
child->clear();
|
_child->clear();
|
||||||
child.reset();
|
_child.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<gs::texture> gfx::source_texture::render(size_t width, size_t height)
|
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)) {
|
if ((height == 0) || (height >= 16384)) {
|
||||||
throw std::runtime_error("Height too large or too small.");
|
throw std::runtime_error("Height too large or too small.");
|
||||||
}
|
}
|
||||||
if (child->destroyed() || parent->destroyed()) {
|
if (_child->destroyed() || _parent->destroyed()) {
|
||||||
return nullptr;
|
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 black;
|
||||||
vec4_zero(&black);
|
vec4_zero(&black);
|
||||||
gs_ortho(0, (float_t)width, 0, (float_t)height, 0, 1);
|
gs_ortho(0, (float_t)width, 0, (float_t)height, 0, 1);
|
||||||
gs_clear(GS_CLEAR_COLOR, &black, 0, 0);
|
gs_clear(GS_CLEAR_COLOR, &black, 0, 0);
|
||||||
if (child) {
|
if (_child) {
|
||||||
obs_source_video_render(child->get());
|
obs_source_video_render(_child->get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<gs::texture> tex;
|
std::shared_ptr<gs::texture> tex;
|
||||||
render_target->get_texture(tex);
|
_rt->get_texture(tex);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,10 @@
|
||||||
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
class source_texture {
|
class source_texture {
|
||||||
std::shared_ptr<obs::source> parent;
|
std::shared_ptr<obs::source> _parent;
|
||||||
std::shared_ptr<obs::source> child;
|
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);
|
source_texture(obs_source_t* parent);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
//#define OBS_LOAD_EFFECT_FILE
|
//#define OBS_LOAD_EFFECT_FILE
|
||||||
|
|
||||||
gs::effect::effect() : m_effect(nullptr) {}
|
gs::effect::effect() : _effect(nullptr) {}
|
||||||
|
|
||||||
gs::effect::effect(std::string file) : effect()
|
gs::effect::effect(std::string file) : effect()
|
||||||
{
|
{
|
||||||
|
@ -72,8 +72,8 @@ gs::effect::effect(std::string file) : effect()
|
||||||
|
|
||||||
char* errorMessage = nullptr;
|
char* errorMessage = nullptr;
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage);
|
_effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage);
|
||||||
if (!m_effect || errorMessage) {
|
if (!_effect || errorMessage) {
|
||||||
std::string error = "Generic Error";
|
std::string error = "Generic Error";
|
||||||
if (errorMessage) {
|
if (errorMessage) {
|
||||||
error = std::string(errorMessage);
|
error = std::string(errorMessage);
|
||||||
|
@ -88,8 +88,8 @@ gs::effect::effect(std::string code, std::string name) : effect()
|
||||||
{
|
{
|
||||||
char* errorMessage = nullptr;
|
char* errorMessage = nullptr;
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage);
|
_effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage);
|
||||||
if (!m_effect || errorMessage) {
|
if (!_effect || errorMessage) {
|
||||||
std::string error = "Generic Error";
|
std::string error = "Generic Error";
|
||||||
if (errorMessage) {
|
if (errorMessage) {
|
||||||
error = std::string(errorMessage);
|
error = std::string(errorMessage);
|
||||||
|
@ -102,22 +102,22 @@ gs::effect::effect(std::string code, std::string name) : effect()
|
||||||
gs::effect::~effect()
|
gs::effect::~effect()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
gs_effect_destroy(m_effect);
|
gs_effect_destroy(_effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_effect_t* gs::effect::get_object()
|
gs_effect_t* gs::effect::get_object()
|
||||||
{
|
{
|
||||||
return m_effect;
|
return _effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t gs::effect::count_parameters()
|
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()
|
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;
|
std::list<gs::effect_parameter> ps;
|
||||||
for (size_t idx = 0; idx < num; idx++) {
|
for (size_t idx = 0; idx < num; idx++) {
|
||||||
ps.emplace_back(get_parameter(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::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)
|
if (!param)
|
||||||
throw std::invalid_argument("parameter with index not found");
|
throw std::invalid_argument("parameter with index not found");
|
||||||
return effect_parameter(param);
|
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)
|
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);
|
return (param != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gs::effect::has_parameter(std::string name, effect_parameter::type type)
|
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)
|
if (param == nullptr)
|
||||||
return false;
|
return false;
|
||||||
gs::effect_parameter eprm(param);
|
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::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)
|
if (!param)
|
||||||
throw std::invalid_argument("parameter with name not found");
|
throw std::invalid_argument("parameter with name not found");
|
||||||
return effect_parameter(param);
|
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)
|
if (!param)
|
||||||
throw std::invalid_argument("param is null");
|
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()
|
std::string gs::effect_parameter::get_name()
|
||||||
{
|
{
|
||||||
return m_paramInfo.name;
|
return _param_info.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::effect_parameter::type gs::effect_parameter::get_type()
|
gs::effect_parameter::type gs::effect_parameter::get_type()
|
||||||
{
|
{
|
||||||
switch (m_paramInfo.type) {
|
switch (_param_info.type) {
|
||||||
case GS_SHADER_PARAM_BOOL:
|
case GS_SHADER_PARAM_BOOL:
|
||||||
return type::Boolean;
|
return type::Boolean;
|
||||||
case GS_SHADER_PARAM_FLOAT:
|
case GS_SHADER_PARAM_FLOAT:
|
||||||
|
@ -206,28 +206,28 @@ void gs::effect_parameter::set_bool(bool v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Boolean)
|
if (get_type() != type::Boolean)
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_bool_array(bool v[], size_t sz)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Boolean)
|
if (get_type() != type::Boolean)
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_float(float_t x)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Float)
|
if (get_type() != type::Float)
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_float2(vec2& v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Float2)
|
if (get_type() != type::Float2)
|
||||||
throw std::bad_cast();
|
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)
|
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)
|
if (get_type() != type::Float2)
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
vec2 v = {{x, y}};
|
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)
|
void gs::effect_parameter::set_float3(vec3& v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Float3)
|
if (get_type() != type::Float3)
|
||||||
throw std::bad_cast();
|
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)
|
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)
|
if (get_type() != type::Float3)
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
vec3 v = {{x, y, z, 0}};
|
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)
|
void gs::effect_parameter::set_float4(vec4& v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Float4)
|
if (get_type() != type::Float4)
|
||||||
throw std::bad_cast();
|
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)
|
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)
|
if (get_type() != type::Float4)
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
vec4 v = {{x, y, z, w}};
|
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)
|
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)
|
if ((get_type() != type::Float) && (get_type() != type::Float2) && (get_type() != type::Float3)
|
||||||
&& (get_type() != type::Float4))
|
&& (get_type() != type::Float4))
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_int(int32_t x)
|
||||||
{
|
{
|
||||||
if ((get_type() != type::Integer) && (get_type() != type::Unknown))
|
if ((get_type() != type::Integer) && (get_type() != type::Unknown))
|
||||||
throw std::bad_cast();
|
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)
|
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))
|
if ((get_type() != type::Integer2) && (get_type() != type::Unknown))
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
int32_t v[2] = {x, y};
|
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)
|
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))
|
if ((get_type() != type::Integer3) && (get_type() != type::Unknown))
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
int32_t v[3] = {x, y, z};
|
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)
|
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))
|
if ((get_type() != type::Integer4) && (get_type() != type::Unknown))
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
int32_t v[4] = {x, y, z, w};
|
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)
|
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)
|
if ((get_type() != type::Integer) && (get_type() != type::Integer2) && (get_type() != type::Integer3)
|
||||||
&& (get_type() != type::Integer4) && (get_type() != type::Unknown))
|
&& (get_type() != type::Integer4) && (get_type() != type::Unknown))
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_matrix(matrix4& v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Matrix)
|
if (get_type() != type::Matrix)
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_texture(std::shared_ptr<gs::texture> v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Texture)
|
if (get_type() != type::Texture)
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_texture(gs_texture_t* v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Texture)
|
if (get_type() != type::Texture)
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_sampler(std::shared_ptr<gs::sampler> v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Texture)
|
if (get_type() != type::Texture)
|
||||||
throw std::bad_cast();
|
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)
|
void gs::effect_parameter::set_sampler(gs_sampler_state* v)
|
||||||
{
|
{
|
||||||
if (get_type() != type::Texture)
|
if (get_type() != type::Texture)
|
||||||
throw std::bad_cast();
|
throw std::bad_cast();
|
||||||
gs_effect_set_next_sampler(m_param, v);
|
gs_effect_set_next_sampler(_param, v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
|
|
||||||
namespace gs {
|
namespace gs {
|
||||||
class effect_parameter {
|
class effect_parameter {
|
||||||
|
gs_eparam_t* _param;
|
||||||
|
gs_effect_param_info _param_info;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class type : uint8_t {
|
enum class type : uint8_t {
|
||||||
Unknown,
|
Unknown,
|
||||||
|
@ -84,13 +87,12 @@ namespace gs {
|
||||||
void set_texture(gs_texture_t* v);
|
void set_texture(gs_texture_t* v);
|
||||||
void set_sampler(std::shared_ptr<gs::sampler> v);
|
void set_sampler(std::shared_ptr<gs::sampler> v);
|
||||||
void set_sampler(gs_sampler_state* v);
|
void set_sampler(gs_sampler_state* v);
|
||||||
|
|
||||||
private:
|
|
||||||
gs_eparam_t* m_param;
|
|
||||||
gs_effect_param_info m_paramInfo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class effect {
|
class effect {
|
||||||
|
protected:
|
||||||
|
gs_effect_t* _effect;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
effect();
|
effect();
|
||||||
effect(std::string file);
|
effect(std::string file);
|
||||||
|
@ -106,7 +108,5 @@ namespace gs {
|
||||||
bool has_parameter(std::string name);
|
bool has_parameter(std::string name);
|
||||||
bool has_parameter(std::string name, effect_parameter::type type);
|
bool has_parameter(std::string name, effect_parameter::type type);
|
||||||
|
|
||||||
protected:
|
|
||||||
gs_effect_t* m_effect;
|
|
||||||
};
|
};
|
||||||
} // namespace gs
|
} // namespace gs
|
||||||
|
|
|
@ -35,7 +35,7 @@ gs::index_buffer::index_buffer(uint32_t maximumVertices)
|
||||||
{
|
{
|
||||||
this->reserve(maximumVertices);
|
this->reserve(maximumVertices);
|
||||||
auto gctx = gs::context();
|
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) {}
|
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()
|
gs::index_buffer::~index_buffer()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
gs_indexbuffer_destroy(m_indexBuffer);
|
gs_indexbuffer_destroy(_index_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_indexbuffer_t* gs::index_buffer::get()
|
gs_indexbuffer_t* gs::index_buffer::get()
|
||||||
|
@ -65,7 +65,7 @@ gs_indexbuffer_t* gs::index_buffer::get(bool refreshGPU)
|
||||||
{
|
{
|
||||||
if (refreshGPU) {
|
if (refreshGPU) {
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
gs_indexbuffer_flush(m_indexBuffer);
|
gs_indexbuffer_flush(_index_buffer);
|
||||||
}
|
}
|
||||||
return m_indexBuffer;
|
return _index_buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,6 @@ namespace gs {
|
||||||
gs_indexbuffer_t* get(bool refreshGPU);
|
gs_indexbuffer_t* get(bool refreshGPU);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
gs_indexbuffer_t* m_indexBuffer;
|
gs_indexbuffer_t* _index_buffer;
|
||||||
};
|
};
|
||||||
} // namespace gs
|
} // namespace gs
|
||||||
|
|
|
@ -72,44 +72,44 @@ struct gs_d3d11_device {
|
||||||
|
|
||||||
gs::mipmapper::~mipmapper()
|
gs::mipmapper::~mipmapper()
|
||||||
{
|
{
|
||||||
vertex_buffer.reset();
|
_vb.reset();
|
||||||
render_target.reset();
|
_rt.reset();
|
||||||
effect.reset();
|
_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::mipmapper::mipmapper()
|
gs::mipmapper::mipmapper()
|
||||||
{
|
{
|
||||||
vertex_buffer = std::make_unique<gs::vertex_buffer>(uint32_t(6u), uint8_t(1u));
|
_vb = std::make_unique<gs::vertex_buffer>(uint32_t(6u), uint8_t(1u));
|
||||||
auto v0 = vertex_buffer->at(0);
|
auto v0 = _vb->at(0);
|
||||||
v0.position->x = 0;
|
v0.position->x = 0;
|
||||||
v0.position->y = 0;
|
v0.position->y = 0;
|
||||||
v0.uv[0]->x = 0;
|
v0.uv[0]->x = 0;
|
||||||
v0.uv[0]->y = 0;
|
v0.uv[0]->y = 0;
|
||||||
|
|
||||||
auto v1 = vertex_buffer->at(1);
|
auto v1 = _vb->at(1);
|
||||||
auto v4 = vertex_buffer->at(4);
|
auto v4 = _vb->at(4);
|
||||||
v4.position->x = v1.position->x = 1.0;
|
v4.position->x = v1.position->x = 1.0;
|
||||||
v4.position->y = v1.position->y = 0;
|
v4.position->y = v1.position->y = 0;
|
||||||
v4.uv[0]->x = v1.uv[0]->x = 1.0;
|
v4.uv[0]->x = v1.uv[0]->x = 1.0;
|
||||||
v4.uv[0]->y = v1.uv[0]->y = 0;
|
v4.uv[0]->y = v1.uv[0]->y = 0;
|
||||||
|
|
||||||
auto v2 = vertex_buffer->at(2);
|
auto v2 = _vb->at(2);
|
||||||
auto v3 = vertex_buffer->at(3);
|
auto v3 = _vb->at(3);
|
||||||
v3.position->x = v2.position->x = 0;
|
v3.position->x = v2.position->x = 0;
|
||||||
v3.position->y = v2.position->y = 1.0;
|
v3.position->y = v2.position->y = 1.0;
|
||||||
v3.uv[0]->x = v2.uv[0]->x = 0;
|
v3.uv[0]->x = v2.uv[0]->x = 0;
|
||||||
v3.uv[0]->y = v2.uv[0]->y = 1.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->x = 1.0;
|
||||||
v5.position->y = 1.0;
|
v5.position->y = 1.0;
|
||||||
v5.uv[0]->x = 1.0;
|
v5.uv[0]->x = 1.0;
|
||||||
v5.uv[0]->y = 1.0;
|
v5.uv[0]->y = 1.0;
|
||||||
|
|
||||||
vertex_buffer->update();
|
_vb->update();
|
||||||
|
|
||||||
char* effect_file = obs_module_file("effects/mipgen.effect");
|
char* effect_file = obs_module_file("effects/mipgen._effect");
|
||||||
effect = std::make_unique<gs::effect>(effect_file);
|
_effect = std::make_unique<gs::effect>(effect_file);
|
||||||
bfree(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());
|
//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.
|
// 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())) {
|
if ((!_rt) || (source->get_color_format() != _rt->get_color_format())) {
|
||||||
render_target = std::make_unique<gs::rendertarget>(source->get_color_format(), GS_ZS_NONE);
|
_rt = std::make_unique<gs::rendertarget>(source->get_color_format(), GS_ZS_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
|
@ -189,7 +189,7 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_load_vertexbuffer(vertex_buffer->update());
|
gs_load_vertexbuffer(_vb->update());
|
||||||
gs_load_indexbuffer(nullptr);
|
gs_load_indexbuffer(nullptr);
|
||||||
|
|
||||||
if (source->get_type() == gs::texture::type::Normal) {
|
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
|
// Draw mipmap layer
|
||||||
try {
|
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_set_cull_mode(GS_NEITHER);
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
|
@ -252,13 +252,13 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
|
||||||
vec4_zero(&black);
|
vec4_zero(&black);
|
||||||
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0);
|
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0);
|
||||||
|
|
||||||
effect->get_parameter("image").set_texture(target);
|
_effect->get_parameter("image").set_texture(target);
|
||||||
effect->get_parameter("level").set_int(int32_t(mip - 1));
|
_effect->get_parameter("level").set_int(int32_t(mip - 1));
|
||||||
effect->get_parameter("imageTexel").set_float2(texel_width, texel_height);
|
_effect->get_parameter("imageTexel").set_float2(texel_width, texel_height);
|
||||||
effect->get_parameter("strength").set_float(strength);
|
_effect->get_parameter("strength").set_float(strength);
|
||||||
|
|
||||||
while (gs_effect_loop(effect->get_object(), technique.c_str())) {
|
while (gs_effect_loop(_effect->get_object(), technique.c_str())) {
|
||||||
gs_draw(gs_draw_mode::GS_TRIS, 0, vertex_buffer->size());
|
gs_draw(gs_draw_mode::GS_TRIS, 0, _vb->size());
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
P_LOG_ERROR("Failed to render mipmap layer.");
|
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) {
|
if (device_type == GS_DEVICE_DIRECT3D_11) {
|
||||||
// Copy
|
// Copy
|
||||||
ID3D11Texture2D* rt =
|
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)));
|
uint32_t level = uint32_t(D3D11CalcSubresource(UINT(mip), 0, UINT(mip_levels)));
|
||||||
dev->context->CopySubresourceRegion(target_t2, level, 0, 0, 0, rt, 0, NULL);
|
dev->context->CopySubresourceRegion(target_t2, level, 0, 0, 0, rt, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@
|
||||||
|
|
||||||
namespace gs {
|
namespace gs {
|
||||||
class mipmapper {
|
class mipmapper {
|
||||||
std::unique_ptr<gs::vertex_buffer> vertex_buffer;
|
std::unique_ptr<gs::vertex_buffer> _vb;
|
||||||
std::unique_ptr<gs::rendertarget> render_target;
|
std::unique_ptr<gs::rendertarget> _rt;
|
||||||
std::unique_ptr<gs::effect> effect;
|
std::unique_ptr<gs::effect> _effect;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class generator : uint8_t {
|
enum class generator : uint8_t {
|
||||||
|
|
|
@ -35,16 +35,16 @@
|
||||||
gs::rendertarget::~rendertarget()
|
gs::rendertarget::~rendertarget()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
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)
|
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();
|
auto gctx = gs::context();
|
||||||
render_target = gs_texrender_create(colorFormat, zsFormat);
|
_render_target = gs_texrender_create(colorFormat, zsFormat);
|
||||||
if (!render_target) {
|
if (!_render_target) {
|
||||||
throw std::runtime_error("Failed to create 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()
|
gs_texture_t* gs::rendertarget::get_object()
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
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;
|
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()
|
gs_color_format gs::rendertarget::get_color_format()
|
||||||
{
|
{
|
||||||
return color_format;
|
return _color_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_zstencil_format gs::rendertarget::get_zstencil_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)
|
gs::rendertarget_op::rendertarget_op(gs::rendertarget* rt, uint32_t width, uint32_t height) : parent(rt)
|
||||||
{
|
{
|
||||||
if (parent == nullptr)
|
if (parent == nullptr)
|
||||||
throw std::invalid_argument("rt");
|
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.");
|
throw std::logic_error("Can't start rendering to the same render target twice.");
|
||||||
|
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
gs_texrender_reset(parent->render_target);
|
gs_texrender_reset(parent->_render_target);
|
||||||
if (!gs_texrender_begin(parent->render_target, width, height)) {
|
if (!gs_texrender_begin(parent->_render_target, width, height)) {
|
||||||
throw std::runtime_error("Failed to begin rendering to render target.");
|
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)
|
gs::rendertarget_op::rendertarget_op(gs::rendertarget_op&& r)
|
||||||
|
@ -118,6 +118,6 @@ gs::rendertarget_op::~rendertarget_op()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
gs_texrender_end(parent->render_target);
|
gs_texrender_end(parent->_render_target);
|
||||||
parent->is_being_rendered = false;
|
parent->_is_being_rendered = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,11 +39,11 @@ namespace gs {
|
||||||
friend class rendertarget_op;
|
friend class rendertarget_op;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
gs_texrender_t* render_target;
|
gs_texrender_t* _render_target;
|
||||||
bool is_being_rendered;
|
bool _is_being_rendered;
|
||||||
|
|
||||||
gs_color_format color_format;
|
gs_color_format _color_format;
|
||||||
gs_zstencil_format zstencil_format;
|
gs_zstencil_format _zstencil_format;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~rendertarget();
|
~rendertarget();
|
||||||
|
|
|
@ -21,113 +21,113 @@
|
||||||
|
|
||||||
gs::sampler::sampler()
|
gs::sampler::sampler()
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
_dirty = true;
|
||||||
m_samplerInfo = {GS_FILTER_LINEAR, GS_ADDRESS_WRAP, GS_ADDRESS_WRAP, GS_ADDRESS_WRAP, 1, 0};
|
_sampler_info = {GS_FILTER_LINEAR, GS_ADDRESS_WRAP, GS_ADDRESS_WRAP, GS_ADDRESS_WRAP, 1, 0};
|
||||||
m_samplerState = nullptr;
|
_sampler_state = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::sampler::~sampler()
|
gs::sampler::~sampler()
|
||||||
{
|
{
|
||||||
if (m_samplerState)
|
if (_sampler_state)
|
||||||
gs_samplerstate_destroy(m_samplerState);
|
gs_samplerstate_destroy(_sampler_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs::sampler::set_filter(gs_sample_filter v)
|
void gs::sampler::set_filter(gs_sample_filter v)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
_dirty = true;
|
||||||
m_samplerInfo.filter = v;
|
_sampler_info.filter = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_sample_filter gs::sampler::get_filter()
|
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)
|
void gs::sampler::set_address_mode_u(gs_address_mode v)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
_dirty = true;
|
||||||
m_samplerInfo.address_u = v;
|
_sampler_info.address_u = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_address_mode gs::sampler::get_address_mode_u()
|
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)
|
void gs::sampler::set_address_mode_v(gs_address_mode v)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
_dirty = true;
|
||||||
m_samplerInfo.address_v = v;
|
_sampler_info.address_v = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_address_mode gs::sampler::get_address_mode_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)
|
void gs::sampler::set_address_mode_w(gs_address_mode v)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
_dirty = true;
|
||||||
m_samplerInfo.address_w = v;
|
_sampler_info.address_w = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_address_mode gs::sampler::get_address_mode_w()
|
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)
|
void gs::sampler::set_max_anisotropy(int v)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
_dirty = true;
|
||||||
m_samplerInfo.max_anisotropy = v;
|
_sampler_info.max_anisotropy = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gs::sampler::get_max_anisotropy()
|
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)
|
void gs::sampler::set_border_color(uint32_t v)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
_dirty = true;
|
||||||
m_samplerInfo.border_color = v;
|
_sampler_info.border_color = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs::sampler::set_border_color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
void gs::sampler::set_border_color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
_dirty = true;
|
||||||
m_samplerInfo.border_color = a << 24 | r << 16 | g << 8 | b;
|
_sampler_info.border_color = a << 24 | r << 16 | g << 8 | b;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gs::sampler::get_border_color()
|
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)
|
uint8_t gs::sampler::get_border_color(bool r, bool g, bool b, bool a)
|
||||||
{
|
{
|
||||||
if (a)
|
if (a)
|
||||||
return (m_samplerInfo.border_color >> 24) & 0xFF;
|
return (_sampler_info.border_color >> 24) & 0xFF;
|
||||||
if (r)
|
if (r)
|
||||||
return (m_samplerInfo.border_color >> 16) & 0xFF;
|
return (_sampler_info.border_color >> 16) & 0xFF;
|
||||||
if (g)
|
if (g)
|
||||||
return (m_samplerInfo.border_color >> 8) & 0xFF;
|
return (_sampler_info.border_color >> 8) & 0xFF;
|
||||||
if (b)
|
if (b)
|
||||||
return m_samplerInfo.border_color & 0xFF;
|
return _sampler_info.border_color & 0xFF;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_sampler_state* gs::sampler::refresh()
|
gs_sampler_state* gs::sampler::refresh()
|
||||||
{
|
{
|
||||||
gs_samplerstate_destroy(m_samplerState);
|
gs_samplerstate_destroy(_sampler_state);
|
||||||
m_samplerState = gs_samplerstate_create(&m_samplerInfo);
|
_sampler_state = gs_samplerstate_create(&_sampler_info);
|
||||||
m_dirty = false;
|
_dirty = false;
|
||||||
return m_samplerState;
|
return _sampler_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_sampler_state* gs::sampler::get_object()
|
gs_sampler_state* gs::sampler::get_object()
|
||||||
{
|
{
|
||||||
if (m_dirty)
|
if (_dirty)
|
||||||
return refresh();
|
return refresh();
|
||||||
return m_samplerState;
|
return _sampler_state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,8 @@ namespace gs {
|
||||||
gs_sampler_state* get_object();
|
gs_sampler_state* get_object();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_dirty;
|
bool _dirty;
|
||||||
gs_sampler_info m_samplerInfo;
|
gs_sampler_info _sampler_info;
|
||||||
gs_sampler_state* m_samplerState;
|
gs_sampler_state* _sampler_state;
|
||||||
};
|
};
|
||||||
} // namespace gs
|
} // namespace gs
|
||||||
|
|
|
@ -52,15 +52,15 @@ gs::texture::texture(uint32_t width, uint32_t height, gs_color_format format, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_texture = gs_texture_create(
|
_texture = gs_texture_create(
|
||||||
width, height, format, mip_levels, mip_data,
|
width, height, format, mip_levels, mip_data,
|
||||||
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
||||||
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
||||||
|
|
||||||
if (!m_texture)
|
if (!_texture)
|
||||||
throw std::runtime_error("Failed to create 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,
|
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();
|
auto gctx = gs::context();
|
||||||
m_texture = gs_voltexture_create(
|
_texture = gs_voltexture_create(
|
||||||
width, height, depth, format, mip_levels, mip_data,
|
width, height, depth, format, mip_levels, mip_data,
|
||||||
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
||||||
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
||||||
|
|
||||||
if (!m_texture)
|
if (!_texture)
|
||||||
throw std::runtime_error("Failed to create 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,
|
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();
|
auto gctx = gs::context();
|
||||||
m_texture = gs_cubetexture_create(
|
_texture = gs_cubetexture_create(
|
||||||
size, format, mip_levels, mip_data,
|
size, format, mip_levels, mip_data,
|
||||||
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
||||||
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
||||||
|
|
||||||
if (!m_texture)
|
if (!_texture)
|
||||||
throw std::runtime_error("Failed to create texture.");
|
throw std::runtime_error("Failed to create texture.");
|
||||||
|
|
||||||
m_textureType = type::Cube;
|
_type = type::Cube;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::texture::texture(std::string file)
|
gs::texture::texture(std::string file)
|
||||||
|
@ -128,75 +128,75 @@ gs::texture::texture(std::string file)
|
||||||
throw std::ios_base::failure(file);
|
throw std::ios_base::failure(file);
|
||||||
|
|
||||||
auto gctx = gs::context();
|
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.");
|
throw std::runtime_error("Failed to load texture.");
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::texture::~texture()
|
gs::texture::~texture()
|
||||||
{
|
{
|
||||||
if (m_isOwner && m_texture) {
|
if (_is_owner && _texture) {
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
switch (gs_get_texture_type(m_texture)) {
|
switch (gs_get_texture_type(_texture)) {
|
||||||
case GS_TEXTURE_2D:
|
case GS_TEXTURE_2D:
|
||||||
gs_texture_destroy(m_texture);
|
gs_texture_destroy(_texture);
|
||||||
break;
|
break;
|
||||||
case GS_TEXTURE_3D:
|
case GS_TEXTURE_3D:
|
||||||
gs_voltexture_destroy(m_texture);
|
gs_voltexture_destroy(_texture);
|
||||||
break;
|
break;
|
||||||
case GS_TEXTURE_CUBE:
|
case GS_TEXTURE_CUBE:
|
||||||
gs_cubetexture_destroy(m_texture);
|
gs_cubetexture_destroy(_texture);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_texture = nullptr;
|
_texture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs::texture::load(int unit)
|
void gs::texture::load(int unit)
|
||||||
{
|
{
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
gs_load_texture(m_texture, unit);
|
gs_load_texture(_texture, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_texture_t* gs::texture::get_object()
|
gs_texture_t* gs::texture::get_object()
|
||||||
{
|
{
|
||||||
return m_texture;
|
return _texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gs::texture::get_width()
|
uint32_t gs::texture::get_width()
|
||||||
{
|
{
|
||||||
switch (m_textureType) {
|
switch (_type) {
|
||||||
case type::Normal:
|
case type::Normal:
|
||||||
return gs_texture_get_width(m_texture);
|
return gs_texture_get_width(_texture);
|
||||||
case type::Volume:
|
case type::Volume:
|
||||||
return gs_voltexture_get_width(m_texture);
|
return gs_voltexture_get_width(_texture);
|
||||||
case type::Cube:
|
case type::Cube:
|
||||||
return gs_cubetexture_get_size(m_texture);
|
return gs_cubetexture_get_size(_texture);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gs::texture::get_height()
|
uint32_t gs::texture::get_height()
|
||||||
{
|
{
|
||||||
switch (m_textureType) {
|
switch (_type) {
|
||||||
case type::Normal:
|
case type::Normal:
|
||||||
return gs_texture_get_height(m_texture);
|
return gs_texture_get_height(_texture);
|
||||||
case type::Volume:
|
case type::Volume:
|
||||||
return gs_voltexture_get_height(m_texture);
|
return gs_voltexture_get_height(_texture);
|
||||||
case type::Cube:
|
case type::Cube:
|
||||||
return gs_cubetexture_get_size(m_texture);
|
return gs_cubetexture_get_size(_texture);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gs::texture::get_depth()
|
uint32_t gs::texture::get_depth()
|
||||||
{
|
{
|
||||||
switch (m_textureType) {
|
switch (_type) {
|
||||||
case type::Normal:
|
case type::Normal:
|
||||||
return 1;
|
return 1;
|
||||||
case type::Volume:
|
case type::Volume:
|
||||||
return gs_voltexture_get_depth(m_texture);
|
return gs_voltexture_get_depth(_texture);
|
||||||
case type::Cube:
|
case type::Cube:
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
@ -205,10 +205,10 @@ uint32_t gs::texture::get_depth()
|
||||||
|
|
||||||
gs::texture::type gs::texture::get_type()
|
gs::texture::type gs::texture::get_type()
|
||||||
{
|
{
|
||||||
return m_textureType;
|
return _type;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_color_format gs::texture::get_color_format()
|
gs_color_format gs::texture::get_color_format()
|
||||||
{
|
{
|
||||||
return gs_texture_get_color_format(m_texture);
|
return gs_texture_get_color_format(_texture);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,9 +44,9 @@ namespace gs {
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
gs_texture_t* m_texture;
|
gs_texture_t* _texture;
|
||||||
bool m_isOwner = true;
|
bool _is_owner = true;
|
||||||
type m_textureType = type::Normal;
|
type _type = type::Normal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~texture();
|
~texture();
|
||||||
|
@ -105,7 +105,7 @@ namespace gs {
|
||||||
/*!
|
/*!
|
||||||
* \brief Create a texture from an existing gs_texture_t object.
|
* \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);
|
void load(int unit);
|
||||||
|
|
||||||
|
@ -123,4 +123,4 @@ namespace gs {
|
||||||
};
|
};
|
||||||
} // namespace gs
|
} // namespace gs
|
||||||
|
|
||||||
ENABLE_BITMASK_OPERATORS(gs::texture::flags)
|
P_ENABLE_BITMASK_OPERATORS(gs::texture::flags)
|
||||||
|
|
|
@ -21,39 +21,39 @@
|
||||||
#include "util-memory.hpp"
|
#include "util-memory.hpp"
|
||||||
|
|
||||||
gs::vertex::vertex()
|
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;
|
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);
|
offset += sizeof(vec3);
|
||||||
|
|
||||||
normal = reinterpret_cast<vec3*>(reinterpret_cast<char*>(store) + offset);
|
normal = reinterpret_cast<vec3*>(reinterpret_cast<char*>(_store) + offset);
|
||||||
offset += sizeof(vec3);
|
offset += sizeof(vec3);
|
||||||
|
|
||||||
tangent = reinterpret_cast<vec3*>(reinterpret_cast<char*>(store) + offset);
|
tangent = reinterpret_cast<vec3*>(reinterpret_cast<char*>(_store) + offset);
|
||||||
offset += sizeof(vec3);
|
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);
|
offset += sizeof(uint32_t);
|
||||||
|
|
||||||
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
|
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);
|
offset += sizeof(vec4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::vertex::~vertex()
|
gs::vertex::~vertex()
|
||||||
{
|
{
|
||||||
if (hasStore) {
|
if (_has_store) {
|
||||||
util::free_aligned(store);
|
util::free_aligned(_store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::vertex::vertex(vec3* p, vec3* n, vec3* t, uint32_t* col, vec4* uvs[MAXIMUM_UVW_LAYERS])
|
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) {
|
if (uvs != nullptr) {
|
||||||
for (size_t idx = 0; idx < MAXIMUM_UVW_LAYERS; idx++) {
|
for (size_t idx = 0; idx < MAXIMUM_UVW_LAYERS; idx++) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace gs {
|
||||||
~vertex();
|
~vertex();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool hasStore;
|
bool _has_store;
|
||||||
void* store;
|
void* _store;
|
||||||
};
|
};
|
||||||
} // namespace gs
|
} // namespace gs
|
||||||
|
|
|
@ -34,43 +34,43 @@
|
||||||
|
|
||||||
gs::vertex_buffer::~vertex_buffer()
|
gs::vertex_buffer::~vertex_buffer()
|
||||||
{
|
{
|
||||||
if (m_positions) {
|
if (_positions) {
|
||||||
util::free_aligned(m_positions);
|
util::free_aligned(_positions);
|
||||||
m_positions = nullptr;
|
_positions = nullptr;
|
||||||
}
|
}
|
||||||
if (m_normals) {
|
if (_normals) {
|
||||||
util::free_aligned(m_normals);
|
util::free_aligned(_normals);
|
||||||
m_normals = nullptr;
|
_normals = nullptr;
|
||||||
}
|
}
|
||||||
if (m_tangents) {
|
if (_tangents) {
|
||||||
util::free_aligned(m_tangents);
|
util::free_aligned(_tangents);
|
||||||
m_tangents = nullptr;
|
_tangents = nullptr;
|
||||||
}
|
}
|
||||||
if (m_colors) {
|
if (_colors) {
|
||||||
util::free_aligned(m_colors);
|
util::free_aligned(_colors);
|
||||||
m_colors = nullptr;
|
_colors = nullptr;
|
||||||
}
|
}
|
||||||
for (size_t n = 0; n < m_layers; n++) {
|
for (size_t n = 0; n < _layers; n++) {
|
||||||
if (m_uvs[n]) {
|
if (_uvs[n]) {
|
||||||
util::free_aligned(m_uvs[n]);
|
util::free_aligned(_uvs[n]);
|
||||||
m_uvs[n] = nullptr;
|
_uvs[n] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_layerdata) {
|
if (_layer_data) {
|
||||||
util::free_aligned(m_layerdata);
|
util::free_aligned(_layer_data);
|
||||||
m_layerdata = nullptr;
|
_layer_data = nullptr;
|
||||||
}
|
}
|
||||||
if (m_vertexbufferdata) {
|
if (_data) {
|
||||||
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
memset(_data, 0, sizeof(gs_vb_data));
|
||||||
if (!m_vertexbuffer) {
|
if (!_buffer) {
|
||||||
gs_vbdata_destroy(m_vertexbufferdata);
|
gs_vbdata_destroy(_data);
|
||||||
m_vertexbufferdata = nullptr;
|
_data = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_vertexbuffer) {
|
if (_buffer) {
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
gs_vertexbuffer_destroy(m_vertexbuffer);
|
gs_vertexbuffer_destroy(_buffer);
|
||||||
m_vertexbuffer = nullptr;
|
_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) : vertex_buffer(vertices, MAXIMUM_UVW_LAYERS) {}
|
||||||
|
|
||||||
gs::vertex_buffer::vertex_buffer(uint32_t vertices, uint8_t uvlayers)
|
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),
|
: _size(vertices), _capacity(vertices), _layers(uvlayers), _positions(nullptr), _normals(nullptr),
|
||||||
m_tangents(nullptr), m_colors(nullptr), m_vertexbufferdata(nullptr), m_vertexbuffer(nullptr), m_layerdata(nullptr)
|
_tangents(nullptr), _colors(nullptr), _data(nullptr), _buffer(nullptr), _layer_data(nullptr)
|
||||||
{
|
{
|
||||||
if (vertices > MAXIMUM_VERTICES) {
|
if (vertices > MAXIMUM_VERTICES) {
|
||||||
throw std::out_of_range("vertices out of range");
|
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.
|
// Allocate memory for data.
|
||||||
m_vertexbufferdata = gs_vbdata_create();
|
_data = gs_vbdata_create();
|
||||||
m_vertexbufferdata->num = m_capacity;
|
_data->num = _capacity;
|
||||||
m_vertexbufferdata->points = m_positions = (vec3*)util::malloc_aligned(16, sizeof(vec3) * m_capacity);
|
_data->points = _positions = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
|
||||||
m_vertexbufferdata->normals = m_normals = (vec3*)util::malloc_aligned(16, sizeof(vec3) * m_capacity);
|
_data->normals = _normals = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
|
||||||
m_vertexbufferdata->tangents = m_tangents = (vec3*)util::malloc_aligned(16, sizeof(vec3) * m_capacity);
|
_data->tangents = _tangents = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
|
||||||
m_vertexbufferdata->colors = m_colors = (uint32_t*)util::malloc_aligned(16, sizeof(uint32_t) * m_capacity);
|
_data->colors = _colors = (uint32_t*)util::malloc_aligned(16, sizeof(uint32_t) * _capacity);
|
||||||
|
|
||||||
// cppcheck-suppress memsetClassFloat
|
// cppcheck-suppress memsetClassFloat
|
||||||
memset(m_positions, 0, sizeof(vec3) * m_capacity);
|
memset(_positions, 0, sizeof(vec3) * _capacity);
|
||||||
// cppcheck-suppress memsetClassFloat
|
// cppcheck-suppress memsetClassFloat
|
||||||
memset(m_normals, 0, sizeof(vec3) * m_capacity);
|
memset(_normals, 0, sizeof(vec3) * _capacity);
|
||||||
// cppcheck-suppress memsetClassFloat
|
// cppcheck-suppress memsetClassFloat
|
||||||
memset(m_tangents, 0, sizeof(vec3) * m_capacity);
|
memset(_tangents, 0, sizeof(vec3) * _capacity);
|
||||||
memset(m_colors, 0, sizeof(uint32_t) * m_capacity);
|
memset(_colors, 0, sizeof(uint32_t) * _capacity);
|
||||||
|
|
||||||
m_vertexbufferdata->num_tex = m_layers;
|
_data->num_tex = _layers;
|
||||||
if (m_layers > 0) {
|
if (_layers > 0) {
|
||||||
m_vertexbufferdata->tvarray = m_layerdata =
|
_data->tvarray = _layer_data =
|
||||||
(gs_tvertarray*)util::malloc_aligned(16, sizeof(gs_tvertarray) * m_layers);
|
(gs_tvertarray*)util::malloc_aligned(16, sizeof(gs_tvertarray) * _layers);
|
||||||
for (size_t n = 0; n < m_layers; n++) {
|
for (size_t n = 0; n < _layers; n++) {
|
||||||
m_layerdata[n].array = m_uvs[n] = (vec4*)util::malloc_aligned(16, sizeof(vec4) * m_capacity);
|
_layer_data[n].array = _uvs[n] = (vec4*)util::malloc_aligned(16, sizeof(vec4) * _capacity);
|
||||||
m_layerdata[n].width = 4;
|
_layer_data[n].width = 4;
|
||||||
memset(m_uvs[n], 0, sizeof(vec4) * m_capacity);
|
memset(_uvs[n], 0, sizeof(vec4) * _capacity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_vertexbufferdata->tvarray = nullptr;
|
_data->tvarray = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate GPU
|
// Allocate GPU
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_vertexbuffer = gs_vertexbuffer_create(m_vertexbufferdata, GS_DYNAMIC);
|
_buffer = gs_vertexbuffer_create(_data, GS_DYNAMIC);
|
||||||
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
memset(_data, 0, sizeof(gs_vb_data));
|
||||||
m_vertexbufferdata->num = m_capacity;
|
_data->num = _capacity;
|
||||||
m_vertexbufferdata->num_tex = m_layers;
|
_data->num_tex = _layers;
|
||||||
if (!m_vertexbuffer) {
|
if (!_buffer) {
|
||||||
throw std::runtime_error("Failed to create vertex 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);
|
this->set_uv_layers((uint32_t)vbd->num_tex);
|
||||||
|
|
||||||
if (vbd->points != nullptr)
|
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)
|
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)
|
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)
|
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) {
|
if (vbd->tvarray != nullptr) {
|
||||||
for (size_t n = 0; n < vbd->num_tex; n++) {
|
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].array != nullptr && vbd->tvarray[n].width <= 4 && vbd->tvarray[n].width > 0) {
|
||||||
if (vbd->tvarray[n].width == 4) {
|
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 {
|
} 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);
|
float* mem = reinterpret_cast<float*>(vbd->tvarray[n].array) + (idx * vbd->tvarray[n].width);
|
||||||
// cppcheck-suppress memsetClassFloat
|
// cppcheck-suppress memsetClassFloat
|
||||||
memset(&m_uvs[n][idx], 0, sizeof(vec4));
|
memset(&_uvs[n][idx], 0, sizeof(vec4));
|
||||||
memcpy(&m_uvs[n][idx], mem, vbd->tvarray[n].width);
|
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
|
// 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
|
// Copy Constructor
|
||||||
memcpy(m_positions, other.m_positions, m_capacity * sizeof(vec3));
|
memcpy(_positions, other._positions, _capacity * sizeof(vec3));
|
||||||
memcpy(m_normals, other.m_normals, m_capacity * sizeof(vec3));
|
memcpy(_normals, other._normals, _capacity * sizeof(vec3));
|
||||||
memcpy(m_tangents, other.m_tangents, m_capacity * sizeof(vec3));
|
memcpy(_tangents, other._tangents, _capacity * sizeof(vec3));
|
||||||
memcpy(m_colors, other.m_colors, m_capacity * sizeof(vec3));
|
memcpy(_colors, other._colors, _capacity * sizeof(vec3));
|
||||||
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
|
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)
|
gs::vertex_buffer::vertex_buffer(vertex_buffer const&& other)
|
||||||
{
|
{
|
||||||
// Move Constructor
|
// Move Constructor
|
||||||
m_capacity = other.m_capacity;
|
_capacity = other._capacity;
|
||||||
m_size = other.m_size;
|
_size = other._size;
|
||||||
m_layers = other.m_layers;
|
_layers = other._layers;
|
||||||
m_positions = other.m_positions;
|
_positions = other._positions;
|
||||||
m_normals = other.m_normals;
|
_normals = other._normals;
|
||||||
m_tangents = other.m_tangents;
|
_tangents = other._tangents;
|
||||||
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
|
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;
|
_data = other._data;
|
||||||
m_vertexbuffer = other.m_vertexbuffer;
|
_buffer = other._buffer;
|
||||||
m_layerdata = other.m_layerdata;
|
_layer_data = other._layer_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs::vertex_buffer::operator=(vertex_buffer const&& other)
|
void gs::vertex_buffer::operator=(vertex_buffer const&& other)
|
||||||
{
|
{
|
||||||
// Move Assignment
|
// Move Assignment
|
||||||
/// First self-destruct (semi-destruct itself).
|
/// First self-destruct (semi-destruct itself).
|
||||||
if (m_positions) {
|
if (_positions) {
|
||||||
util::free_aligned(m_positions);
|
util::free_aligned(_positions);
|
||||||
m_positions = nullptr;
|
_positions = nullptr;
|
||||||
}
|
}
|
||||||
if (m_normals) {
|
if (_normals) {
|
||||||
util::free_aligned(m_normals);
|
util::free_aligned(_normals);
|
||||||
m_normals = nullptr;
|
_normals = nullptr;
|
||||||
}
|
}
|
||||||
if (m_tangents) {
|
if (_tangents) {
|
||||||
util::free_aligned(m_tangents);
|
util::free_aligned(_tangents);
|
||||||
m_tangents = nullptr;
|
_tangents = nullptr;
|
||||||
}
|
}
|
||||||
if (m_colors) {
|
if (_colors) {
|
||||||
util::free_aligned(m_colors);
|
util::free_aligned(_colors);
|
||||||
m_colors = nullptr;
|
_colors = nullptr;
|
||||||
}
|
}
|
||||||
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
|
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
|
||||||
if (m_uvs[n]) {
|
if (_uvs[n]) {
|
||||||
util::free_aligned(m_uvs[n]);
|
util::free_aligned(_uvs[n]);
|
||||||
m_uvs[n] = nullptr;
|
_uvs[n] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_layerdata) {
|
if (_layer_data) {
|
||||||
util::free_aligned(m_layerdata);
|
util::free_aligned(_layer_data);
|
||||||
m_layerdata = nullptr;
|
_layer_data = nullptr;
|
||||||
}
|
}
|
||||||
if (m_vertexbufferdata) {
|
if (_data) {
|
||||||
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
memset(_data, 0, sizeof(gs_vb_data));
|
||||||
if (!m_vertexbuffer) {
|
if (!_buffer) {
|
||||||
gs_vbdata_destroy(m_vertexbufferdata);
|
gs_vbdata_destroy(_data);
|
||||||
m_vertexbufferdata = nullptr;
|
_data = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_vertexbuffer) {
|
if (_buffer) {
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
gs_vertexbuffer_destroy(m_vertexbuffer);
|
gs_vertexbuffer_destroy(_buffer);
|
||||||
m_vertexbuffer = nullptr;
|
_buffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Then assign new values.
|
/// Then assign new values.
|
||||||
m_capacity = other.m_capacity;
|
_capacity = other._capacity;
|
||||||
m_size = other.m_size;
|
_size = other._size;
|
||||||
m_layers = other.m_layers;
|
_layers = other._layers;
|
||||||
m_positions = other.m_positions;
|
_positions = other._positions;
|
||||||
m_normals = other.m_normals;
|
_normals = other._normals;
|
||||||
m_tangents = other.m_tangents;
|
_tangents = other._tangents;
|
||||||
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
|
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;
|
_data = other._data;
|
||||||
m_vertexbuffer = other.m_vertexbuffer;
|
_buffer = other._buffer;
|
||||||
m_layerdata = other.m_layerdata;
|
_layer_data = other._layer_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs::vertex_buffer::resize(uint32_t new_size)
|
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");
|
throw std::out_of_range("new_size out of range");
|
||||||
}
|
}
|
||||||
m_size = new_size;
|
_size = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gs::vertex_buffer::size()
|
uint32_t gs::vertex_buffer::size()
|
||||||
{
|
{
|
||||||
return m_size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gs::vertex_buffer::empty()
|
bool gs::vertex_buffer::empty()
|
||||||
{
|
{
|
||||||
return m_size == 0;
|
return _size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gs::vertex gs::vertex_buffer::at(uint32_t idx)
|
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");
|
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);
|
gs::vertex vtx(&_positions[idx], &_normals[idx], &_tangents[idx], &_colors[idx], nullptr);
|
||||||
for (size_t n = 0; n < m_layers; n++) {
|
for (size_t n = 0; n < _layers; n++) {
|
||||||
vtx.uv[n] = &m_uvs[n][idx];
|
vtx.uv[n] = &_uvs[n][idx];
|
||||||
}
|
}
|
||||||
return vtx;
|
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)
|
void gs::vertex_buffer::set_uv_layers(uint32_t layers)
|
||||||
{
|
{
|
||||||
m_layers = layers;
|
_layers = layers;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gs::vertex_buffer::get_uv_layers()
|
uint32_t gs::vertex_buffer::get_uv_layers()
|
||||||
{
|
{
|
||||||
return m_layers;
|
return _layers;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3* gs::vertex_buffer::get_positions()
|
vec3* gs::vertex_buffer::get_positions()
|
||||||
{
|
{
|
||||||
return m_positions;
|
return _positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3* gs::vertex_buffer::get_normals()
|
vec3* gs::vertex_buffer::get_normals()
|
||||||
{
|
{
|
||||||
return m_normals;
|
return _normals;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3* gs::vertex_buffer::get_tangents()
|
vec3* gs::vertex_buffer::get_tangents()
|
||||||
{
|
{
|
||||||
return m_tangents;
|
return _tangents;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t* gs::vertex_buffer::get_colors()
|
uint32_t* gs::vertex_buffer::get_colors()
|
||||||
{
|
{
|
||||||
return m_colors;
|
return _colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4* gs::vertex_buffer::get_uv_layer(size_t idx)
|
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");
|
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)
|
gs_vertbuffer_t* gs::vertex_buffer::update(bool refreshGPU)
|
||||||
{
|
{
|
||||||
if (!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");
|
throw std::out_of_range("size is larger than capacity");
|
||||||
|
|
||||||
// Update VertexBuffer data.
|
// Update VertexBuffer data.
|
||||||
auto gctx = gs::context();
|
auto gctx = gs::context();
|
||||||
m_vertexbufferdata = gs_vertexbuffer_get_data(m_vertexbuffer);
|
_data = gs_vertexbuffer_get_data(_buffer);
|
||||||
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
memset(_data, 0, sizeof(gs_vb_data));
|
||||||
m_vertexbufferdata->num = m_capacity;
|
_data->num = _capacity;
|
||||||
m_vertexbufferdata->points = m_positions;
|
_data->points = _positions;
|
||||||
m_vertexbufferdata->normals = m_normals;
|
_data->normals = _normals;
|
||||||
m_vertexbufferdata->tangents = m_tangents;
|
_data->tangents = _tangents;
|
||||||
m_vertexbufferdata->colors = m_colors;
|
_data->colors = _colors;
|
||||||
m_vertexbufferdata->num_tex = m_layers;
|
_data->num_tex = _layers;
|
||||||
m_vertexbufferdata->tvarray = m_layerdata;
|
_data->tvarray = _layer_data;
|
||||||
for (size_t n = 0; n < m_layers; n++) {
|
for (size_t n = 0; n < _layers; n++) {
|
||||||
m_layerdata[n].array = m_uvs[n];
|
_layer_data[n].array = _uvs[n];
|
||||||
m_layerdata[n].width = 4;
|
_layer_data[n].width = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update GPU
|
// 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.
|
// WORKAROUND: OBS Studio 20.x and below incorrectly deletes data that it doesn't own.
|
||||||
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
memset(_data, 0, sizeof(gs_vb_data));
|
||||||
m_vertexbufferdata->num = m_capacity;
|
_data->num = _capacity;
|
||||||
m_vertexbufferdata->num_tex = m_layers;
|
_data->num_tex = _layers;
|
||||||
for (uint32_t n = 0; n < m_layers; n++) {
|
for (uint32_t n = 0; n < _layers; n++) {
|
||||||
m_layerdata[n].width = 4;
|
_layer_data[n].width = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_vertexbuffer;
|
return _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_vertbuffer_t* gs::vertex_buffer::update()
|
gs_vertbuffer_t* gs::vertex_buffer::update()
|
||||||
|
|
|
@ -36,6 +36,22 @@
|
||||||
|
|
||||||
namespace gs {
|
namespace gs {
|
||||||
class vertex_buffer {
|
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:
|
public:
|
||||||
virtual ~vertex_buffer();
|
virtual ~vertex_buffer();
|
||||||
|
|
||||||
|
@ -160,22 +176,5 @@ namespace gs {
|
||||||
gs_vertbuffer_t* update();
|
gs_vertbuffer_t* update();
|
||||||
|
|
||||||
gs_vertbuffer_t* update(bool refreshGPU);
|
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
|
} // namespace gs
|
||||||
|
|
|
@ -43,7 +43,7 @@ void obs::source_tracker::source_create_handler(void* ptr, calldata_t* data)
|
||||||
return;
|
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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto found = self->source_map.find(std::string(name));
|
auto found = self->_source_map.find(std::string(name));
|
||||||
if (found == self->source_map.end()) {
|
if (found == self->_source_map.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_weak_source_release(found->second);
|
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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto found = self->source_map.find(std::string(prev_name));
|
auto found = self->_source_map.find(std::string(prev_name));
|
||||||
if (found == self->source_map.end()) {
|
if (found == self->_source_map.end()) {
|
||||||
// Untracked source, insert.
|
// Untracked source, insert.
|
||||||
obs_weak_source_t* weak = obs_source_get_weak_source(target);
|
obs_weak_source_t* weak = obs_source_get_weak_source(target);
|
||||||
if (!weak) {
|
if (!weak) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self->source_map.insert({new_name, weak});
|
self->_source_map.insert({new_name, weak});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert at new key, remove old pair.
|
// Insert at new key, remove old pair.
|
||||||
self->source_map.insert({new_name, found->second});
|
self->_source_map.insert({new_name, found->second});
|
||||||
self->source_map.erase(found);
|
self->_source_map.erase(found);
|
||||||
}
|
}
|
||||||
|
|
||||||
void obs::source_tracker::initialize()
|
void obs::source_tracker::initialize()
|
||||||
|
@ -136,17 +136,17 @@ obs::source_tracker::~source_tracker()
|
||||||
signal_handler_disconnect(osi, "source_rename", &source_rename_handler, this);
|
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);
|
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)
|
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.
|
// Need func-local copy, otherwise we risk corruption if a new source is created or destroyed.
|
||||||
auto source_map_copy = this->source_map;
|
auto source_map_copy = this->_source_map;
|
||||||
for (auto kv : this->source_map) {
|
for (auto kv : this->_source_map) {
|
||||||
obs_source_t* source = obs_weak_source_get_source(kv.second);
|
obs_source_t* source = obs_weak_source_get_source(kv.second);
|
||||||
if (!source) {
|
if (!source) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
namespace obs {
|
namespace obs {
|
||||||
class source_tracker {
|
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_create_handler(void* ptr, calldata_t* data);
|
||||||
static void source_destroy_handler(void* ptr, calldata_t* data);
|
static void source_destroy_handler(void* ptr, calldata_t* data);
|
||||||
|
|
|
@ -28,8 +28,8 @@ void obs::source::handle_destroy(void* p, calldata_t* calldata)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->self == source) {
|
if (self->_self == source) {
|
||||||
self->self = nullptr;
|
self->_self = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->events.destroy) {
|
if (self->events.destroy) {
|
||||||
|
@ -397,10 +397,10 @@ obs::source::~source()
|
||||||
auto_signal_d(transition_stop);
|
auto_signal_d(transition_stop);
|
||||||
#undef auto_signal_d
|
#undef auto_signal_d
|
||||||
|
|
||||||
if (this->track_ownership && this->self) {
|
if (this->_track_ownership && this->_self) {
|
||||||
obs_source_release(this->self);
|
obs_source_release(this->_self);
|
||||||
}
|
}
|
||||||
this->self = nullptr;
|
this->_self = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs::source::source()
|
obs::source::source()
|
||||||
|
@ -411,17 +411,17 @@ obs::source::source()
|
||||||
#define auto_signal_c(SIGNAL) \
|
#define auto_signal_c(SIGNAL) \
|
||||||
{ \
|
{ \
|
||||||
this->events.SIGNAL.set_listen_callback([this] { \
|
this->events.SIGNAL.set_listen_callback([this] { \
|
||||||
if (!this->self) \
|
if (!this->_self) \
|
||||||
return; \
|
return; \
|
||||||
auto sh = obs_source_get_signal_handler(this->self); \
|
auto sh = obs_source_get_signal_handler(this->_self); \
|
||||||
if (sh) { \
|
if (sh) { \
|
||||||
signal_handler_connect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); \
|
signal_handler_connect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); \
|
||||||
} \
|
} \
|
||||||
}); \
|
}); \
|
||||||
this->events.SIGNAL.set_silence_callback([this] { \
|
this->events.SIGNAL.set_silence_callback([this] { \
|
||||||
if (!this->self) \
|
if (!this->_self) \
|
||||||
return; \
|
return; \
|
||||||
auto sh = obs_source_get_signal_handler(this->self); \
|
auto sh = obs_source_get_signal_handler(this->_self); \
|
||||||
if (sh) { \
|
if (sh) { \
|
||||||
signal_handler_disconnect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); \
|
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.
|
// things do. So instead we'll have to manually deal with it for now.
|
||||||
{
|
{
|
||||||
this->events.audio_data.set_listen_callback([this] {
|
this->events.audio_data.set_listen_callback([this] {
|
||||||
if (!this->self)
|
if (!this->_self)
|
||||||
return;
|
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] {
|
this->events.audio_data.set_silence_callback([this] {
|
||||||
if (!this->self)
|
if (!this->_self)
|
||||||
return;
|
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()
|
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());
|
this->_self = obs_get_source_by_name(name.c_str());
|
||||||
if (!this->self) {
|
if (!this->_self) {
|
||||||
throw std::runtime_error("source with name not found");
|
throw std::runtime_error("source with name not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->track_ownership = ptrack_ownership;
|
this->_track_ownership = ptrack_ownership;
|
||||||
if (!add_reference) {
|
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()
|
obs::source::source(obs_source_t* source, bool ptrack_ownership, bool add_reference) : ::obs::source::source()
|
||||||
{
|
{
|
||||||
this->self = source;
|
this->_self = source;
|
||||||
if (!this->self) {
|
if (!this->_self) {
|
||||||
throw std::invalid_argument("source must not be null");
|
throw std::invalid_argument("source must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->track_ownership = ptrack_ownership;
|
this->_track_ownership = ptrack_ownership;
|
||||||
if (add_reference) {
|
if (add_reference) {
|
||||||
obs_source_addref(this->self);
|
obs_source_addref(this->_self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs::source::source(source const& other)
|
obs::source::source(source const& other)
|
||||||
{
|
{
|
||||||
this->self = other.self;
|
this->_self = other._self;
|
||||||
this->track_ownership = other.track_ownership;
|
this->_track_ownership = other._track_ownership;
|
||||||
|
|
||||||
if (this->track_ownership) {
|
if (this->_track_ownership) {
|
||||||
obs_source_addref(this->self);
|
obs_source_addref(this->_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef auto_signal_c
|
#ifdef auto_signal_c
|
||||||
|
@ -529,15 +529,15 @@ obs::source& obs::source::operator=(source const& other)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release previous source.
|
// Release previous source.
|
||||||
if (this->self && this->track_ownership) {
|
if (this->_self && this->_track_ownership) {
|
||||||
obs_source_release(this->self);
|
obs_source_release(this->_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->self = other.self;
|
this->_self = other._self;
|
||||||
this->track_ownership = other.track_ownership;
|
this->_track_ownership = other._track_ownership;
|
||||||
|
|
||||||
if (this->track_ownership) {
|
if (this->_track_ownership) {
|
||||||
obs_source_addref(this->self);
|
obs_source_addref(this->_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef auto_signal_c
|
#ifdef auto_signal_c
|
||||||
|
@ -576,11 +576,11 @@ obs::source& obs::source::operator=(source const& other)
|
||||||
return *this;
|
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
|
// Clean out other source
|
||||||
other.self = nullptr;
|
other._self = nullptr;
|
||||||
other.track_ownership = false;
|
other._track_ownership = false;
|
||||||
|
|
||||||
#ifdef auto_signal_c
|
#ifdef auto_signal_c
|
||||||
#undef auto_signal_c
|
#undef auto_signal_c
|
||||||
|
@ -623,14 +623,14 @@ obs::source& obs::source::operator=(source&& other)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release previous source.
|
// Release previous source.
|
||||||
if (this->self && this->track_ownership) {
|
if (this->_self && this->_track_ownership) {
|
||||||
obs_source_release(this->self);
|
obs_source_release(this->_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->self = std::move(other.self);
|
this->_self = std::move(other._self);
|
||||||
this->track_ownership = std::move(other.track_ownership);
|
this->_track_ownership = std::move(other._track_ownership);
|
||||||
other.self = nullptr;
|
other._self = nullptr;
|
||||||
other.track_ownership = false;
|
other._track_ownership = false;
|
||||||
|
|
||||||
#ifdef auto_signal_c
|
#ifdef auto_signal_c
|
||||||
#undef auto_signal_c
|
#undef auto_signal_c
|
||||||
|
@ -670,47 +670,47 @@ obs::source& obs::source::operator=(source&& other)
|
||||||
|
|
||||||
obs_source_type obs::source::type()
|
obs_source_type obs::source::type()
|
||||||
{
|
{
|
||||||
if (!self) {
|
if (!_self) {
|
||||||
return (obs_source_type)-1;
|
return (obs_source_type)-1;
|
||||||
}
|
}
|
||||||
return obs_source_get_type(self);
|
return obs_source_get_type(_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* obs::source::type_data()
|
void* obs::source::type_data()
|
||||||
{
|
{
|
||||||
if (!self) {
|
if (!_self) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return obs_source_get_type_data(self);
|
return obs_source_get_type_data(_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t obs::source::width()
|
uint32_t obs::source::width()
|
||||||
{
|
{
|
||||||
if (!self) {
|
if (!_self) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return obs_source_get_width(self);
|
return obs_source_get_width(_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t obs::source::height()
|
uint32_t obs::source::height()
|
||||||
{
|
{
|
||||||
if (!self) {
|
if (!_self) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return obs_source_get_height(self);
|
return obs_source_get_height(_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool obs::source::destroyed()
|
bool obs::source::destroyed()
|
||||||
{
|
{
|
||||||
return self == nullptr;
|
return _self == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void obs::source::clear()
|
void obs::source::clear()
|
||||||
{
|
{
|
||||||
self = nullptr;
|
_self = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_t* obs::source::get()
|
obs_source_t* obs::source::get()
|
||||||
{
|
{
|
||||||
return self;
|
return _self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@
|
||||||
|
|
||||||
namespace obs {
|
namespace obs {
|
||||||
class source {
|
class source {
|
||||||
obs_source_t* self;
|
obs_source_t* _self;
|
||||||
bool track_ownership = false;
|
bool _track_ownership = false;
|
||||||
|
|
||||||
static void handle_destroy(void* p, calldata_t* calldata);
|
static void handle_destroy(void* p, calldata_t* calldata);
|
||||||
static void handle_remove(void* p, calldata_t* calldata);
|
static void handle_remove(void* p, calldata_t* calldata);
|
||||||
|
|
|
@ -20,15 +20,15 @@
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "obs/obs-source-tracker.hpp"
|
#include "obs/obs-source-tracker.hpp"
|
||||||
|
|
||||||
std::list<std::function<void()>> initializerFunctions;
|
std::list<std::function<void()>> initializer_functions;
|
||||||
std::list<std::function<void()>> finalizerFunctions;
|
std::list<std::function<void()>> finalizer_functions;
|
||||||
|
|
||||||
MODULE_EXPORT bool obs_module_load(void)
|
MODULE_EXPORT bool obs_module_load(void)
|
||||||
{
|
{
|
||||||
P_LOG_INFO("Loading Version %u.%u.%u (Build %u)", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR,
|
P_LOG_INFO("Loading Version %u.%u.%u (Build %u)", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR,
|
||||||
PROJECT_VERSION_PATCH, PROJECT_VERSION_TWEAK);
|
PROJECT_VERSION_PATCH, PROJECT_VERSION_TWEAK);
|
||||||
obs::source_tracker::initialize();
|
obs::source_tracker::initialize();
|
||||||
for (auto func : initializerFunctions) {
|
for (auto func : initializer_functions) {
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
return true;
|
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,
|
P_LOG_INFO("Unloading Version %u.%u.%u (Build %u)", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR,
|
||||||
PROJECT_VERSION_PATCH, PROJECT_VERSION_TWEAK);
|
PROJECT_VERSION_PATCH, PROJECT_VERSION_TWEAK);
|
||||||
for (auto func : finalizerFunctions) {
|
for (auto func : finalizer_functions) {
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
obs::source_tracker::finalize();
|
obs::source_tracker::finalize();
|
||||||
|
|
|
@ -44,5 +44,5 @@
|
||||||
#define P_LOG_DEBUG(...) P_LOG(LOG_DEBUG, __VA_ARGS__)
|
#define P_LOG_DEBUG(...) P_LOG(LOG_DEBUG, __VA_ARGS__)
|
||||||
|
|
||||||
// Initializer & Finalizer
|
// Initializer & Finalizer
|
||||||
extern std::list<std::function<void()>> initializerFunctions;
|
extern std::list<std::function<void()>> initializer_functions;
|
||||||
extern std::list<std::function<void()>> finalizerFunctions;
|
extern std::list<std::function<void()>> finalizer_functions;
|
||||||
|
|
|
@ -38,33 +38,33 @@
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define S_SOURCE_MIRROR "Source.Mirror"
|
#define ST "Source.Mirror"
|
||||||
#define P_SOURCE "Source.Mirror.Source"
|
#define ST_SOURCE "Source.Mirror.Source"
|
||||||
#define P_SOURCE_SIZE "Source.Mirror.Source.Size"
|
#define ST_SOURCE_SIZE "Source.Mirror.Source.Size"
|
||||||
#define P_SOURCE_AUDIO "Source.Mirror.Source.Audio"
|
#define ST_AUDIO "Source.Mirror.Source.Audio"
|
||||||
#define ST_AUDIO_LAYOUT S_SOURCE_MIRROR ".Audio.Layout"
|
#define ST_AUDIO_LAYOUT ST ".Audio.Layout"
|
||||||
#define ST_AUDIO_LAYOUT_(x) ST_AUDIO_LAYOUT "." D_VSTR(x)
|
#define ST_AUDIO_LAYOUT_(x) ST_AUDIO_LAYOUT "." D_VSTR(x)
|
||||||
#define P_SCALING "Source.Mirror.Scaling"
|
#define ST_SCALING "Source.Mirror.Scaling"
|
||||||
#define P_SCALING_METHOD "Source.Mirror.Scaling.Method"
|
#define ST_SCALING_METHOD "Source.Mirror.Scaling.Method"
|
||||||
#define P_SCALING_METHOD_POINT "Source.Mirror.Scaling.Method.Point"
|
#define ST_SCALING_METHOD_POINT "Source.Mirror.Scaling.Method.Point"
|
||||||
#define P_SCALING_METHOD_BILINEAR "Source.Mirror.Scaling.Method.Bilinear"
|
#define ST_SCALING_METHOD_BILINEAR "Source.Mirror.Scaling.Method.Bilinear"
|
||||||
#define P_SCALING_METHOD_BICUBIC "Source.Mirror.Scaling.Method.Bicubic"
|
#define ST_SCALING_METHOD_BICUBIC "Source.Mirror.Scaling.Method.Bicubic"
|
||||||
#define P_SCALING_METHOD_LANCZOS "Source.Mirror.Scaling.Method.Lanczos"
|
#define ST_SCALING_METHOD_LANCZOS "Source.Mirror.Scaling.Method.Lanczos"
|
||||||
#define P_SCALING_SIZE "Source.Mirror.Scaling.Size"
|
#define ST_SCALING_SIZE "Source.Mirror.Scaling.Size"
|
||||||
#define P_SCALING_TRANSFORMKEEPORIGINAL "Source.Mirror.Scaling.TransformKeepOriginal"
|
#define ST_SCALING_TRANSFORMKEEPORIGINAL "Source.Mirror.Scaling.TransformKeepOriginal"
|
||||||
#define P_SCALING_BOUNDS "Source.Mirror.Scaling.Bounds"
|
#define ST_SCALING_BOUNDS "Source.Mirror.Scaling.Bounds"
|
||||||
#define P_SCALING_BOUNDS_STRETCH "Source.Mirror.Scaling.Bounds.Stretch"
|
#define ST_SCALING_BOUNDS_STRETCH "Source.Mirror.Scaling.Bounds.Stretch"
|
||||||
#define P_SCALING_BOUNDS_FIT "Source.Mirror.Scaling.Bounds.Fit"
|
#define ST_SCALING_BOUNDS_FIT "Source.Mirror.Scaling.Bounds.Fit"
|
||||||
#define P_SCALING_BOUNDS_FILL "Source.Mirror.Scaling.Bounds.Fill"
|
#define ST_SCALING_BOUNDS_FILL "Source.Mirror.Scaling.Bounds.Fill"
|
||||||
#define P_SCALING_BOUNDS_FILLWIDTH "Source.Mirror.Scaling.Bounds.FillWidth"
|
#define ST_SCALING_BOUNDS_FILLWIDTH "Source.Mirror.Scaling.Bounds.FillWidth"
|
||||||
#define P_SCALING_BOUNDS_FILLHEIGHT "Source.Mirror.Scaling.Bounds.FillHeight"
|
#define ST_SCALING_BOUNDS_FILLHEIGHT "Source.Mirror.Scaling.Bounds.FillHeight"
|
||||||
#define P_SCALING_ALIGNMENT "Source.Mirror.Scaling.Alignment"
|
#define ST_SCALING_ALIGNMENT "Source.Mirror.Scaling.Alignment"
|
||||||
|
|
||||||
// Initializer & Finalizer
|
// Initializer & Finalizer
|
||||||
INITIALIZER(SourceMirrorInit)
|
P_INITIALIZER(SourceMirrorInit)
|
||||||
{
|
{
|
||||||
initializerFunctions.push_back([] { source::mirror::mirror_factory::initialize(); });
|
initializer_functions.push_back([] { source::mirror::mirror_factory::initialize(); });
|
||||||
finalizerFunctions.push_back([] { source::mirror::mirror_factory::finalize(); });
|
finalizer_functions.push_back([] { source::mirror::mirror_factory::finalize(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<source::mirror::mirror_factory> factory_instance = nullptr;
|
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()
|
source::mirror::mirror_factory::mirror_factory()
|
||||||
{
|
{
|
||||||
memset(&osi, 0, sizeof(obs_source_info));
|
memset(&_source_info, 0, sizeof(obs_source_info));
|
||||||
osi.id = "obs-stream-effects-source-mirror";
|
_source_info.id = "obs-stream-effects-source-mirror";
|
||||||
osi.type = OBS_SOURCE_TYPE_INPUT;
|
_source_info.type = OBS_SOURCE_TYPE_INPUT;
|
||||||
osi.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_AUDIO | OBS_SOURCE_CUSTOM_DRAW;
|
_source_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_AUDIO | OBS_SOURCE_CUSTOM_DRAW;
|
||||||
|
|
||||||
osi.get_name = get_name;
|
_source_info.get_name = get_name;
|
||||||
osi.get_defaults = get_defaults;
|
_source_info.get_defaults = get_defaults;
|
||||||
osi.get_properties = get_properties;
|
_source_info.get_properties = get_properties;
|
||||||
osi.get_width = get_width;
|
_source_info.get_width = get_width;
|
||||||
osi.get_height = get_height;
|
_source_info.get_height = get_height;
|
||||||
osi.create = create;
|
_source_info.create = create;
|
||||||
osi.destroy = destroy;
|
_source_info.destroy = destroy;
|
||||||
osi.update = update;
|
_source_info.update = update;
|
||||||
osi.activate = activate;
|
_source_info.activate = activate;
|
||||||
osi.deactivate = deactivate;
|
_source_info.deactivate = deactivate;
|
||||||
osi.video_tick = video_tick;
|
_source_info.video_tick = video_tick;
|
||||||
osi.video_render = video_render;
|
_source_info.video_render = video_render;
|
||||||
osi.enum_active_sources = enum_active_sources;
|
_source_info.enum_active_sources = enum_active_sources;
|
||||||
osi.load = load;
|
_source_info.load = load;
|
||||||
osi.save = save;
|
_source_info.save = save;
|
||||||
|
|
||||||
obs_register_source(&osi);
|
obs_register_source(&_source_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
source::mirror::mirror_factory::~mirror_factory() {}
|
source::mirror::mirror_factory::~mirror_factory() {}
|
||||||
|
|
||||||
const char* source::mirror::mirror_factory::get_name(void*)
|
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)
|
void source::mirror::mirror_factory::get_defaults(obs_data_t* data)
|
||||||
{
|
{
|
||||||
obs_data_set_default_string(data, P_SOURCE, "");
|
obs_data_set_default_string(data, ST_SOURCE, "");
|
||||||
obs_data_set_default_bool(data, P_SOURCE_AUDIO, false);
|
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_int(data, ST_AUDIO_LAYOUT, static_cast<int64_t>(SPEAKERS_UNKNOWN));
|
||||||
obs_data_set_default_bool(data, P_SCALING, false);
|
obs_data_set_default_bool(data, ST_SCALING, false);
|
||||||
obs_data_set_default_string(data, P_SCALING_SIZE, "100x100");
|
obs_data_set_default_string(data, ST_SCALING_SIZE, "100x100");
|
||||||
obs_data_set_default_int(data, P_SCALING_METHOD, (int64_t)obs_scale_type::OBS_SCALE_BILINEAR);
|
obs_data_set_default_int(data, ST_SCALING_METHOD, (int64_t)obs_scale_type::OBS_SCALE_BILINEAR);
|
||||||
obs_data_set_default_bool(data, P_SCALING_TRANSFORMKEEPORIGINAL, false);
|
obs_data_set_default_bool(data, ST_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, ST_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_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)
|
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) {
|
if (obs_properties_get(pr, ST_SOURCE) == p) {
|
||||||
obs_source_t* target = obs_get_source_by_name(obs_data_get_string(data, P_SOURCE));
|
obs_source_t* target = obs_get_source_by_name(obs_data_get_string(data, ST_SOURCE));
|
||||||
if (target) {
|
if (target) {
|
||||||
std::vector<char> buf(256);
|
std::vector<char> buf(256);
|
||||||
snprintf(buf.data(), buf.size(), "%" PRIu32 "x%" PRIu32, obs_source_get_width(target),
|
snprintf(buf.data(), buf.size(), "%" PRIu32 "x%" PRIu32, obs_source_get_width(target),
|
||||||
obs_source_get_height(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 {
|
} else {
|
||||||
obs_data_set_string(data, P_SOURCE_SIZE, "0x0");
|
obs_data_set_string(data, ST_SOURCE_SIZE, "0x0");
|
||||||
}
|
}
|
||||||
obs_source_release(target);
|
obs_source_release(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obs_properties_get(pr, P_SOURCE_AUDIO) == p) {
|
if (obs_properties_get(pr, ST_AUDIO) == p) {
|
||||||
bool show = obs_data_get_bool(data, P_SOURCE_AUDIO);
|
bool show = obs_data_get_bool(data, ST_AUDIO);
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_AUDIO_LAYOUT), show);
|
obs_property_set_visible(obs_properties_get(pr, ST_AUDIO_LAYOUT), show);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obs_properties_get(pr, P_SCALING) == p) {
|
if (obs_properties_get(pr, ST_SCALING) == p) {
|
||||||
bool show = obs_data_get_bool(data, P_SCALING);
|
bool show = obs_data_get_bool(data, ST_SCALING);
|
||||||
obs_property_set_visible(obs_properties_get(pr, P_SCALING_METHOD), show);
|
obs_property_set_visible(obs_properties_get(pr, ST_SCALING_METHOD), show);
|
||||||
obs_property_set_visible(obs_properties_get(pr, P_SCALING_SIZE), show);
|
obs_property_set_visible(obs_properties_get(pr, ST_SCALING_SIZE), show);
|
||||||
obs_property_set_visible(obs_properties_get(pr, P_SCALING_BOUNDS), show);
|
obs_property_set_visible(obs_properties_get(pr, ST_SCALING_BOUNDS), show);
|
||||||
obs_property_set_visible(obs_properties_get(pr, P_SCALING_ALIGNMENT), show);
|
obs_property_set_visible(obs_properties_get(pr, ST_SCALING_ALIGNMENT), show);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obs_properties_get(pr, P_SCALING_BOUNDS) == p) {
|
if (obs_properties_get(pr, ST_SCALING_BOUNDS) == p) {
|
||||||
obs_bounds_type scaling_type = static_cast<obs_bounds_type>(obs_data_get_int(data, P_SCALING_BOUNDS));
|
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, P_SCALING_BOUNDS);
|
obs_property_t* p2 = obs_properties_get(pr, ST_SCALING_BOUNDS);
|
||||||
switch (scaling_type) {
|
switch (scaling_type) {
|
||||||
case obs_bounds_type::OBS_BOUNDS_STRETCH:
|
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;
|
break;
|
||||||
case obs_bounds_type::OBS_BOUNDS_SCALE_INNER:
|
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;
|
break;
|
||||||
case obs_bounds_type::OBS_BOUNDS_SCALE_OUTER:
|
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;
|
break;
|
||||||
case obs_bounds_type::OBS_BOUNDS_SCALE_TO_WIDTH:
|
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;
|
break;
|
||||||
case obs_bounds_type::OBS_BOUNDS_SCALE_TO_HEIGHT:
|
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;
|
break;
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -194,8 +194,8 @@ obs_properties_t* source::mirror::mirror_factory::get_properties(void*)
|
||||||
obs_properties_t* pr = obs_properties_create();
|
obs_properties_t* pr = obs_properties_create();
|
||||||
obs_property_t* p = nullptr;
|
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);
|
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, P_TRANSLATE(P_DESC(P_SOURCE)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SOURCE)));
|
||||||
obs_property_set_modified_callback(p, modified_properties);
|
obs_property_set_modified_callback(p, modified_properties);
|
||||||
obs_property_list_add_string(p, "", "");
|
obs_property_list_add_string(p, "", "");
|
||||||
obs::source_tracker::get()->enumerate(
|
obs::source_tracker::get()->enumerate(
|
||||||
|
@ -211,60 +211,60 @@ obs_properties_t* source::mirror::mirror_factory::get_properties(void*)
|
||||||
},
|
},
|
||||||
obs::source_tracker::filter_scenes);
|
obs::source_tracker::filter_scenes);
|
||||||
|
|
||||||
p = obs_properties_add_text(pr, P_SOURCE_SIZE, P_TRANSLATE(P_SOURCE_SIZE), OBS_TEXT_DEFAULT);
|
p = obs_properties_add_text(pr, ST_SOURCE_SIZE, D_TRANSLATE(ST_SOURCE_SIZE), OBS_TEXT_DEFAULT);
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SOURCE_SIZE)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SOURCE_SIZE)));
|
||||||
obs_property_set_enabled(p, false);
|
obs_property_set_enabled(p, false);
|
||||||
|
|
||||||
p = obs_properties_add_bool(pr, P_SOURCE_AUDIO, P_TRANSLATE(P_SOURCE_AUDIO));
|
p = obs_properties_add_bool(pr, ST_AUDIO, D_TRANSLATE(ST_AUDIO));
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SOURCE_AUDIO)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_AUDIO)));
|
||||||
obs_property_set_modified_callback(p, modified_properties);
|
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_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, D_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, D_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, D_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, D_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, D_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_(QuadraphonicLFE)),
|
||||||
static_cast<int64_t>(SPEAKERS_4POINT1));
|
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, D_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_list_add_int(p, D_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_set_long_description(p, D_TRANSLATE(D_DESC(ST_AUDIO_LAYOUT)));
|
||||||
|
|
||||||
p = obs_properties_add_bool(pr, P_SCALING, P_TRANSLATE(P_SCALING));
|
p = obs_properties_add_bool(pr, ST_SCALING, D_TRANSLATE(ST_SCALING));
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALING)));
|
||||||
obs_property_set_modified_callback(p, modified_properties);
|
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_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_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, D_TRANSLATE(ST_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, D_TRANSLATE(ST_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, D_TRANSLATE(ST_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_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);
|
p = obs_properties_add_text(pr, ST_SCALING_SIZE, D_TRANSLATE(ST_SCALING_SIZE), OBS_TEXT_DEFAULT);
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_SIZE)));
|
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));
|
p = obs_properties_add_bool(pr, ST_SCALING_TRANSFORMKEEPORIGINAL, D_TRANSLATE(ST_SCALING_TRANSFORMKEEPORIGINAL));
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_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_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_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, D_TRANSLATE(ST_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, D_TRANSLATE(ST_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, D_TRANSLATE(ST_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_FILLWIDTH),
|
||||||
(int64_t)obs_bounds_type::OBS_BOUNDS_SCALE_TO_WIDTH);
|
(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);
|
(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_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_property_list_add_int(p, obs_module_recursive_text("\\@" S_ALIGNMENT_LEFT "\\@ \\@" S_ALIGNMENT_TOP "\\@"),
|
||||||
OBS_ALIGN_LEFT | OBS_ALIGN_TOP);
|
OBS_ALIGN_LEFT | OBS_ALIGN_TOP);
|
||||||
obs_property_list_add_int(p, obs_module_recursive_text("\\@" S_ALIGNMENT_TOP "\\@"), 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()
|
void source::mirror::mirror_instance::release_input()
|
||||||
{
|
{
|
||||||
// Clear any references to the previous source.
|
// Clear any references to the previous source.
|
||||||
if (this->m_source_item) {
|
if (this->_source_item) {
|
||||||
obs_sceneitem_remove(this->m_source_item);
|
obs_sceneitem_remove(this->_source_item);
|
||||||
this->m_source_item = nullptr;
|
this->_source_item = nullptr;
|
||||||
}
|
}
|
||||||
this->m_source.reset();
|
this->_source.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void source::mirror::mirror_instance::acquire_input(std::string source_name)
|
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) {
|
if (!ref_source) {
|
||||||
// Early-Exit: Unable to find a source with this name, likely has been released.
|
// Early-Exit: Unable to find a source with this name, likely has been released.
|
||||||
#ifdef _DEBUG
|
#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());
|
source_name.c_str());
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
} else if (ref_source == this->m_self) {
|
} else if (ref_source == this->_self) {
|
||||||
// Early-Exit: Attempted self-mirror (recursion).
|
// Early-Exit: Attempted self-mirror (recursion).
|
||||||
#ifdef _DEBUG
|
#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
|
#endif
|
||||||
obs_source_release(ref_source);
|
obs_source_release(ref_source);
|
||||||
return;
|
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);
|
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.
|
// 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());
|
this->_source_item = obs_scene_add(obs_scene_from_source(this->_scene->get()), new_source->get());
|
||||||
if (!this->m_source_item) {
|
if (!this->_source_item) {
|
||||||
// Late-Exit: OBS detected something bad, so no further action will be taken.
|
// Late-Exit: OBS detected something bad, so no further action will be taken.
|
||||||
#ifdef _DEBUG
|
#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());
|
source_name.c_str());
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If everything worked fine, we now set everything up.
|
// If everything worked fine, we now set everything up.
|
||||||
this->m_source = new_source;
|
this->_source = new_source;
|
||||||
this->m_source->events.rename += std::bind(&source::mirror::mirror_instance::on_source_rename, this,
|
this->_source->events.rename += std::bind(&source::mirror::mirror_instance::on_source_rename, this,
|
||||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||||
if ((obs_source_get_output_flags(this->m_source->get()) & OBS_SOURCE_AUDIO) != 0) {
|
if ((obs_source_get_output_flags(this->_source->get()) & OBS_SOURCE_AUDIO) != 0) {
|
||||||
this->m_source->events.audio_data +=
|
this->_source->events.audio_data +=
|
||||||
std::bind(&source::mirror::mirror_instance::on_audio_data, this, std::placeholders::_1,
|
std::bind(&source::mirror::mirror_instance::on_audio_data, this, std::placeholders::_1,
|
||||||
std::placeholders::_2, std::placeholders::_3);
|
std::placeholders::_2, std::placeholders::_3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source::mirror::mirror_instance::mirror_instance(obs_data_t*, obs_source_t* src)
|
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),
|
: _self(src), _active(true), _tick(0), _scene_rendered(false), _rescale_enabled(false), _rescale_width(1),
|
||||||
m_rescale_height(1), m_rescale_keep_orig_size(false), m_rescale_type(obs_scale_type::OBS_SCALE_BICUBIC),
|
_rescale_height(1), _rescale_keep_orig_size(false), _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),
|
_rescale_bounds(obs_bounds_type::OBS_BOUNDS_STRETCH), _audio_enabled(false), _audio_kill_thread(false),
|
||||||
m_audio_have_output(false), m_source_item(nullptr)
|
_audio_have_output(false), _source_item(nullptr)
|
||||||
{
|
{
|
||||||
// Initialize Video Rendering
|
// 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")));
|
std::make_shared<obs::source>(obs_scene_get_source(obs_scene_create_private("Source Mirror Internal Scene")));
|
||||||
this->m_scene_texture_renderer =
|
this->_scene_texture_renderer =
|
||||||
std::make_shared<gfx::source_texture>(this->m_scene, std::make_shared<obs::source>(this->m_self, false, false));
|
std::make_shared<gfx::source_texture>(this->_scene, std::make_shared<obs::source>(this->_self, false, false));
|
||||||
|
|
||||||
// Initialize Audio Rendering
|
// 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()
|
source::mirror::mirror_instance::~mirror_instance()
|
||||||
|
@ -441,27 +441,27 @@ source::mirror::mirror_instance::~mirror_instance()
|
||||||
release_input();
|
release_input();
|
||||||
|
|
||||||
// Finalize Audio Rendering
|
// Finalize Audio Rendering
|
||||||
this->m_audio_kill_thread = true;
|
this->_audio_kill_thread = true;
|
||||||
this->m_audio_notify.notify_all();
|
this->_audio_notify.notify_all();
|
||||||
if (this->m_audio_thread.joinable()) {
|
if (this->_audio_thread.joinable()) {
|
||||||
this->m_audio_thread.join();
|
this->_audio_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize Video Rendering
|
// Finalize Video Rendering
|
||||||
this->m_scene_texture_renderer.reset();
|
this->_scene_texture_renderer.reset();
|
||||||
this->m_scene.reset();
|
this->_scene.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t source::mirror::mirror_instance::get_width()
|
uint32_t source::mirror::mirror_instance::get_width()
|
||||||
{
|
{
|
||||||
if (m_source) {
|
if (_source) {
|
||||||
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 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (this->m_rescale_enabled && this->m_rescale_width > 0 && !this->m_rescale_keep_orig_size) {
|
if (this->_rescale_enabled && this->_rescale_width > 0 && !this->_rescale_keep_orig_size) {
|
||||||
return this->m_rescale_width;
|
return this->_rescale_width;
|
||||||
} else {
|
} else {
|
||||||
return m_source->width();
|
return _source->width();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -469,14 +469,14 @@ uint32_t source::mirror::mirror_instance::get_width()
|
||||||
|
|
||||||
uint32_t source::mirror::mirror_instance::get_height()
|
uint32_t source::mirror::mirror_instance::get_height()
|
||||||
{
|
{
|
||||||
if (m_source) {
|
if (_source) {
|
||||||
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 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (this->m_rescale_enabled && this->m_rescale_height > 0 && !this->m_rescale_keep_orig_size) {
|
if (this->_rescale_enabled && this->_rescale_height > 0 && !this->_rescale_keep_orig_size) {
|
||||||
return this->m_rescale_height;
|
return this->_rescale_height;
|
||||||
} else {
|
} else {
|
||||||
return m_source->height();
|
return _source->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -486,84 +486,84 @@ void source::mirror::mirror_instance::update(obs_data_t* data)
|
||||||
{
|
{
|
||||||
{ // User changed the source we are tracking.
|
{ // User changed the source we are tracking.
|
||||||
release_input();
|
release_input();
|
||||||
this->m_source_name = obs_data_get_string(data, P_SOURCE);
|
this->_source_name = obs_data_get_string(data, ST_SOURCE);
|
||||||
if (this->m_source_name.length() > 0) {
|
if (this->_source_name.length() > 0) {
|
||||||
acquire_input(this->m_source_name);
|
acquire_input(this->_source_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
this->m_audio_enabled = obs_data_get_bool(data, P_SOURCE_AUDIO);
|
this->_audio_enabled = obs_data_get_bool(data, ST_AUDIO);
|
||||||
this->m_audio_layout = static_cast<speaker_layout>(obs_data_get_int(data, ST_AUDIO_LAYOUT));
|
this->_audio_layout = static_cast<speaker_layout>(obs_data_get_int(data, ST_AUDIO_LAYOUT));
|
||||||
|
|
||||||
// Rescaling
|
// Rescaling
|
||||||
this->m_rescale_enabled = obs_data_get_bool(data, P_SCALING);
|
this->_rescale_enabled = obs_data_get_bool(data, ST_SCALING);
|
||||||
if (this->m_rescale_enabled) { // Parse rescaling settings.
|
if (this->_rescale_enabled) { // Parse rescaling settings.
|
||||||
uint32_t width, height;
|
uint32_t width, height;
|
||||||
|
|
||||||
// Read value.
|
// 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');
|
const char* xpos = strchr(size, 'x');
|
||||||
if (xpos != nullptr) {
|
if (xpos != nullptr) {
|
||||||
// Width
|
// Width
|
||||||
width = strtoul(size, nullptr, 10);
|
width = strtoul(size, nullptr, 10);
|
||||||
if (errno == ERANGE || width == 0) {
|
if (errno == ERANGE || width == 0) {
|
||||||
this->m_rescale_enabled = false;
|
this->_rescale_enabled = false;
|
||||||
this->m_rescale_width = 1;
|
this->_rescale_width = 1;
|
||||||
} else {
|
} else {
|
||||||
this->m_rescale_width = width;
|
this->_rescale_width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
height = strtoul(xpos + 1, nullptr, 10);
|
height = strtoul(xpos + 1, nullptr, 10);
|
||||||
if (errno == ERANGE || height == 0) {
|
if (errno == ERANGE || height == 0) {
|
||||||
this->m_rescale_enabled = false;
|
this->_rescale_enabled = false;
|
||||||
this->m_rescale_height = 1;
|
this->_rescale_height = 1;
|
||||||
} else {
|
} else {
|
||||||
this->m_rescale_height = height;
|
this->_rescale_height = height;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->m_rescale_enabled = false;
|
this->_rescale_enabled = false;
|
||||||
this->m_rescale_width = 1;
|
this->_rescale_width = 1;
|
||||||
this->m_rescale_height = 1;
|
this->_rescale_height = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->m_rescale_keep_orig_size = obs_data_get_bool(data, P_SCALING_TRANSFORMKEEPORIGINAL);
|
this->_rescale_keep_orig_size = obs_data_get_bool(data, ST_SCALING_TRANSFORMKEEPORIGINAL);
|
||||||
this->m_rescale_type = static_cast<obs_scale_type>(obs_data_get_int(data, P_SCALING_METHOD));
|
this->_rescale_type = static_cast<obs_scale_type>(obs_data_get_int(data, ST_SCALING_METHOD));
|
||||||
this->m_rescale_bounds = static_cast<obs_bounds_type>(obs_data_get_int(data, P_SCALING_BOUNDS));
|
this->_rescale_bounds = static_cast<obs_bounds_type>(obs_data_get_int(data, ST_SCALING_BOUNDS));
|
||||||
this->m_rescale_alignment = static_cast<int32_t>(obs_data_get_int(data, P_SCALING_ALIGNMENT));
|
this->_rescale_alignment = static_cast<int32_t>(obs_data_get_int(data, ST_SCALING_ALIGNMENT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void source::mirror::mirror_instance::activate()
|
void source::mirror::mirror_instance::activate()
|
||||||
{
|
{
|
||||||
this->m_active = true;
|
this->_active = true;
|
||||||
|
|
||||||
// No source, delayed acquire.
|
// No source, delayed acquire.
|
||||||
if (!this->m_source_item && this->m_source_name.length() > 0) {
|
if (!this->_source_item && this->_source_name.length() > 0) {
|
||||||
this->acquire_input(this->m_source_name.c_str());
|
this->acquire_input(this->_source_name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void source::mirror::mirror_instance::deactivate()
|
void source::mirror::mirror_instance::deactivate()
|
||||||
{
|
{
|
||||||
this->m_active = false;
|
this->_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void source::mirror::mirror_instance::video_tick(float time)
|
void source::mirror::mirror_instance::video_tick(float time)
|
||||||
{
|
{
|
||||||
this->m_tick += time;
|
this->_tick += time;
|
||||||
if (this->m_tick > 0.1f) {
|
if (this->_tick > 0.1f) {
|
||||||
this->m_tick -= 0.1f;
|
this->_tick -= 0.1f;
|
||||||
|
|
||||||
// No source, delayed acquire.
|
// No source, delayed acquire.
|
||||||
if (!this->m_source_item && this->m_source_name.length() > 0) {
|
if (!this->_source_item && this->_source_name.length() > 0) {
|
||||||
this->acquire_input(this->m_source_name.c_str());
|
this->acquire_input(this->_source_name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Scene Item Boundaries
|
// Update Scene Item Boundaries
|
||||||
if ((this->m_source_item && this->m_source)
|
if ((this->_source_item && this->_source)
|
||||||
&& ((obs_source_get_output_flags(this->m_source->get()) & OBS_SOURCE_VIDEO) != 0)) {
|
&& ((obs_source_get_output_flags(this->_source->get()) & OBS_SOURCE_VIDEO) != 0)) {
|
||||||
obs_transform_info info;
|
obs_transform_info info;
|
||||||
info.pos.x = 0;
|
info.pos.x = 0;
|
||||||
info.pos.y = 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.alignment = OBS_ALIGN_LEFT | OBS_ALIGN_TOP;
|
||||||
info.bounds.x = float_t(this->get_width());
|
info.bounds.x = float_t(this->get_width());
|
||||||
info.bounds.y = float_t(this->get_height());
|
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;
|
info.bounds_type = obs_bounds_type::OBS_BOUNDS_STRETCH;
|
||||||
if (this->m_rescale_enabled) {
|
if (this->_rescale_enabled) {
|
||||||
info.bounds_type = this->m_rescale_bounds;
|
info.bounds_type = this->_rescale_bounds;
|
||||||
}
|
}
|
||||||
obs_sceneitem_set_info(this->m_source_item, &info);
|
obs_sceneitem_set_info(this->_source_item, &info);
|
||||||
obs_sceneitem_force_update_transform(this->m_source_item);
|
obs_sceneitem_force_update_transform(this->_source_item);
|
||||||
obs_sceneitem_set_scale_filter(this->m_source_item, this->m_rescale_enabled ? this->m_rescale_type
|
obs_sceneitem_set_scale_filter(this->_source_item, this->_rescale_enabled ? this->_rescale_type
|
||||||
: obs_scale_type::OBS_SCALE_POINT);
|
: obs_scale_type::OBS_SCALE_POINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_scene_rendered = false;
|
_scene_rendered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void source::mirror::mirror_instance::video_render(gs_effect_t* effect)
|
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
|
if ((this->_rescale_width == 0) || (this->_rescale_height == 0) || !this->_source_item
|
||||||
|| !this->m_scene_texture_renderer || !this->m_source) {
|
|| !this->_scene_texture_renderer || !this->_source) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't bother rendering sources that aren't video.
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only re-render the scene if there was a video_tick, saves GPU cycles.
|
// 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.
|
// Override render size if rescaling is enabled.
|
||||||
uint32_t render_width = this->m_source->width();
|
uint32_t render_width = this->_source->width();
|
||||||
uint32_t render_height = this->m_source->height();
|
uint32_t render_height = this->_source->height();
|
||||||
if (m_rescale_enabled) {
|
if (_rescale_enabled) {
|
||||||
render_width = m_rescale_width;
|
render_width = _rescale_width;
|
||||||
render_height = m_rescale_height;
|
render_height = _rescale_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!render_width || !render_height) {
|
if (!render_width || !render_height) {
|
||||||
|
@ -615,56 +615,56 @@ void source::mirror::mirror_instance::video_render(gs_effect_t* effect)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_scene_texture = this->m_scene_texture_renderer->render(render_width, render_height);
|
_scene_texture = this->_scene_texture_renderer->render(render_width, render_height);
|
||||||
m_scene_rendered = true;
|
_scene_rendered = true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// If we fail to render the source, just render nothing.
|
// If we fail to render the source, just render nothing.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_scene_texture) {
|
if (_scene_texture) {
|
||||||
// Use default effect unless we are provided a different effect.
|
// Use default effect unless we are provided a different effect.
|
||||||
if (!effect) {
|
if (!effect) {
|
||||||
effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
|
effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the cached scene texture.
|
// 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")) {
|
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()
|
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) {
|
while (!this->_audio_kill_thread) {
|
||||||
this->m_audio_notify.wait(ulock, [this]() { return this->m_audio_have_output || this->m_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::shared_ptr<mirror_audio_data> mad;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> capture_lock(this->m_audio_lock_capturer);
|
std::lock_guard<std::mutex> capture_lock(this->_audio_lock_capturer);
|
||||||
if (m_audio_data_queue.size() > 0) {
|
if (_audio_data_queue.size() > 0) {
|
||||||
mad = m_audio_data_queue.front();
|
mad = _audio_data_queue.front();
|
||||||
m_audio_data_queue.pop();
|
_audio_data_queue.pop();
|
||||||
}
|
}
|
||||||
if (m_audio_data_queue.size() == 0) {
|
if (_audio_data_queue.size() == 0) {
|
||||||
this->m_audio_have_output = false;
|
this->_audio_have_output = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mad) {
|
if (mad) {
|
||||||
ulock.unlock();
|
ulock.unlock();
|
||||||
obs_source_output_audio(this->m_self, &mad->audio);
|
obs_source_output_audio(this->_self, &mad->audio);
|
||||||
ulock.lock();
|
ulock.lock();
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> capture_lock(this->m_audio_lock_capturer);
|
std::lock_guard<std::mutex> capture_lock(this->_audio_lock_capturer);
|
||||||
m_audio_data_free_queue.push(mad);
|
_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)
|
void source::mirror::mirror_instance::enum_active_sources(obs_source_enum_proc_t enum_callback, void* param)
|
||||||
{
|
{
|
||||||
if (this->m_scene) {
|
if (this->_scene) {
|
||||||
enum_callback(this->m_self, this->m_scene->get(), param);
|
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)
|
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;
|
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)
|
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_t* ref = obs_source_get_settings(this->_self);
|
||||||
obs_data_set_string(ref, P_SOURCE, obs_source_get_name(source->get()));
|
obs_data_set_string(ref, ST_SOURCE, obs_source_get_name(source->get()));
|
||||||
obs_source_update(this->m_self, ref);
|
obs_source_update(this->_self, ref);
|
||||||
obs_data_release(ref);
|
obs_data_release(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void source::mirror::mirror_instance::on_audio_data(obs::source*, const audio_data* audio, bool)
|
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;
|
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;
|
std::shared_ptr<mirror_audio_data> mad;
|
||||||
{ // Get free audio data element.
|
{ // Get free audio data element.
|
||||||
std::lock_guard<std::mutex> capture_lock(this->m_audio_lock_capturer);
|
std::lock_guard<std::mutex> capture_lock(this->_audio_lock_capturer);
|
||||||
if (m_audio_data_free_queue.size() > 0) {
|
if (_audio_data_free_queue.size() > 0) {
|
||||||
mad = m_audio_data_free_queue.front();
|
mad = _audio_data_free_queue.front();
|
||||||
m_audio_data_free_queue.pop();
|
_audio_data_free_queue.pop();
|
||||||
} else {
|
} else {
|
||||||
mad = std::make_shared<mirror_audio_data>();
|
mad = std::make_shared<mirror_audio_data>();
|
||||||
mad->data.resize(MAX_AUDIO_CHANNELS);
|
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.frames = audio->frames;
|
||||||
mad->audio.timestamp = audio->timestamp;
|
mad->audio.timestamp = audio->timestamp;
|
||||||
mad->audio.samples_per_sec = aoi->samples_per_sec;
|
mad->audio.samples_per_sec = aoi->samples_per_sec;
|
||||||
if (this->m_audio_layout != SPEAKERS_UNKNOWN) {
|
if (this->_audio_layout != SPEAKERS_UNKNOWN) {
|
||||||
mad->audio.speakers = this->m_audio_layout;
|
mad->audio.speakers = this->_audio_layout;
|
||||||
} else {
|
} else {
|
||||||
mad->audio.speakers = aoi->speakers;
|
mad->audio.speakers = aoi->speakers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Push used audio data element.
|
{ // Push used audio data element.
|
||||||
std::lock_guard<std::mutex> capture_lock(this->m_audio_lock_capturer);
|
std::lock_guard<std::mutex> capture_lock(this->_audio_lock_capturer);
|
||||||
m_audio_data_queue.push(mad);
|
_audio_data_queue.push(mad);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Signal other side.
|
{ // Signal other side.
|
||||||
std::lock_guard<std::mutex> output_lock(this->m_audio_lock_outputter);
|
std::lock_guard<std::mutex> output_lock(this->_audio_lock_outputter);
|
||||||
this->m_audio_have_output = true;
|
this->_audio_have_output = true;
|
||||||
}
|
}
|
||||||
this->m_audio_notify.notify_all();
|
this->_audio_notify.notify_all();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
namespace source {
|
namespace source {
|
||||||
namespace mirror {
|
namespace mirror {
|
||||||
class mirror_factory {
|
class mirror_factory {
|
||||||
obs_source_info osi;
|
obs_source_info _source_info;
|
||||||
|
|
||||||
public: // Singleton
|
public: // Singleton
|
||||||
static void initialize();
|
static void initialize();
|
||||||
|
@ -81,41 +81,41 @@ namespace source {
|
||||||
};
|
};
|
||||||
|
|
||||||
class mirror_instance {
|
class mirror_instance {
|
||||||
obs_source_t* m_self;
|
obs_source_t* _self;
|
||||||
bool m_active;
|
bool _active;
|
||||||
float_t m_tick;
|
float_t _tick;
|
||||||
|
|
||||||
// Video Rendering
|
// Video Rendering
|
||||||
std::shared_ptr<obs::source> m_scene;
|
std::shared_ptr<obs::source> _scene;
|
||||||
std::shared_ptr<gfx::source_texture> m_scene_texture_renderer;
|
std::shared_ptr<gfx::source_texture> _scene_texture_renderer;
|
||||||
std::shared_ptr<gs::texture> m_scene_texture;
|
std::shared_ptr<gs::texture> _scene_texture;
|
||||||
bool m_scene_rendered;
|
bool _scene_rendered;
|
||||||
int m_rescale_alignment;
|
int _rescale_alignment;
|
||||||
|
|
||||||
// Rescaling
|
// Rescaling
|
||||||
bool m_rescale_enabled;
|
bool _rescale_enabled;
|
||||||
uint32_t m_rescale_width;
|
uint32_t _rescale_width;
|
||||||
uint32_t m_rescale_height;
|
uint32_t _rescale_height;
|
||||||
bool m_rescale_keep_orig_size;
|
bool _rescale_keep_orig_size;
|
||||||
obs_scale_type m_rescale_type;
|
obs_scale_type _rescale_type;
|
||||||
obs_bounds_type m_rescale_bounds;
|
obs_bounds_type _rescale_bounds;
|
||||||
|
|
||||||
// Audio Rendering
|
// Audio Rendering
|
||||||
bool m_audio_enabled;
|
bool _audio_enabled;
|
||||||
std::condition_variable m_audio_notify;
|
std::condition_variable _audio_notify;
|
||||||
std::thread m_audio_thread;
|
std::thread _audio_thread;
|
||||||
bool m_audio_kill_thread;
|
bool _audio_kill_thread;
|
||||||
bool m_audio_have_output;
|
bool _audio_have_output;
|
||||||
std::mutex m_audio_lock_outputter;
|
std::mutex _audio_lock_outputter;
|
||||||
std::mutex m_audio_lock_capturer;
|
std::mutex _audio_lock_capturer;
|
||||||
std::queue<std::shared_ptr<mirror_audio_data>> m_audio_data_queue;
|
std::queue<std::shared_ptr<mirror_audio_data>> _audio_data_queue;
|
||||||
std::queue<std::shared_ptr<mirror_audio_data>> m_audio_data_free_queue;
|
std::queue<std::shared_ptr<mirror_audio_data>> _audio_data_free_queue;
|
||||||
speaker_layout m_audio_layout;
|
speaker_layout _audio_layout;
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
std::shared_ptr<obs::source> m_source;
|
std::shared_ptr<obs::source> _source;
|
||||||
obs_sceneitem_t* m_source_item;
|
obs_sceneitem_t* _source_item;
|
||||||
std::string m_source_name;
|
std::string _source_name;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void release_input();
|
void release_input();
|
||||||
|
|
|
@ -20,14 +20,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
|
|
||||||
#define P_TRANSLATE(x) obs_module_text(x)
|
#define D_TRANSLATE(x) obs_module_text(x)
|
||||||
#define P_DESC(x) x ".Description"
|
#define D_DESC(x) x ".Description"
|
||||||
|
|
||||||
#define T_FILEFILTERS_IMAGE "*.png *.webp *.tga *.tiff *.jpeg *.jpg *.bmp"
|
#define S_FILEFILTERS_IMAGE "*.png *.webp *.tga *.tiff *.jpeg *.jpg *.bmp"
|
||||||
#define T_FILEFILTERS_VIDEO "*.mkv *.webm *.mp4 *.mov *.flv"
|
#define S_FILEFILTERS_VIDEO "*.mkv *.webm *.mp4 *.mov *.flv"
|
||||||
#define T_FILEFILTERS_SOUND "*.ogg *.flac *.mp3 *.wav"
|
#define S_FILEFILTERS_SOUND "*.ogg *.flac *.mp3 *.wav"
|
||||||
#define T_FILEFILTERS_EFFECT "*.effect *.txt"
|
#define S_FILEFILTERS_EFFECT "*.effect *.txt"
|
||||||
#define T_FILEFILTERS_ANY "*.*"
|
#define S_FILEFILTERS_ANY "*.*"
|
||||||
|
|
||||||
#define S_VERSION "Version"
|
#define S_VERSION "Version"
|
||||||
|
|
||||||
|
|
|
@ -36,14 +36,14 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
#define PI 3.1415926535897932384626433832795 // PI = pi
|
#define S_PI 3.1415926535897932384626433832795 // PI = pi
|
||||||
#define PI2 6.283185307179586476925286766559 // 2PI = 2 * pi
|
#define S_PI2 6.283185307179586476925286766559 // 2PI = 2 * pi
|
||||||
#define PI2_SQROOT 2.506628274631000502415765284811 // sqrt(2 * pi)
|
#define S_PI2_SQROOT 2.506628274631000502415765284811 // sqrt(2 * pi)
|
||||||
|
|
||||||
#define V_RAD 57.295779513082320876798154814105 // 180/pi
|
#define S_RAD 57.295779513082320876798154814105 // 180/pi
|
||||||
#define V_DEG 0.01745329251994329576923690768489 // pi/180
|
#define S_DEG 0.01745329251994329576923690768489 // pi/180
|
||||||
#define DEG_TO_RAD(x) (x * V_DEG)
|
#define D_DEG_TO_RAD(x) (x * S_DEG)
|
||||||
#define RAD_TO_DEG(x) (x * V_RAD)
|
#define D_RAD_TO_DEG(x) (x * S_RAD)
|
||||||
|
|
||||||
inline size_t GetNearestPowerOfTwoAbove(size_t v)
|
inline size_t GetNearestPowerOfTwoAbove(size_t v)
|
||||||
{
|
{
|
||||||
|
@ -114,23 +114,23 @@ namespace util {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma push_macro("is_power_of_two_as_loop")
|
#pragma push_macro("P_IS_POWER_OF_TWO_AS_LOOP")
|
||||||
#define is_power_of_two_as_loop(x) \
|
#define P_IS_POWER_OF_TWO_AS_LOOP(x) \
|
||||||
template<> \
|
template<> \
|
||||||
inline bool is_power_of_two(x v) \
|
inline bool is_power_of_two(x v) \
|
||||||
{ \
|
{ \
|
||||||
return is_power_of_two_loop(v); \
|
return is_power_of_two_loop(v); \
|
||||||
}
|
}
|
||||||
is_power_of_two_as_loop(int8_t);
|
P_IS_POWER_OF_TWO_AS_LOOP(int8_t);
|
||||||
is_power_of_two_as_loop(uint8_t);
|
P_IS_POWER_OF_TWO_AS_LOOP(uint8_t);
|
||||||
is_power_of_two_as_loop(int16_t);
|
P_IS_POWER_OF_TWO_AS_LOOP(int16_t);
|
||||||
is_power_of_two_as_loop(uint16_t);
|
P_IS_POWER_OF_TWO_AS_LOOP(uint16_t);
|
||||||
is_power_of_two_as_loop(int32_t);
|
P_IS_POWER_OF_TWO_AS_LOOP(int32_t);
|
||||||
is_power_of_two_as_loop(uint32_t);
|
P_IS_POWER_OF_TWO_AS_LOOP(uint32_t);
|
||||||
is_power_of_two_as_loop(int64_t);
|
P_IS_POWER_OF_TWO_AS_LOOP(int64_t);
|
||||||
is_power_of_two_as_loop(uint64_t);
|
P_IS_POWER_OF_TWO_AS_LOOP(uint64_t);
|
||||||
#undef is_power_of_two_as_loop
|
#undef P_IS_POWER_OF_TWO_AS_LOOP
|
||||||
#pragma pop_macro("is_power_of_two_as_loop")
|
#pragma pop_macro("P_IS_POWER_OF_TWO_AS_LOOP")
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline uint64_t get_power_of_two_exponent_floor(T v)
|
inline uint64_t get_power_of_two_exponent_floor(T v)
|
||||||
|
|
|
@ -22,10 +22,18 @@
|
||||||
|
|
||||||
#define USE_STD_ALLOC_FREE
|
#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)
|
void* util::malloc_aligned(size_t align, size_t size)
|
||||||
{
|
{
|
||||||
#ifdef USE_STD_ALLOC_FREE
|
#ifdef USE_STD_ALLOC_FREE
|
||||||
return aligned_alloc(align, size);
|
return D_ALIGNED_ALLOC(align, size);
|
||||||
#else
|
#else
|
||||||
// Ensure that we have space for the pointer and the data.
|
// Ensure that we have space for the pointer and the data.
|
||||||
size_t asize = aligned_offset(align, size + (sizeof(void*) * 2));
|
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)
|
void util::free_aligned(void* mem)
|
||||||
{
|
{
|
||||||
#ifdef USE_STD_ALLOC_FREE
|
#ifdef USE_STD_ALLOC_FREE
|
||||||
aligned_free(mem);
|
D_ALIGNED_FREE(mem);
|
||||||
#else
|
#else
|
||||||
void* ptr = reinterpret_cast<void*>(*reinterpret_cast<intptr_t*>(static_cast<char*>(mem) - sizeof(void*)));
|
void* ptr = reinterpret_cast<void*>(*reinterpret_cast<intptr_t*>(static_cast<char*>(mem) - sizeof(void*)));
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
|
|
@ -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));
|
return static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ENABLE_BITMASK_OPERATORS(x) \
|
#define P_ENABLE_BITMASK_OPERATORS(x) \
|
||||||
template<> \
|
template<> \
|
||||||
struct enable_bitmask_operators<x> { \
|
struct enable_bitmask_operators<x> { \
|
||||||
static const bool enable = true; \
|
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)
|
#define D_VSTR(s) D_STR(s)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define INITIALIZER(f) \
|
#define P_INITIALIZER(f) \
|
||||||
static void f(void); \
|
static void f(void); \
|
||||||
struct f##_t_ { \
|
struct f##_t_ { \
|
||||||
f##_t_(void) \
|
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; \
|
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
|
||||||
__pragma(comment(linker, "/include:" p #f "_")) static void f(void)
|
__pragma(comment(linker, "/include:" p #f "_")) static void f(void)
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#define INITIALIZER(f) INITIALIZER2_(f, "")
|
#define P_INITIALIZER(f) INITIALIZER2_(f, "")
|
||||||
#else
|
#else
|
||||||
#define INITIALIZER(f) INITIALIZER2_(f, "_")
|
#define P_INITIALIZER(f) INITIALIZER2_(f, "_")
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define INITIALIZER(f) \
|
#define P_INITIALIZER(f) \
|
||||||
static void f(void) __attribute__((constructor)); \
|
static void f(void) __attribute__((constructor)); \
|
||||||
static void f(void)
|
static void f(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue