diff options
| author | Tim Redfern <tim@herge.(none)> | 2013-05-10 17:51:45 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@herge.(none)> | 2013-05-10 17:51:45 +0100 |
| commit | 574c15ebe9989d079eee42b9cee4be19333fe24e (patch) | |
| tree | 7dedf5f80fa064b6661670cc014869bffcd9310e /rotord | |
| parent | ef8e5b1a427b473543fe3c38819d2cef4ee019b2 (diff) | |
echo trails almost working (?)
Diffstat (limited to 'rotord')
| -rwxr-xr-x | rotord/rotor.h | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/rotord/rotor.h b/rotord/rotor.h index 407d57c..60138fe 100755 --- a/rotord/rotor.h +++ b/rotord/rotor.h @@ -124,6 +124,8 @@ namespace Rotor { class Frame_spec: public Time_spec{ public: Frame_spec(float _time,float _framerate,int _w,int _h){ time=_time; framerate=_framerate; w=_w; h=_h;}; + Frame_spec(int _frame,float _framerate,int _w,int _h){ time=((float)_frame)/framerate; framerate=_framerate; w=_w; h=_h;}; + //float time; //this hould probably be implemented with a num/denom scheme eventually for accuracy //float framerate; int h,w; @@ -187,13 +189,20 @@ namespace Rotor { } return false; } + Image* clone(){ + Image *t=new Image(w,h); + for (int i=0;i<w*h*3;i++) { + t->RGBdata[i]=RGBdata[i]; + } + return t; + } Image & operator+=(const Image &other) { if (other.w!=w||other.h!=h) { - cerr<<"Rotor: cannot add images with different sizes!"<<endl; + 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++){ - RGBdata[i]+=other.RGBdata[i]; + RGBdata[i]=(unsigned char)(((int)other.RGBdata[i]+(int)RGBdata[i])&0x00FF); } } return *this; @@ -532,7 +541,7 @@ namespace Rotor { LUT=nullptr; generate_LUT(); } - void generate_LUT(){ + void generate_LUT(){ //check this if (LUT) delete[] LUT; LUT=new unsigned char[256]; float fltmax=(255.0f/256.0f); @@ -540,15 +549,20 @@ namespace Rotor { LUT[i]=(unsigned char)(((pow(min(fltmax,max(0.0f,(((((float)i)/256.0f)-black_in)/(white_in-black_in)))),(1.0/gamma))*(white_out-black_out))+black_out)*256.0f); } } + void apply_LUT(const Image& in){ + apply_LUT(in,*image); + } + void apply_LUT(const Image& in,Image &out){ //facility to apply to other images for ingherited classes + out.setup(in.w,in.h); + for (int i=0;i<out.w*out.h*3;i++){ + out.RGBdata[i]=LUT[in.RGBdata[i]]; + } + } Image *get_output(const Frame_spec &frame){ - image->setup(frame.w,frame.h); if (image_inputs.size()) { if (image_inputs[0]->connection){ if (LUT) { - Image *in= (((Image_node*)image_inputs[0]->connection)->get_output(frame)); - for (int i=0;i<frame.w*frame.h*3;i++){ - image->RGBdata[i]=LUT[in->RGBdata[i]]; - } + apply_LUT(*(((Image_node*)image_inputs[0]->connection)->get_output(frame))); return image; } } @@ -564,7 +578,7 @@ namespace Rotor { }; class Echo_trails: public Luma_levels { //draw trail frames additively that fade off over time - //the hard thing here is how to cache frames, if its done cleverly it could have no impact when + //the hard thing here is how to cache frames, if its done cleverly it could have no impact when //used linearly //Image needs to overload operator+ //need a clever data structure to cache frames - maybe a map of Image pointers @@ -598,17 +612,16 @@ namespace Rotor { number=find_setting(settings,"number",1); levels_settings(settings); image=new Image(); - w=h=0; + lastframe=-1; }; ~Echo_trails(){if (image) {delete image;} }; Image *get_output(const Frame_spec &frame){ - //cache frames - if (frame.w!=w||frame.h!=h){ //or framerate changed? + //check if cache is valid + if (frame.w!=image->w||frame.h!=image->h){ //or framerate changed? //clear cache and start over images.clear(); + lastframe=-1; //calculate frame interval - w=frame.w; - h=frame.h; interval=(int)((duration/number)*frame.framerate); total=interval*number; } @@ -623,15 +636,40 @@ namespace Rotor { ++i; } //if frame has already been calculated just return it - if (image) delete image; - if (image_inputs.size()) { - if (image_inputs[0]->connection){ - if (LUT) { - (*image)= *(((Image_node*)image_inputs[0]->connection)->get_output(frame)); - for (int i=0;i<frame.w*frame.h*3;i++){ - image->RGBdata[i]=LUT[in->RGBdata[i]]; + if (thisframe==lastframe) { + return image; + } + else { + if (image_inputs.size()) { + if (image_inputs[0]->connection){ + if (LUT) { + //copy incoming image **writable + image->free(); + image=(((Image_node*)image_inputs[0]->connection)->get_output(frame))->clone(); + for (int i=0;i<number;i++){ + //check echo frame isn't at negative time + int absframe=thisframe-(i*interval); + if (absframe>-1){ + //check if image is in the cache + if (images.find(absframe)==images.end()){ + //cerr<<"Rotor: preparing image ("<<image->w<<"x"<<image->h<<")"<<endl; + + images[absframe]=new Image(image->w,image->h); + //cerr<<"Rotor: prepared image ("<<images[absframe].w<<"x"<<images[absframe].h<<")"<<endl; + + Frame_spec wanted=Frame_spec(absframe,frame.framerate,frame.w,frame.h); + apply_LUT(*(((Image_node*)image_inputs[0]->connection)->get_output(wanted)),*images[absframe]); + } + //cerr<<"Rotor: about to apply image ("<<images[absframe].w<<"x"<<images[absframe].h<<")"<<endl; + (*image)+=*images[absframe]; + } + } + //for (int i=0;i<frame.w*frame.h*3;i++){ + // image->RGBdata[i]=LUT[in->RGBdata[i]]; + //} + lastframe=thisframe; + return image; } - return image; } } } @@ -640,9 +678,9 @@ namespace Rotor { Echo_trails* clone(map<string,string> &_settings) { return new Echo_trails(_settings);}; private: float duration; - int number,w,h; - int interval,total; //number of frames between displayed echoes - unordered_map<int,Image> images; + int number; + int interval,total,lastframe; //number of frames between displayed echoes + unordered_map<int,Image*> images; }; //------------------------------------------------------------------- class Node_factory{ |
