filter-transform: Refactor onto obs::source_factory

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2019-10-18 21:58:16 +02:00
parent bacf52f9b6
commit 141a5efd00
2 changed files with 213 additions and 355 deletions

View File

@ -65,7 +65,7 @@
static const float farZ = 2097152.0f; // 2 pow 21
static const float nearZ = 1.0f / farZ;
enum class CameraMode : int32_t { Orthographic, Perspective };
enum class CameraMode : int64_t { Orthographic, Perspective };
enum RotationOrder : int64_t {
XYZ,
@ -76,297 +76,8 @@ enum RotationOrder : int64_t {
ZYX,
};
static std::shared_ptr<filter::transform::transform_factory> factory_instance = nullptr;
void filter::transform::transform_factory::initialize()
{
factory_instance = std::make_shared<filter::transform::transform_factory>();
}
void filter::transform::transform_factory::finalize()
{
factory_instance.reset();
}
std::shared_ptr<filter::transform::transform_factory> filter::transform::transform_factory::get()
{
return factory_instance;
}
filter::transform::transform_factory::transform_factory()
{
memset(&_source_info, 0, sizeof(obs_source_info));
_source_info.id = "obs-stream-effects-filter-transform";
_source_info.type = OBS_SOURCE_TYPE_FILTER;
_source_info.output_flags = OBS_SOURCE_VIDEO;
_source_info.get_name = get_name;
_source_info.get_defaults = get_defaults;
_source_info.get_properties = get_properties;
_source_info.create = create;
_source_info.destroy = destroy;
_source_info.update = update;
_source_info.activate = activate;
_source_info.deactivate = deactivate;
_source_info.video_tick = video_tick;
_source_info.video_render = video_render;
obs_register_source(&_source_info);
}
filter::transform::transform_factory::~transform_factory() {}
const char* filter::transform::transform_factory::get_name(void*) noexcept try {
return D_TRANSLATE(ST);
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
void filter::transform::transform_factory::get_defaults(obs_data_t* data) noexcept try {
obs_data_set_default_int(data, ST_CAMERA, (int64_t)CameraMode::Orthographic);
obs_data_set_default_double(data, ST_CAMERA_FIELDOFVIEW, 90.0);
obs_data_set_default_double(data, ST_POSITION_X, 0);
obs_data_set_default_double(data, ST_POSITION_Y, 0);
obs_data_set_default_double(data, ST_POSITION_Z, 0);
obs_data_set_default_double(data, ST_ROTATION_X, 0);
obs_data_set_default_double(data, ST_ROTATION_Y, 0);
obs_data_set_default_double(data, ST_ROTATION_Z, 0);
obs_data_set_default_double(data, ST_SCALE_X, 100);
obs_data_set_default_double(data, ST_SCALE_Y, 100);
obs_data_set_default_double(data, ST_SHEAR_X, 0);
obs_data_set_default_double(data, ST_SHEAR_Y, 0);
obs_data_set_default_bool(data, S_ADVANCED, false);
obs_data_set_default_int(data, ST_ROTATION_ORDER, RotationOrder::ZXY);
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
obs_properties_t* filter::transform::transform_factory::get_properties(void*) noexcept try {
obs_properties_t* pr = obs_properties_create();
obs_property_t* p = NULL;
// Camera
/// Projection Mode
p = obs_properties_add_list(pr, ST_CAMERA, D_TRANSLATE(ST_CAMERA), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA)));
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_ORTHOGRAPHIC), (int64_t)CameraMode::Orthographic);
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_PERSPECTIVE), (int64_t)CameraMode::Perspective);
obs_property_set_modified_callback(p, modified_properties);
/// Field Of View
p = obs_properties_add_float_slider(pr, ST_CAMERA_FIELDOFVIEW, D_TRANSLATE(ST_CAMERA_FIELDOFVIEW), 1.0, 179.0,
0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA_FIELDOFVIEW)));
// Mesh
/// Position
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_POSITION_X, D_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_Y, D_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_Z, D_DESC(ST_POSITION)),
};
for (auto kv : entries) {
p = obs_properties_add_float(pr, kv.first, D_TRANSLATE(kv.first), -10000, 10000, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Rotation
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_ROTATION_X, D_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_Y, D_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_Z, D_DESC(ST_ROTATION)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -180, 180, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Scale
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_SCALE_X, D_DESC(ST_SCALE)),
std::make_pair(ST_SCALE_Y, D_DESC(ST_SCALE)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -1000, 1000, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Shear
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_SHEAR_X, D_DESC(ST_SHEAR)),
std::make_pair(ST_SHEAR_Y, D_DESC(ST_SHEAR)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -100.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
p = obs_properties_add_bool(pr, S_ADVANCED, D_TRANSLATE(S_ADVANCED));
obs_property_set_modified_callback(p, modified_properties);
p = obs_properties_add_list(pr, ST_ROTATION_ORDER, D_TRANSLATE(ST_ROTATION_ORDER), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROTATION_ORDER)));
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_XYZ), RotationOrder::XYZ);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_XZY), RotationOrder::XZY);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_YXZ), RotationOrder::YXZ);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_YZX), RotationOrder::YZX);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_ZXY), RotationOrder::ZXY);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_ZYX), RotationOrder::ZYX);
p = obs_properties_add_bool(pr, ST_MIPMAPPING, D_TRANSLATE(ST_MIPMAPPING));
obs_property_set_modified_callback(p, modified_properties);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MIPMAPPING)));
p = obs_properties_add_list(pr, S_MIPGENERATOR, D_TRANSLATE(S_MIPGENERATOR), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_MIPGENERATOR)));
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_POINT), (long long)gs::mipmapper::generator::Point);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_LINEAR), (long long)gs::mipmapper::generator::Linear);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_SHARPEN), (long long)gs::mipmapper::generator::Sharpen);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_SMOOTHEN), (long long)gs::mipmapper::generator::Smoothen);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_BICUBIC), (long long)gs::mipmapper::generator::Bicubic);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_LANCZOS), (long long)gs::mipmapper::generator::Lanczos);
p = obs_properties_add_float_slider(pr, S_MIPGENERATOR_INTENSITY, D_TRANSLATE(S_MIPGENERATOR_INTENSITY), 0.0,
1000.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_MIPGENERATOR_INTENSITY)));
return pr;
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
return nullptr;
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return nullptr;
}
bool filter::transform::transform_factory::modified_properties(obs_properties_t* pr, obs_property_t*,
obs_data_t* d) noexcept try {
switch ((CameraMode)obs_data_get_int(d, ST_CAMERA)) {
case CameraMode::Orthographic:
obs_property_set_visible(obs_properties_get(pr, ST_CAMERA_FIELDOFVIEW), false);
obs_property_set_visible(obs_properties_get(pr, ST_POSITION_Z), false);
break;
case CameraMode::Perspective:
obs_property_set_visible(obs_properties_get(pr, ST_CAMERA_FIELDOFVIEW), true);
obs_property_set_visible(obs_properties_get(pr, ST_POSITION_Z), true);
break;
}
bool advancedVisible = obs_data_get_bool(d, S_ADVANCED);
obs_property_set_visible(obs_properties_get(pr, ST_ROTATION_ORDER), advancedVisible);
obs_property_set_visible(obs_properties_get(pr, ST_MIPMAPPING), advancedVisible);
bool mipmappingVisible = obs_data_get_bool(d, ST_MIPMAPPING) && advancedVisible;
obs_property_set_visible(obs_properties_get(pr, S_MIPGENERATOR), mipmappingVisible);
obs_property_set_visible(obs_properties_get(pr, S_MIPGENERATOR_INTENSITY), mipmappingVisible);
return true;
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
void* filter::transform::transform_factory::create(obs_data_t* data, obs_source_t* source) noexcept try {
return new transform_instance(data, source);
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
return nullptr;
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return nullptr;
}
void filter::transform::transform_factory::destroy(void* ptr) noexcept try {
delete reinterpret_cast<transform_instance*>(ptr);
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
uint32_t filter::transform::transform_factory::get_width(void* ptr) noexcept try {
return reinterpret_cast<transform_instance*>(ptr)->get_width();
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
return 0;
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return 0;
}
uint32_t filter::transform::transform_factory::get_height(void* ptr) noexcept try {
return reinterpret_cast<transform_instance*>(ptr)->get_height();
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
return 0;
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return 0;
}
void filter::transform::transform_factory::update(void* ptr, obs_data_t* data) noexcept try {
reinterpret_cast<transform_instance*>(ptr)->update(data);
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
void filter::transform::transform_factory::activate(void* ptr) noexcept try {
reinterpret_cast<transform_instance*>(ptr)->activate();
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
void filter::transform::transform_factory::deactivate(void* ptr) noexcept try {
reinterpret_cast<transform_instance*>(ptr)->deactivate();
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
void filter::transform::transform_factory::video_tick(void* ptr, float time) noexcept try {
reinterpret_cast<transform_instance*>(ptr)->video_tick(time);
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
void filter::transform::transform_factory::video_render(void* ptr, gs_effect_t* effect) noexcept try {
reinterpret_cast<transform_instance*>(ptr)->video_render(effect);
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
filter::transform::transform_instance::~transform_instance()
{
_shear.reset();
_scale.reset();
_rotation.reset();
_position.reset();
_vertex_buffer.reset();
_shape_texture.reset();
_shape_rendertarget.reset();
_source_texture.reset();
_source_rendertarget.reset();
}
filter::transform::transform_instance::transform_instance(obs_data_t* data, obs_source_t* context)
: _active(true), _self(context), _source_rendered(false), _mipmap_enabled(false), _mipmap_strength(50.0),
: obs::source_instance(data, context), _source_rendered(false), _mipmap_enabled(false), _mipmap_strength(50.0),
_mipmap_generator(gs::mipmapper::generator::Linear), _update_mesh(false), _rotation_order(RotationOrder::ZXY),
_camera_orthographic(true), _camera_fov(90.0)
{
@ -386,14 +97,17 @@ filter::transform::transform_instance::transform_instance(obs_data_t* data, obs_
update(data);
}
uint32_t filter::transform::transform_instance::get_width()
filter::transform::transform_instance::~transform_instance()
{
return 0;
}
uint32_t filter::transform::transform_instance::get_height()
{
return 0;
_shear.reset();
_scale.reset();
_rotation.reset();
_position.reset();
_vertex_buffer.reset();
_shape_texture.reset();
_shape_rendertarget.reset();
_source_texture.reset();
_source_rendertarget.reset();
}
void filter::transform::transform_instance::update(obs_data_t* data)
@ -425,16 +139,6 @@ void filter::transform::transform_instance::update(obs_data_t* data)
_update_mesh = true;
}
void filter::transform::transform_instance::activate()
{
_active = true;
}
void filter::transform::transform_instance::deactivate()
{
_active = false;
}
void filter::transform::transform_instance::video_tick(float)
{
uint32_t width = 0;
@ -552,11 +256,6 @@ void filter::transform::transform_instance::video_tick(float)
void filter::transform::transform_instance::video_render(gs_effect_t* paramEffect)
{
if (!_active) {
obs_source_skip_video_filter(_self);
return;
}
// Grab parent and target.
obs_source_t* parent = obs_filter_get_parent(_self);
obs_source_t* target = obs_filter_get_target(_self);
@ -700,3 +399,168 @@ void filter::transform::transform_instance::video_render(gs_effect_t* paramEffec
gs_draw_sprite(_shape_texture->get_object(), 0, 0, 0);
}
}
std::shared_ptr<filter::transform::transform_factory> filter::transform::transform_factory::factory_instance = nullptr;
filter::transform::transform_factory::transform_factory()
{
_info.id = "obs-stream-effects-filter-transform";
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO;
_info.get_width = _info.get_height = nullptr;
obs_register_source(&_info);
}
filter::transform::transform_factory::~transform_factory() {}
const char* filter::transform::transform_factory::get_name()
{
return D_TRANSLATE(ST);
}
void filter::transform::transform_factory::get_defaults2(obs_data_t* data)
{
obs_data_set_default_int(data, ST_CAMERA, (int64_t)CameraMode::Orthographic);
obs_data_set_default_double(data, ST_CAMERA_FIELDOFVIEW, 90.0);
obs_data_set_default_double(data, ST_POSITION_X, 0);
obs_data_set_default_double(data, ST_POSITION_Y, 0);
obs_data_set_default_double(data, ST_POSITION_Z, 0);
obs_data_set_default_double(data, ST_ROTATION_X, 0);
obs_data_set_default_double(data, ST_ROTATION_Y, 0);
obs_data_set_default_double(data, ST_ROTATION_Z, 0);
obs_data_set_default_double(data, ST_SCALE_X, 100);
obs_data_set_default_double(data, ST_SCALE_Y, 100);
obs_data_set_default_double(data, ST_SHEAR_X, 0);
obs_data_set_default_double(data, ST_SHEAR_Y, 0);
obs_data_set_default_bool(data, S_ADVANCED, false);
obs_data_set_default_int(data, ST_ROTATION_ORDER, RotationOrder::ZXY);
}
static bool modified_properties(obs_properties_t* pr, obs_property_t*, obs_data_t* d) noexcept try {
switch ((CameraMode)obs_data_get_int(d, ST_CAMERA)) {
case CameraMode::Orthographic:
obs_property_set_visible(obs_properties_get(pr, ST_CAMERA_FIELDOFVIEW), false);
obs_property_set_visible(obs_properties_get(pr, ST_POSITION_Z), false);
break;
case CameraMode::Perspective:
obs_property_set_visible(obs_properties_get(pr, ST_CAMERA_FIELDOFVIEW), true);
obs_property_set_visible(obs_properties_get(pr, ST_POSITION_Z), true);
break;
}
bool advancedVisible = obs_data_get_bool(d, S_ADVANCED);
obs_property_set_visible(obs_properties_get(pr, ST_ROTATION_ORDER), advancedVisible);
obs_property_set_visible(obs_properties_get(pr, ST_MIPMAPPING), advancedVisible);
bool mipmappingVisible = obs_data_get_bool(d, ST_MIPMAPPING) && advancedVisible;
obs_property_set_visible(obs_properties_get(pr, S_MIPGENERATOR), mipmappingVisible);
obs_property_set_visible(obs_properties_get(pr, S_MIPGENERATOR_INTENSITY), mipmappingVisible);
return true;
} catch (const std::exception& ex) {
P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
obs_properties_t* filter::transform::transform_factory::get_properties2(filter::transform::transform_instance* data)
{
obs_properties_t* pr = obs_properties_create();
obs_property_t* p = NULL;
// Camera
/// Projection Mode
p = obs_properties_add_list(pr, ST_CAMERA, D_TRANSLATE(ST_CAMERA), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA)));
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_ORTHOGRAPHIC), (int64_t)CameraMode::Orthographic);
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_PERSPECTIVE), (int64_t)CameraMode::Perspective);
obs_property_set_modified_callback(p, modified_properties);
/// Field Of View
p = obs_properties_add_float_slider(pr, ST_CAMERA_FIELDOFVIEW, D_TRANSLATE(ST_CAMERA_FIELDOFVIEW), 1.0, 179.0,
0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA_FIELDOFVIEW)));
// Mesh
/// Position
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_POSITION_X, D_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_Y, D_DESC(ST_POSITION)),
std::make_pair(ST_POSITION_Z, D_DESC(ST_POSITION)),
};
for (auto kv : entries) {
p = obs_properties_add_float(pr, kv.first, D_TRANSLATE(kv.first), -10000, 10000, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Rotation
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_ROTATION_X, D_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_Y, D_DESC(ST_ROTATION)),
std::make_pair(ST_ROTATION_Z, D_DESC(ST_ROTATION)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -180, 180, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Scale
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_SCALE_X, D_DESC(ST_SCALE)),
std::make_pair(ST_SCALE_Y, D_DESC(ST_SCALE)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -1000, 1000, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
/// Shear
{
std::pair<const char*, const char*> entries[] = {
std::make_pair(ST_SHEAR_X, D_DESC(ST_SHEAR)),
std::make_pair(ST_SHEAR_Y, D_DESC(ST_SHEAR)),
};
for (auto kv : entries) {
p = obs_properties_add_float_slider(pr, kv.first, D_TRANSLATE(kv.first), -100.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(kv.second));
}
}
p = obs_properties_add_bool(pr, S_ADVANCED, D_TRANSLATE(S_ADVANCED));
obs_property_set_modified_callback(p, modified_properties);
p = obs_properties_add_list(pr, ST_ROTATION_ORDER, D_TRANSLATE(ST_ROTATION_ORDER), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROTATION_ORDER)));
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_XYZ), RotationOrder::XYZ);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_XZY), RotationOrder::XZY);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_YXZ), RotationOrder::YXZ);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_YZX), RotationOrder::YZX);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_ZXY), RotationOrder::ZXY);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_ZYX), RotationOrder::ZYX);
p = obs_properties_add_bool(pr, ST_MIPMAPPING, D_TRANSLATE(ST_MIPMAPPING));
obs_property_set_modified_callback(p, modified_properties);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MIPMAPPING)));
p = obs_properties_add_list(pr, S_MIPGENERATOR, D_TRANSLATE(S_MIPGENERATOR), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_MIPGENERATOR)));
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_POINT), (long long)gs::mipmapper::generator::Point);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_LINEAR), (long long)gs::mipmapper::generator::Linear);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_SHARPEN), (long long)gs::mipmapper::generator::Sharpen);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_SMOOTHEN), (long long)gs::mipmapper::generator::Smoothen);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_BICUBIC), (long long)gs::mipmapper::generator::Bicubic);
obs_property_list_add_int(p, D_TRANSLATE(S_MIPGENERATOR_LANCZOS), (long long)gs::mipmapper::generator::Lanczos);
p = obs_properties_add_float_slider(pr, S_MIPGENERATOR_INTENSITY, D_TRANSLATE(S_MIPGENERATOR_INTENSITY), 0.0,
1000.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_MIPGENERATOR_INTENSITY)));
return pr;
}

