mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-24 08:39:59 +01:00
New OSC Filter attribute of source
Adding attribute for setting filter: set filter by name, set method by name, set first argument value
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include "Mixer.h"
|
||||
#include "Source.h"
|
||||
#include "TextSource.h"
|
||||
#include "CloneSource.h"
|
||||
#include "SourceCallback.h"
|
||||
#include "ImageProcessingShader.h"
|
||||
#include "ActionManager.h"
|
||||
@@ -252,24 +253,28 @@ std::string Control::RequestListener::FullMessage( const osc::ReceivedMessage& m
|
||||
osc::ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
|
||||
while (arg != m.ArgumentsEnd()) {
|
||||
if( arg->IsBool() ){
|
||||
bool a = (arg++)->AsBoolUnchecked();
|
||||
bool a = (arg)->AsBoolUnchecked();
|
||||
message << (a ? "T" : "F");
|
||||
}
|
||||
else if( arg->IsInt32() ){
|
||||
int a = (arg++)->AsInt32Unchecked();
|
||||
int a = (arg)->AsInt32Unchecked();
|
||||
message << "i";
|
||||
arguments << " " << a;
|
||||
}
|
||||
else if( arg->IsFloat() ){
|
||||
float a = (arg++)->AsFloatUnchecked();
|
||||
float a = (arg)->AsFloatUnchecked();
|
||||
message << "f";
|
||||
arguments << " " << std::fixed << std::setprecision(2) << a;
|
||||
}
|
||||
else if( arg->IsString() ){
|
||||
const char *a = (arg++)->AsStringUnchecked();
|
||||
const char *a = (arg)->AsStringUnchecked();
|
||||
message << "s";
|
||||
arguments << " " << a;
|
||||
}
|
||||
else if (arg->IsNil()) {
|
||||
message << "N";
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
catch( osc::Exception& e ){
|
||||
@@ -882,6 +887,46 @@ bool Control::receiveSourceAttribute(Source *target, const std::string &attribut
|
||||
textsrc->contents()->setText(label);
|
||||
}
|
||||
}
|
||||
/// e.g. '/vimix/current/filter sf blur 0.5'
|
||||
else if (attribute.compare(OSC_SOURCE_FILTER) == 0) {
|
||||
std::string filter_name;
|
||||
std::string filter_method;
|
||||
float filter_value = NAN;
|
||||
float t = 0.f;
|
||||
try {
|
||||
const char *str = nullptr;
|
||||
arguments >> str;
|
||||
filter_name = std::string(str);
|
||||
}
|
||||
// ignore invalid or Nil types
|
||||
catch (osc::WrongArgumentTypeException &) {
|
||||
}
|
||||
|
||||
if (arguments.Eos())
|
||||
arguments >> osc::EndMessage;
|
||||
else {
|
||||
try {
|
||||
const char *str = nullptr;
|
||||
arguments >> str;
|
||||
filter_method = std::string(str);
|
||||
}
|
||||
// ignore invalid or Nil types
|
||||
catch (osc::WrongArgumentTypeException &) {
|
||||
}
|
||||
if (arguments.Eos())
|
||||
arguments >> osc::EndMessage;
|
||||
else {
|
||||
arguments >> filter_value;
|
||||
if (arguments.Eos())
|
||||
arguments >> osc::EndMessage;
|
||||
else {
|
||||
arguments >> t >> osc::EndMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
// operate on source
|
||||
target->call( new SetFilter(filter_name, filter_method, filter_value, t), true);
|
||||
}
|
||||
/// e.g. '/vimix/name/sync'
|
||||
else if ( attribute.compare(OSC_SYNC) == 0) {
|
||||
// this will require to send feedback status about source
|
||||
|
||||
@@ -63,6 +63,11 @@
|
||||
#define OSC_SOURCE_POSTERIZE "/posterize"
|
||||
#define OSC_SOURCE_INVERT "/invert"
|
||||
#define OSC_SOURCE_CORRECTION "/correction"
|
||||
#define OSC_SOURCE_CROP "/crop"
|
||||
#define OSC_SOURCE_TEXPOSITION "/texture_position"
|
||||
#define OSC_SOURCE_TEXSIZE "/texture_size"
|
||||
#define OSC_SOURCE_TEXANGLE "/texture_angle"
|
||||
#define OSC_SOURCE_FILTER "/filter"
|
||||
|
||||
#define OSC_SESSION "/session"
|
||||
#define OSC_SESSION_VERSION "/version"
|
||||
|
||||
@@ -1228,32 +1228,6 @@ void ImGuiVisitor::visit (AlphaFilter& f)
|
||||
|
||||
if ( m == AlphaFilter::ALPHA_CHROMAKEY || m == AlphaFilter::ALPHA_LUMAKEY)
|
||||
{
|
||||
float t = filter_parameters["Threshold"];
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if (ImGui::SliderFloat( "##Threshold", &t, 0.f, 1.f, "%.2f")) {
|
||||
f.setProgramParameter("Threshold", t);
|
||||
}
|
||||
if (ImGui::IsItemHovered() && io.MouseWheel != 0.f ){
|
||||
t = CLAMP( t + 0.01f * io.MouseWheel, 0.f, 1.f);
|
||||
f.setProgramParameter("Threshold", t);
|
||||
oss << AlphaFilter::operation_label[ f.operation() ];
|
||||
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
if (ImGui::IsItemDeactivatedAfterEdit()) {
|
||||
oss << AlphaFilter::operation_label[ f.operation() ];
|
||||
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
ImGui::SameLine(0, IMGUI_SAME_LINE);
|
||||
if (ImGuiToolkit::TextButton("Threshold")) {
|
||||
t = 0.f;
|
||||
f.setProgramParameter("Threshold", t);
|
||||
oss << AlphaFilter::operation_label[ f.operation() ];
|
||||
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
|
||||
float v = filter_parameters["Tolerance"];
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if (ImGui::SliderFloat( "##Tolerance", &v, 0.f, 1.f, "%.2f")) {
|
||||
@@ -1279,6 +1253,32 @@ void ImGuiVisitor::visit (AlphaFilter& f)
|
||||
oss << " : " << "Tolerance" << " " << std::setprecision(3) << v;
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
|
||||
float t = filter_parameters["Threshold"];
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if (ImGui::SliderFloat( "##Threshold", &t, 0.f, 1.f, "%.2f")) {
|
||||
f.setProgramParameter("Threshold", t);
|
||||
}
|
||||
if (ImGui::IsItemHovered() && io.MouseWheel != 0.f ){
|
||||
t = CLAMP( t + 0.01f * io.MouseWheel, 0.f, 1.f);
|
||||
f.setProgramParameter("Threshold", t);
|
||||
oss << AlphaFilter::operation_label[ f.operation() ];
|
||||
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
if (ImGui::IsItemDeactivatedAfterEdit()) {
|
||||
oss << AlphaFilter::operation_label[ f.operation() ];
|
||||
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
ImGui::SameLine(0, IMGUI_SAME_LINE);
|
||||
if (ImGuiToolkit::TextButton("Threshold")) {
|
||||
t = 0.f;
|
||||
f.setProgramParameter("Threshold", t);
|
||||
oss << AlphaFilter::operation_label[ f.operation() ];
|
||||
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
}
|
||||
|
||||
if ( m == AlphaFilter::ALPHA_CHROMAKEY || m == AlphaFilter::ALPHA_FILL)
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <glm/gtc/matrix_access.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include "defines.h"
|
||||
#include "Resource.h"
|
||||
#include "Visitor.h"
|
||||
#include "FrameBuffer.h"
|
||||
@@ -465,6 +464,34 @@ void ResampleFilter::setFactor(int factor)
|
||||
input_ = nullptr;
|
||||
}
|
||||
|
||||
bool ResampleFilter::setFactor(const std::string &label)
|
||||
{
|
||||
std::string target_factor = label;
|
||||
std::transform(target_factor.begin(), target_factor.end(), target_factor.begin(), ::tolower);
|
||||
|
||||
// find method by name
|
||||
int __f = ResampleFilter::RESAMPLE_DOUBLE;
|
||||
for (; __f != ResampleFilter::RESAMPLE_INVALID; __f++) {
|
||||
std::string _b = ResampleFilter::factor_label[__f];
|
||||
auto loc = _b.find_first_of(" ");
|
||||
if (loc != std::string::npos)
|
||||
_b = _b.erase(loc);
|
||||
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
|
||||
if (target_factor.compare(_b) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// invalid filter name
|
||||
if (__f == ResampleFilter::RESAMPLE_INVALID)
|
||||
return false;
|
||||
|
||||
// Apply if provided method name is different from current
|
||||
if (factor() != __f)
|
||||
setFactor(__f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ResampleFilter::draw (FrameBuffer *input)
|
||||
{
|
||||
bool forced = false;
|
||||
@@ -579,6 +606,34 @@ void BlurFilter::setMethod(int method)
|
||||
setProgram( programs_[ (int) method_] );
|
||||
}
|
||||
|
||||
bool BlurFilter::setMethod(const std::string &label)
|
||||
{
|
||||
std::string target_method = label;
|
||||
std::transform(target_method.begin(), target_method.end(), target_method.begin(), ::tolower);
|
||||
|
||||
// find method by name
|
||||
int __m = BlurFilter::BLUR_GAUSSIAN;
|
||||
for (; __m != BlurFilter::BLUR_INVALID; __m++) {
|
||||
std::string _b = BlurFilter::method_label[__m];
|
||||
auto loc = _b.find_first_of(" ");
|
||||
if (loc != std::string::npos)
|
||||
_b = _b.erase(loc);
|
||||
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
|
||||
if (target_method.compare(_b) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// invalid filter name
|
||||
if (__m == BlurFilter::BLUR_INVALID)
|
||||
return false;
|
||||
|
||||
// Apply if provided method name is different from current
|
||||
if (method() != __m)
|
||||
setMethod(__m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlurFilter::draw (FrameBuffer *input)
|
||||
{
|
||||
bool forced = false;
|
||||
@@ -684,6 +739,34 @@ void SharpenFilter::setMethod(int method)
|
||||
setProgram( programs_[ (int) method_] );
|
||||
}
|
||||
|
||||
bool SharpenFilter::setMethod(const std::string &label)
|
||||
{
|
||||
std::string target_method = label;
|
||||
std::transform(target_method.begin(), target_method.end(), target_method.begin(), ::tolower);
|
||||
|
||||
// find method by name
|
||||
int __m = SharpenFilter::SHARPEN_MASK;
|
||||
for (; __m != SharpenFilter::SHARPEN_INVALID; __m++) {
|
||||
// get first word of label, in lower case
|
||||
std::string _b = SharpenFilter::method_label[__m];
|
||||
auto loc = _b.find_first_of(" ");
|
||||
if (loc != std::string::npos)
|
||||
_b = _b.erase(loc);
|
||||
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
|
||||
if (target_method.compare(_b) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (__m == SharpenFilter::SHARPEN_INVALID)
|
||||
return false;
|
||||
|
||||
// Apply if provided method name is different from current
|
||||
if (method() != __m)
|
||||
setMethod(__m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SharpenFilter::draw (FrameBuffer *input)
|
||||
{
|
||||
// Default
|
||||
@@ -708,7 +791,7 @@ void SharpenFilter::accept (Visitor& v)
|
||||
////////////////////////////////////////
|
||||
|
||||
const char* SmoothFilter::method_label[SmoothFilter::SMOOTH_INVALID] = {
|
||||
"Bilateral", "Kuwahara", "Opening", "Closing", "Erosion", "Dilation", "Remove noise", "Add noise", "Add grain"
|
||||
"Bilateral", "Kuwahara", "Opening", "Closing", "Erosion", "Dilation", "Denoise", "Noise add", "Grain add"
|
||||
};
|
||||
|
||||
std::vector< FilteringProgram > SmoothFilter::programs_ = {
|
||||
@@ -733,6 +816,33 @@ void SmoothFilter::setMethod(int method)
|
||||
setProgram( programs_[ (int) method_] );
|
||||
}
|
||||
|
||||
bool SmoothFilter::setMethod(const std::string &label)
|
||||
{
|
||||
std::string target_method = label;
|
||||
std::transform(target_method.begin(), target_method.end(), target_method.begin(), ::tolower);
|
||||
|
||||
// find method by name
|
||||
int __m = SmoothFilter::SMOOTH_BILINEAR;
|
||||
for (; __m != SmoothFilter::SMOOTH_INVALID; __m++) {
|
||||
std::string _b = SmoothFilter::method_label[__m];
|
||||
auto loc = _b.find_first_of(" ");
|
||||
if (loc != std::string::npos)
|
||||
_b = _b.erase(loc);
|
||||
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
|
||||
if (target_method.compare(_b) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (__m == SmoothFilter::SMOOTH_INVALID)
|
||||
return false;
|
||||
|
||||
// Apply if provided method name is different from current
|
||||
if (method() != __m)
|
||||
setMethod(__m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SmoothFilter::draw (FrameBuffer *input)
|
||||
{
|
||||
// Default
|
||||
@@ -776,6 +886,33 @@ void EdgeFilter::setMethod(int method)
|
||||
setProgram( programs_[ (int) method_] );
|
||||
}
|
||||
|
||||
bool EdgeFilter::setMethod(const std::string &label)
|
||||
{
|
||||
std::string target_method = label;
|
||||
std::transform(target_method.begin(), target_method.end(), target_method.begin(), ::tolower);
|
||||
|
||||
// find method by name
|
||||
int __m = EdgeFilter::EDGE_SOBEL;
|
||||
for (; __m != EdgeFilter::EDGE_INVALID; __m++) {
|
||||
std::string _b = EdgeFilter::method_label[__m];
|
||||
auto loc = _b.find_first_of(" ");
|
||||
if (loc != std::string::npos)
|
||||
_b = _b.erase(loc);
|
||||
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
|
||||
if (target_method.compare(_b) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (__m == EdgeFilter::EDGE_INVALID)
|
||||
return false;
|
||||
|
||||
// Apply if provided method name is different from current
|
||||
if (method() != __m)
|
||||
setMethod(__m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EdgeFilter::draw (FrameBuffer *input)
|
||||
{
|
||||
// Default
|
||||
@@ -804,8 +941,8 @@ const char* AlphaFilter::operation_label[AlphaFilter::ALPHA_INVALID] = {
|
||||
};
|
||||
|
||||
std::vector< FilteringProgram > AlphaFilter::programs_ = {
|
||||
FilteringProgram("Chromakey","shaders/filters/chromakey.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0}, { "Threshold", 0.5}, { "Tolerance", 0.5} }),
|
||||
FilteringProgram("Lumakey", "shaders/filters/lumakey.glsl", "", { { "Luminance", 0.0}, { "Threshold", 0.5}, { "Tolerance", 0.5} } ),
|
||||
FilteringProgram("Chromakey","shaders/filters/chromakey.glsl", "", { { "Threshold", 0.5}, { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0}, { "Tolerance", 0.5} } ),
|
||||
FilteringProgram("Lumakey", "shaders/filters/lumakey.glsl", "", { { "Threshold", 0.5}, { "Luminance", 0.0}, { "Tolerance", 0.5} } ),
|
||||
FilteringProgram("coloralpha","shaders/filters/coloralpha.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0} } )
|
||||
};
|
||||
|
||||
@@ -819,6 +956,33 @@ void AlphaFilter::setOperation(int op)
|
||||
setProgram( programs_[ (int) operation_] );
|
||||
}
|
||||
|
||||
bool AlphaFilter::setOperation(const std::string &label)
|
||||
{
|
||||
std::string target_op = label;
|
||||
std::transform(target_op.begin(), target_op.end(), target_op.begin(), ::tolower);
|
||||
|
||||
// find method by name
|
||||
int __o = AlphaFilter::ALPHA_CHROMAKEY;
|
||||
for (; __o != AlphaFilter::ALPHA_INVALID; __o++) {
|
||||
std::string _b = AlphaFilter::operation_label[__o];
|
||||
auto loc = _b.find_first_of(" ");
|
||||
if (loc != std::string::npos)
|
||||
_b = _b.erase(loc);
|
||||
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
|
||||
if (target_op.compare(_b) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (__o == AlphaFilter::ALPHA_INVALID)
|
||||
return false;
|
||||
|
||||
// Apply if provided method name is different from current
|
||||
if (operation() != __o)
|
||||
setOperation(__o);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AlphaFilter::draw (FrameBuffer *input)
|
||||
{
|
||||
// Default
|
||||
|
||||
@@ -154,6 +154,7 @@ public:
|
||||
} ResampleFactor;
|
||||
static const char* factor_label[RESAMPLE_INVALID];
|
||||
ResampleFactor factor () const { return factor_; }
|
||||
bool setFactor(const std::string &label);
|
||||
void setFactor(int factor);
|
||||
|
||||
// implementation of FrameBufferFilter
|
||||
@@ -187,6 +188,7 @@ public:
|
||||
} BlurMethod;
|
||||
static const char* method_label[BLUR_INVALID];
|
||||
BlurMethod method () const { return method_; }
|
||||
bool setMethod(const std::string &label);
|
||||
void setMethod(int method);
|
||||
|
||||
// implementation of FrameBufferFilter
|
||||
@@ -221,6 +223,7 @@ public:
|
||||
} SharpenMethod;
|
||||
static const char* method_label[SHARPEN_INVALID];
|
||||
SharpenMethod method () const { return method_; }
|
||||
bool setMethod(const std::string &label);
|
||||
void setMethod(int method);
|
||||
|
||||
// implementation of FrameBufferFilter
|
||||
@@ -255,7 +258,10 @@ public:
|
||||
SMOOTH_INVALID
|
||||
} SmoothMethod;
|
||||
static const char* method_label[SMOOTH_INVALID];
|
||||
static std::vector< FilteringProgram > programs_;
|
||||
|
||||
SmoothMethod method () const { return method_; }
|
||||
bool setMethod(const std::string &label);
|
||||
void setMethod(int method);
|
||||
|
||||
// implementation of FrameBufferFilter
|
||||
@@ -266,7 +272,6 @@ public:
|
||||
|
||||
private:
|
||||
SmoothMethod method_;
|
||||
static std::vector< FilteringProgram > programs_;
|
||||
};
|
||||
|
||||
|
||||
@@ -286,6 +291,7 @@ public:
|
||||
} EdgeMethod;
|
||||
static const char* method_label[EDGE_INVALID];
|
||||
EdgeMethod method () const { return method_; }
|
||||
bool setMethod(const std::string &label);
|
||||
void setMethod(int method);
|
||||
|
||||
// implementation of FrameBufferFilter
|
||||
@@ -317,6 +323,7 @@ public:
|
||||
} AlphaOperation;
|
||||
static const char* operation_label[ALPHA_INVALID];
|
||||
AlphaOperation operation () const { return operation_; }
|
||||
bool setOperation(const std::string &label);
|
||||
void setOperation(int op);
|
||||
|
||||
// implementation of FrameBufferFilter
|
||||
|
||||
@@ -16,13 +16,18 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
**/
|
||||
#include <fstream>
|
||||
|
||||
#include "defines.h"
|
||||
#include "Source.h"
|
||||
#include "ImageProcessingShader.h"
|
||||
#include "CloneSource.h"
|
||||
#include "ImageFilter.h"
|
||||
#include "DelayFilter.h"
|
||||
#include "MediaSource.h"
|
||||
#include "MediaPlayer.h"
|
||||
#include "Visitor.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include "SourceCallback.h"
|
||||
|
||||
@@ -98,6 +103,9 @@ SourceCallback *SourceCallback::create(CallbackType type)
|
||||
case SourceCallback::CALLBACK_POSTERIZE:
|
||||
loadedcallback = new SetPosterize;
|
||||
break;
|
||||
case SourceCallback::CALLBACK_FILTER:
|
||||
loadedcallback = new SetFilter;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1086,3 +1094,217 @@ void SetGamma::accept(Visitor& v)
|
||||
SourceCallback::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SetFilter::SetFilter(const std::string &filter, const std::string &method, float value, float ms)
|
||||
: SourceCallback()
|
||||
, target_filter_(filter)
|
||||
, target_method_(method)
|
||||
, target_value_(value)
|
||||
, duration_(ms)
|
||||
{
|
||||
imagefilter = nullptr;
|
||||
delayfilter = nullptr;
|
||||
}
|
||||
|
||||
void SetFilter::update(Source *s, float dt)
|
||||
{
|
||||
SourceCallback::update(s, dt);
|
||||
CloneSource *clonesrc = dynamic_cast<CloneSource *>(s);
|
||||
|
||||
if (s->locked() || !clonesrc)
|
||||
status_ = FINISHED;
|
||||
|
||||
// apply when ready
|
||||
if (status_ == READY) {
|
||||
|
||||
///
|
||||
/// Set Filter
|
||||
///
|
||||
// convert target_filter_ to lower case to avoid mistakes
|
||||
std::transform(target_filter_.begin(),
|
||||
target_filter_.end(),
|
||||
target_filter_.begin(),
|
||||
::tolower);
|
||||
|
||||
if (!target_filter_.empty()) {
|
||||
// find filter type ID of the filter name provided, if valid
|
||||
size_t __t = FrameBufferFilter::FILTER_PASSTHROUGH;
|
||||
for (; __t != FrameBufferFilter::FILTER_INVALID; __t++) {
|
||||
// get first word of filter label, in lower case
|
||||
std::string _b = std::get<2>(FrameBufferFilter::Types[__t]);
|
||||
auto loc = _b.find_first_of(" ");
|
||||
if (loc != std::string::npos)
|
||||
_b = _b.erase(loc);
|
||||
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
|
||||
// end search if found same as target filter name (success)
|
||||
if (target_filter_.compare(_b) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Provided filter name is valid
|
||||
FrameBufferFilter::Type __type = FrameBufferFilter::Type(__t);
|
||||
if (__type != FrameBufferFilter::FILTER_INVALID) {
|
||||
// change filter if different from source
|
||||
if (clonesrc->filter()->type() != __type)
|
||||
clonesrc->setFilter(__type);
|
||||
} else
|
||||
Log::Info("Filter : unknown type '%s'", target_filter_.c_str());
|
||||
}
|
||||
|
||||
///
|
||||
/// Set Method
|
||||
///
|
||||
if (!target_method_.empty()) {
|
||||
// treat image filter types differently
|
||||
// ignore invalid or Nil types
|
||||
switch (clonesrc->filter()->type()) {
|
||||
case FrameBufferFilter::FILTER_RESAMPLE: {
|
||||
// get resamplig filter
|
||||
ResampleFilter *__f = dynamic_cast<ResampleFilter *>(clonesrc->filter());
|
||||
if ( !__f->setFactor(target_method_) )
|
||||
Log::Info("Filter Resample: unknown factor '%s'", target_method_.c_str());
|
||||
} break;
|
||||
case FrameBufferFilter::FILTER_BLUR: {
|
||||
// get blur filter
|
||||
BlurFilter *__f = dynamic_cast<BlurFilter *>(clonesrc->filter());
|
||||
if ( !__f->setMethod(target_method_) )
|
||||
Log::Info("Filter Blur: unknown method '%s'", target_method_.c_str());
|
||||
} break;
|
||||
case FrameBufferFilter::FILTER_SHARPEN: {
|
||||
// get sharpen filter
|
||||
SharpenFilter *__f = dynamic_cast<SharpenFilter *>(clonesrc->filter());
|
||||
if ( !__f->setMethod(target_method_) )
|
||||
Log::Info("Filter Sharpen: unknown method '%s'", target_method_.c_str());
|
||||
} break;
|
||||
case FrameBufferFilter::FILTER_SMOOTH: {
|
||||
// get smooth filter
|
||||
SmoothFilter *__f = dynamic_cast<SmoothFilter *>(clonesrc->filter());
|
||||
if (!__f->setMethod(target_method_))
|
||||
Log::Info("Filter Smooth: unknown method '%s'", target_method_.c_str());
|
||||
} break;
|
||||
case FrameBufferFilter::FILTER_EDGE: {
|
||||
// get edge filter
|
||||
EdgeFilter *__f = dynamic_cast<EdgeFilter *>(clonesrc->filter());
|
||||
if (!__f->setMethod(target_method_))
|
||||
Log::Info("Filter Edge: unknown method '%s'", target_method_.c_str());
|
||||
} break;
|
||||
case FrameBufferFilter::FILTER_ALPHA: {
|
||||
// get alpha filter
|
||||
AlphaFilter *__f = dynamic_cast<AlphaFilter *>(clonesrc->filter());
|
||||
if (!__f->setOperation(target_method_))
|
||||
Log::Info("Filter Alpha: unknown operation '%s'", target_method_.c_str());
|
||||
} break;
|
||||
case FrameBufferFilter::FILTER_IMAGE: {
|
||||
// Open the file
|
||||
std::ifstream file(target_method_);
|
||||
// Check if the file is opened successfully
|
||||
if (file.is_open()) {
|
||||
// Read the content of the file into an std::string
|
||||
std::string fileContent((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
FilteringProgram prog;
|
||||
prog.setName(target_method_);
|
||||
prog.setCode({fileContent, ""});
|
||||
// get alpha filter
|
||||
ImageFilter *__f = dynamic_cast<ImageFilter *>(clonesrc->filter());
|
||||
__f->setProgram(prog);
|
||||
}
|
||||
else
|
||||
Log::Info("Filter Custom: can't read file '%s'", target_method_.c_str());
|
||||
// Close the file
|
||||
file.close();
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// by default, consider it's over,
|
||||
status_ = FINISHED;
|
||||
|
||||
// ...but if a target value is given,
|
||||
if ( !std::isnan(target_value_) ){
|
||||
imagefilter = dynamic_cast<ImageFilter *>(clonesrc->filter());
|
||||
// ...and if there is a parameter to the filter
|
||||
if (imagefilter && imagefilter->program().parameters().size() > 0) {
|
||||
target_parameter_ = imagefilter->program().parameters().rbegin()->first;
|
||||
start_value_ = imagefilter->program().parameters().rbegin()->second;
|
||||
// then activate for value update
|
||||
status_ = ACTIVE;
|
||||
}
|
||||
// or maybe its a delay filter?
|
||||
else {
|
||||
delayfilter = dynamic_cast<DelayFilter *>(clonesrc->filter());
|
||||
if (delayfilter) {
|
||||
start_value_ = delayfilter->delay();
|
||||
// then activate for value update
|
||||
status_ = ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Set Value
|
||||
///
|
||||
|
||||
if (status_ == ACTIVE) {
|
||||
// time passed since start
|
||||
float progress = elapsed_ - delay_;
|
||||
// update ImageFilter types of filters
|
||||
if (imagefilter) {
|
||||
// time-out or instantaneous
|
||||
if (!(ABS(duration_) > 0.f) || progress > duration_) {
|
||||
// apply target value
|
||||
imagefilter->setProgramParameter(target_parameter_, target_value_);
|
||||
// done
|
||||
status_ = FINISHED;
|
||||
}
|
||||
else {
|
||||
// apply calculated intermediate value
|
||||
imagefilter->setProgramParameter(target_parameter_,
|
||||
glm::mix(start_value_,
|
||||
target_value_,
|
||||
progress / duration_));
|
||||
}
|
||||
}
|
||||
// update DelayFilter
|
||||
else if (delayfilter) {
|
||||
// time-out or instantaneous
|
||||
if (!(ABS(duration_) > 0.f) || progress > duration_) {
|
||||
// apply target value
|
||||
delayfilter->setDelay(target_value_);
|
||||
// done
|
||||
status_ = FINISHED;
|
||||
}
|
||||
else {
|
||||
// apply calculated intermediate value
|
||||
delayfilter->setDelay(glm::mix(start_value_, target_value_, progress / duration_));
|
||||
}
|
||||
}
|
||||
else
|
||||
status_ = FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
void SetFilter::multiply (float factor)
|
||||
{
|
||||
target_value_ *= factor;
|
||||
}
|
||||
|
||||
SourceCallback *SetFilter::clone() const
|
||||
{
|
||||
return new SetFilter(target_filter_,
|
||||
target_method_,
|
||||
target_value_,
|
||||
duration_);
|
||||
}
|
||||
|
||||
void SetFilter::accept(Visitor& v)
|
||||
{
|
||||
SourceCallback::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef SOURCECALLBACK_H
|
||||
#define SOURCECALLBACK_H
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Scene.h"
|
||||
@@ -48,7 +50,8 @@ public:
|
||||
CALLBACK_HUE,
|
||||
CALLBACK_THRESHOLD,
|
||||
CALLBACK_INVERT,
|
||||
CALLBACK_POSTERIZE
|
||||
CALLBACK_POSTERIZE,
|
||||
CALLBACK_FILTER
|
||||
} CallbackType;
|
||||
|
||||
static SourceCallback *create(CallbackType type);
|
||||
@@ -471,4 +474,37 @@ public:
|
||||
void accept (Visitor& v) override;
|
||||
};
|
||||
|
||||
class SetFilter : public SourceCallback
|
||||
{
|
||||
std::string target_filter_;
|
||||
std::string target_method_;
|
||||
std::string target_parameter_;
|
||||
float start_value_;
|
||||
float target_value_;
|
||||
float duration_;
|
||||
class ImageFilter *imagefilter;
|
||||
class DelayFilter *delayfilter;
|
||||
|
||||
public:
|
||||
SetFilter(const std::string &filter = std::string(),
|
||||
const std::string &method = std::string(),
|
||||
float value = NAN,
|
||||
float ms = 0.f);
|
||||
|
||||
std::string filter() const { return target_filter_; }
|
||||
void setFilter(const std::string &f) { target_filter_ = f; }
|
||||
std::string method() const { return target_method_; }
|
||||
void setMethod(const std::string &m) { target_method_ = m; }
|
||||
float value () const { return target_value_; }
|
||||
void setValue (float g) { target_value_ = g; }
|
||||
float duration () const { return duration_; }
|
||||
void setDuration (float ms) { duration_ = ms; }
|
||||
|
||||
void update (Source *s, float) override;
|
||||
void multiply (float factor) override;
|
||||
SourceCallback *clone () const override;
|
||||
CallbackType type () const override { return CALLBACK_FILTER; }
|
||||
void accept (Visitor& v) override;
|
||||
};
|
||||
|
||||
#endif // SOURCECALLBACK_H
|
||||
|
||||
@@ -313,4 +313,41 @@ void drawMediaPlayer()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// // get second argument : can be string, float or nothing
|
||||
// bool argloop = false;
|
||||
// while (!argloop) {
|
||||
// // work on copy of arguments
|
||||
// osc::ReceivedMessageArgumentStream __args = arguments;
|
||||
// // no argument
|
||||
// if (__args.Eos()) {
|
||||
// filter_arg_type = osc::NIL_TYPE_TAG;
|
||||
// argloop = true;
|
||||
// }
|
||||
// // try with float (last try)
|
||||
// if (filter_arg_type == osc::FLOAT_TYPE_TAG) {
|
||||
// try {
|
||||
// __args >> filter_value >> osc::EndMessage;
|
||||
// } catch (osc::WrongArgumentTypeException &) {
|
||||
// filter_arg_type = osc::NIL_TYPE_TAG;
|
||||
// }
|
||||
// // done!
|
||||
// argloop = true;
|
||||
// }
|
||||
// // try with string (first try)
|
||||
// if (filter_arg_type == osc::STRING_TYPE_TAG) {
|
||||
// try {
|
||||
// const char *m = nullptr;
|
||||
// __args >> m >> osc::EndMessage;
|
||||
// // done!
|
||||
// filter_method = std::string(m);
|
||||
// std::transform(filter_method.begin(),
|
||||
// filter_method.end(),
|
||||
// filter_method.begin(),
|
||||
// ::tolower);
|
||||
// argloop = true;
|
||||
// } catch (osc::WrongArgumentTypeException &) {
|
||||
// // next: try with float
|
||||
// filter_arg_type = osc::FLOAT_TYPE_TAG;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user