diff options
Diffstat (limited to 'rotord/rotor.h')
| -rwxr-xr-x | rotord/rotor.h | 79 |
1 files changed, 59 insertions, 20 deletions
diff --git a/rotord/rotor.h b/rotord/rotor.h index d5dc60e..e128fd5 100755 --- a/rotord/rotor.h +++ b/rotord/rotor.h @@ -2,6 +2,8 @@ nodes can have many inputs but only 1 output image nodes that use an image as input can pass on the incoming image only if its unchanged. + +TODO - parameter class that automatically links variable to correctly named inputs */ #include <unordered_map> @@ -210,6 +212,18 @@ namespace Rotor { } return *this; } + Image & add_wrap(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + for (int i=0;i<w*h*3;i++){ + //creates rainbow overload + RGBdata[i]=(unsigned char)(((int)other.RGBdata[i]+(int)RGBdata[i])); + } + } + return *this; + } Image * operator*(const float &amount) { Image *other=new Image(); other->setup(w,h); @@ -264,11 +278,7 @@ namespace Rotor { public: Parameter_input(const string &_param,const string &_desc): Signal_input(_desc),receiver(nullptr),parameter(_param){}; float *receiver; - void update(const Time_spec& time){ //gets input and updates variable - if (receiver){ - *receiver=((Signal_node*)connection)->get_output(time); - } - } + void update(const Time_spec& time); string parameter; }; class Node{ @@ -304,7 +314,8 @@ namespace Rotor { public: vector<Image_input*> image_inputs; //image node also has image inputs and outputs void create_image_input(const string &description) {image_inputs.push_back(new Image_input(description));}; - virtual Image *get_output(const Frame_spec &frame)=0; + Image *get_output(const Frame_spec &frame) { update_params((Time_spec)frame); return output(frame); }; + virtual const Image *output(const Frame_spec &frame)=0; Image *get_preview(const Frame_spec &frame); Image *image; //this can be privately allocated or just passed on as the node see fit private: @@ -382,6 +393,9 @@ namespace Rotor { if (_op=="<") op=COMPARISON_Less; if (_op==">=") op=COMPARISON_Greater_or_equal; if (_op=="<=") op=COMPARISON_Less_or_equal; + for (auto p:parameter_inputs){ + if (p->parameter=="value") p->receiver=&value; + } }; Comparison* clone(map<string,string> &_settings) { return new Comparison(_settings);}; const float output(const Time_spec &time) { @@ -432,6 +446,9 @@ namespace Rotor { if (_op=="*") op=ARITHMETIC_multiply; if (_op=="/") op=ARITHMETIC_divide; if (_op=="%") op=ARITHMETIC_modulo; + for (auto p:parameter_inputs){ + if (p->parameter=="value") p->receiver=&value; + } }; Arithmetic* clone(map<string,string> &_settings) { return new Arithmetic(_settings);}; const float output(const Time_spec &time) { @@ -468,6 +485,9 @@ namespace Rotor { Signal_divide(map<string,string> &settings) { base_settings(settings); divide_amount=ofToFloat(find_setting(settings,"amount")); + for (auto p:parameter_inputs){ + if (p->parameter=="divide_amount") p->receiver=÷_amount; + } }; Signal_divide* clone(map<string,string> &_settings) { return new Signal_divide(_settings);}; const float output(const Time_spec &time) { @@ -537,7 +557,7 @@ namespace Rotor { }; ~Testcard(){ delete image;}; Testcard* clone(map<string,string> &_settings) { return new Testcard(_settings);}; - Image *get_output(const Frame_spec &frame){ + Image *output(const Frame_spec &frame){ if (image->setup(frame.w,frame.h)) { } @@ -567,7 +587,7 @@ namespace Rotor { }; ~Invert(){ delete image;}; Invert* clone(map<string,string> &_settings) { return new Invert(_settings);}; - Image *get_output(const Frame_spec &frame){ + Image *output(const Frame_spec &frame){ if (inputs.size()) { if (image_inputs[0]->connection){ if (inputs[0]->connection) { @@ -602,7 +622,7 @@ namespace Rotor { exporter=new libav::Exporter(); }; ~Video_output(){ delete exporter; }; - Image *get_output(const Frame_spec &frame){ + Image *output(const Frame_spec &frame){ if (image_inputs[0]->connection) { return ((Image_node*)(image_inputs[0]->connection))->get_output(frame); } @@ -616,21 +636,21 @@ namespace Rotor { libav::Exporter *exporter; libav::Audioloader audioloader; }; - class Video_input: public Image_node { + class Video_loader: public Image_node { //video input using gstreamer //seems slow //TODO: scaling public: - Video_input(){}; - Video_input(map<string,string> &settings) { + Video_loader(){}; + Video_loader(map<string,string> &settings) { base_settings(settings); player=new ofGstVideoPlayer(); image=new Image(); }; - ~Video_input(){ delete player; delete image;}; + ~Video_loader(){ delete player; delete image;}; bool load(const string &filename); - Image *get_output(const Frame_spec &frame); - Video_input* clone(map<string,string> &_settings) { return new Video_input(_settings);}; + Image *output(const Frame_spec &frame); + Video_loader* clone(map<string,string> &_settings) { return new Video_loader(_settings);}; private: ofGstVideoPlayer *player; Image *image; @@ -644,7 +664,7 @@ namespace Rotor { }; ~Video_cycler(){}; bool load(const string &filename); - Image *get_output(const Frame_spec &frame){ + Image *output(const Frame_spec &frame){ int which_input=0; if (inputs[0]->connection) { which_input=((int)((Signal_node*)inputs[0]->connection)->get_output((Time_spec)frame))%image_inputs.size(); @@ -667,6 +687,13 @@ namespace Rotor { base_settings(settings); levels_settings(settings); image=new Image(); + for (auto p:parameter_inputs){ + if (p->parameter=="black_in") p->receiver=&black_in; + if (p->parameter=="white_in") p->receiver=&white_in; + if (p->parameter=="gamma") p->receiver=γ + if (p->parameter=="black_out") p->receiver=&black_out; + if (p->parameter=="white_out") p->receiver=&white_out; + } }; ~Luma_levels(){if (LUT) {delete[] LUT;} if (image) {delete image;} }; void levels_settings(map<string,string> &settings){ @@ -695,7 +722,7 @@ namespace Rotor { out.RGBdata[i]=LUT[in.RGBdata[i]]; } } - Image *get_output(const Frame_spec &frame){ + Image *output(const Frame_spec &frame){ if (image_inputs.size()) { if (image_inputs[0]->connection){ if (LUT) { @@ -710,7 +737,6 @@ namespace Rotor { protected: unsigned char *LUT; Image *image; - private: float black_in,white_in,gamma,black_out,white_out; }; class Echo_trails: public Luma_levels { @@ -751,9 +777,20 @@ namespace Rotor { levels_settings(settings); image=new Image(); lastframe=-1; + mode=find_setting(settings,"mode",0.0f); + for (auto p:parameter_inputs){ + if (p->parameter=="black_in") p->receiver=&black_in; + if (p->parameter=="white_in") p->receiver=&white_in; + if (p->parameter=="gamma") p->receiver=γ + if (p->parameter=="black_out") p->receiver=&black_out; + if (p->parameter=="white_out") p->receiver=&white_out; + + //TODO: control an integer + if (p->parameter=="mode") p->receiver=&mode; + } }; ~Echo_trails(){if (image) {delete image;} }; - Image *get_output(const Frame_spec &frame){ + Image *output(const Frame_spec &frame){ //check if cache is valid if (frame.w!=image->w||frame.h!=image->h){ //or framerate changed? //clear cache and start over @@ -801,7 +838,8 @@ namespace Rotor { //cerr<<"Rotor: about to apply image ("<<images[absframe].w<<"x"<<images[absframe].h<<")"<<endl; if (fless(fadeto,1.0f)){ Image *temp=*images[absframe]*((float)number/((fadeto*number)+((1.0-fadeto)*i))); - (*image)+=*temp; + if (mode<0.5) (*image)+=*temp; + else (*image)=image->add_wrap(*temp); delete temp; } else (*image)+=*images[absframe]; @@ -824,6 +862,7 @@ namespace Rotor { int number; int interval,total,lastframe; //number of frames between displayed echoes unordered_map<int,Image*> images; + float mode; //TODO make int, enum string parameter types }; //------------------------------------------------------------------- class Node_factory{ |