View File

@ -24,44 +24,12 @@
#include "obs/gs/gs-rendertarget.hpp"
#include "obs/gs/gs-texture.hpp"
#include "obs/gs/gs-vertexbuffer.hpp"
#include "obs/obs-source-factory.hpp"
#include "plugin.hpp"
namespace filter {
namespace transform {
class transform_factory {
obs_source_info _source_info;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<transform_factory> get();
public:
transform_factory();
~transform_factory();
static const char* get_name(void*) noexcept;
static void get_defaults(obs_data_t*) noexcept;
static obs_properties_t* get_properties(void*) noexcept;
static bool modified_properties(obs_properties_t*, obs_property_t*, obs_data_t*) noexcept;
static void* create(obs_data_t*, obs_source_t*) noexcept;
static void destroy(void*) noexcept;
static uint32_t get_width(void*) noexcept;
static uint32_t get_height(void*) noexcept;
static void update(void*, obs_data_t*) noexcept;
static void activate(void*) noexcept;
static void deactivate(void*) noexcept;
static void show(void*) noexcept;
static void hide(void*) noexcept;
static void video_tick(void*, float) noexcept;
static void video_render(void*, gs_effect_t*) noexcept;
};
class transform_instance {
bool _active;
obs_source_t* _self;
class transform_instance : public obs::source_instance {
// Input
std::shared_ptr<gs::rendertarget> _source_rendertarget;
std::shared_ptr<gs::texture> _source_texture;
@ -92,17 +60,43 @@ namespace filter {
float_t _camera_fov;
public:
~transform_instance();
transform_instance(obs_data_t*, obs_source_t*);
virtual ~transform_instance() override;
uint32_t get_width();
uint32_t get_height();
virtual void update(obs_data_t*) override;
virtual void video_tick(float) override;
virtual void video_render(gs_effect_t*) override;
};
void update(obs_data_t*);
void activate();
void deactivate();
void video_tick(float);
void video_render(gs_effect_t*);
class transform_factory
: public obs::source_factory<filter::transform::transform_factory, filter::transform::transform_instance> {
static std::shared_ptr<filter::transform::transform_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<filter::transform::transform_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<transform_factory> get()
{
return factory_instance;
}
public:
transform_factory();
virtual ~transform_factory() override;
virtual const char* get_name() override;
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(filter::transform::transform_instance* data) override;
};
} // namespace transform
} // namespace filter