From b28a850a8ab4532ee425439446f5b4e01f9471a9 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Mon, 18 Sep 2017 22:32:45 +0100 Subject: threading working --- gui/src/chainImage.cpp | 34 ++++- gui/src/chainImage.h | 11 +- gui/src/chainImageSet.cpp | 240 ++++++++++++++++++++--------------- gui/src/chainImageSet.h | 18 ++- gui/src/ofApp.cpp | 5 +- gui/src/threadedChainImageLoader.cpp | 8 +- 6 files changed, 204 insertions(+), 112 deletions(-) (limited to 'gui') diff --git a/gui/src/chainImage.cpp b/gui/src/chainImage.cpp index 78731ba..d91a633 100644 --- a/gui/src/chainImage.cpp +++ b/gui/src/chainImage.cpp @@ -15,11 +15,19 @@ void chainImage::init(ofPoint _linkPos,float _linkScale,float _linkRot){ } void chainImage::start(bool reverse){ + transition=reverse?1.0f:0.0f; time=ofGetElapsedTimef(); setUseTexture(true); scale=reverse?linkScale*link->linkScale:linkScale; - + /* + printf("Started: %s: link %f current scale %f transition %f\n", + filename.c_str(), + linkScale, + scale, + transition + ); + */ } int chainImage::updateOutput(float decayRatio){ @@ -62,6 +70,13 @@ int chainImage::updateOutput(float decayRatio){ transition=-(scale-linkScale)/(linkScale-(linkScale*link->linkScale)); //transition=min(1.0f,((float)framecount)/totalframes); +/* + printf("ChainImage %f: scale %f linkscale %f transition %f \n", + decayRatio, + scale, + linkScale, + transition); + */ if (scale>linkScale){ transition = 0.0f; @@ -100,8 +115,11 @@ float chainImage::getRotation(){ return linkRot+(transition*link->linkRot); //linkRot+ }; void chainImage::makeThumbnail(){ + thumbnail.setUseTexture(false); thumbnail=(const ofImage)*this; //copy the ofImage itself + // thumbnail.setFromPixels(this->getPixels()); + float thumbheight=THUMB_SIZE; //ofGetWindowHeight()*THUMB_BORDER_RATIO; float thumbwidth=(thumbnail.getWidth()/thumbnail.getHeight())*thumbheight; @@ -114,6 +132,13 @@ void chainImage::makeThumbnail(){ borderwidth); thumbnail.resize(thumbwidth,thumbheight); + thumbnail.update(); + + printf("Rescaled %s: %fx%f\n", + filename.c_str(), + thumbnail.getWidth(), + thumbnail.getHeight() + ); thumbnail.setAnchorPoint(thumbnail.getWidth()/2,thumbnail.getHeight()/2); } @@ -186,4 +211,9 @@ bool chainImage::fromJson(Json::Value json){ } return false; } - +void chainImage::setupTextures(){ + setUseTexture(true); + update(); + thumbnail.setUseTexture(true); + thumbnail.update(); +} diff --git a/gui/src/chainImage.h b/gui/src/chainImage.h index 30a1cd2..367d051 100644 --- a/gui/src/chainImage.h +++ b/gui/src/chainImage.h @@ -20,20 +20,24 @@ class chainImage : public ofImage{ chainImage(){ link=NULL; ofImage(); + isLoaded=false; } void init(ofPoint _linkPos,float _linkScale,float _linkRot); void start(bool reverse=false); - bool load(std::string _filename){ + bool tload(std::string _filename){ + printf("tload : %s\n",_filename.c_str()); filename=_filename; if (ofImage::load(filename)){ makeThumbnail(); - + //could there be a way to load without committing the texture //setUseTexture(false); setAnchorPoint(getWidth()/2,getHeight()/2); + isLoaded=true; return true; } + else printf("could not load : %s\n",_filename.c_str()); return false; } @@ -47,6 +51,7 @@ class chainImage : public ofImage{ ofImage thumbnail; void makeThumbnail(); + void setupTextures(); Json::Value toJson(); bool fromJson(Json::Value json); @@ -66,6 +71,8 @@ class chainImage : public ofImage{ ofPolyline path; + bool isLoaded; + //int totalframes,framecount; }; diff --git a/gui/src/chainImageSet.cpp b/gui/src/chainImageSet.cpp index 5a538cb..7952d7c 100644 --- a/gui/src/chainImageSet.cpp +++ b/gui/src/chainImageSet.cpp @@ -8,6 +8,8 @@ void chainImageSet::drawOutput(){ camera_throw*=fitFactor; //fudge factor to allow tweening + //printf("Drawing chain: %i images\n",images.size()); + if (images.size()){ /* @@ -17,18 +19,26 @@ void chainImageSet::drawOutput(){ */ glMatrixMode ( GL_MODELVIEW ); glLoadIdentity ( ); - gluLookAt( currentImage->getTransform().x, - currentImage->getTransform().y, // i1.linkPos.y+(xform.y*intervalpoint), - currentImage->getWidth()*camera_throw*currentImage->getScale(), - currentImage->getTransform().x, - currentImage->getTransform().y, // i1.linkPos.y+(xform.y*intervalpoint), + glOrtho( + 0, + (*currentImage)->getTransform().x*2, + 0, + (*currentImage)->getTransform().y*2, + -100, + (*currentImage)->getTransform().x*4 + ); + gluLookAt( (*currentImage)->getTransform().x, + (*currentImage)->getTransform().y, // i1.linkPos.y+(xform.y*intervalpoint), + (*currentImage)->getWidth()*camera_throw*(*currentImage)->getScale(), + (*currentImage)->getTransform().x, + (*currentImage)->getTransform().y, // i1.linkPos.y+(xform.y*intervalpoint), 0, - sin(-currentImage->getRotation()*(PI/180)), - cos(-currentImage->getRotation()*(PI/180)), + sin(-(*currentImage)->getRotation()*(PI/180)), + cos(-(*currentImage)->getRotation()*(PI/180)), 0); - currentImage->drawChain(DEFAULT_FADEIN,additive,intensity); + (*currentImage)->drawChain(DEFAULT_FADEIN,additive,intensity); } @@ -53,42 +63,46 @@ void chainImageSet::drawGui(int x,int y,bool is_selected){ glTranslatef(x,y,0); - for(std::list::iterator ii=images.begin(); ii != images.end(); ii++){ + for(auto ii=images.begin(); ii != images.end(); ii++){ ofSetColor(255,255,255); - float thumbx=ii->thumbnail.getWidth()/2; - float thumby=ii->thumbnail.getHeight()/2; - float thumbscale=ii->thumbnail.getWidth()/ii->getWidth(); + float thumbx=(*ii)->thumbnail.getWidth()/2; + float thumby=(*ii)->thumbnail.getHeight()/2; + float thumbscale=(*ii)->thumbnail.getWidth()/(*ii)->getWidth(); //why do I have to set this every time?? - ii->thumbnail.setAnchorPercent(0.5,0.5); + (*ii)->thumbnail.setAnchorPercent(0.5,0.5); - ii->thumbnail.draw( - t_xoffs+borderwidth+thumbx, - borderwidth+thumby, - ii->thumbnail.getWidth(), - ii->thumbnail.getHeight() + if ((*ii)->thumbnail.isAllocated()){ + (*ii)->thumbnail.setUseTexture(true); + (*ii)->thumbnail.draw( + t_xoffs+borderwidth+thumbx, + borderwidth+thumby, + (*ii)->thumbnail.getWidth(), + (*ii)->thumbnail.getHeight() ); + } + ofSetColor(255,255,255); if (ii==selected) ofSetColor(255,0,0); - if (&(*ii)==currentImage) ofSetColor(0,255,0); + if (ii==currentImage) ofSetColor(0,255,0); ofDrawLine(t_xoffs+borderwidth,borderwidth, - t_xoffs+borderwidth+ii->thumbnail.getWidth(),borderwidth); - ofDrawLine(t_xoffs+borderwidth+ii->thumbnail.getWidth(),borderwidth, - t_xoffs+borderwidth+ii->thumbnail.getWidth(),borderwidth+ii->thumbnail.getHeight()); - ofDrawLine(t_xoffs+borderwidth+ii->thumbnail.getWidth(),borderwidth+ii->thumbnail.getHeight(), - t_xoffs+borderwidth,borderwidth+ii->thumbnail.getHeight()); - ofDrawLine(t_xoffs+borderwidth,borderwidth+ii->thumbnail.getHeight(), + t_xoffs+borderwidth+(*ii)->thumbnail.getWidth(),borderwidth); + ofDrawLine(t_xoffs+borderwidth+(*ii)->thumbnail.getWidth(),borderwidth, + t_xoffs+borderwidth+(*ii)->thumbnail.getWidth(),borderwidth+(*ii)->thumbnail.getHeight()); + ofDrawLine(t_xoffs+borderwidth+(*ii)->thumbnail.getWidth(),borderwidth+(*ii)->thumbnail.getHeight(), + t_xoffs+borderwidth,borderwidth+(*ii)->thumbnail.getHeight()); + ofDrawLine(t_xoffs+borderwidth,borderwidth+(*ii)->thumbnail.getHeight(), t_xoffs+borderwidth,borderwidth); ofSetColor(255,255,255); - if (ii->link){ - ofPoint lp=ii->linkPos; + if ((*ii)->link){ + ofPoint lp=(*ii)->linkPos; if (ii==selected){ lp+=dragPoint; } @@ -99,7 +113,7 @@ void chainImageSet::drawGui(int x,int y,bool is_selected){ ofDrawLine( subpictx, subpicty, - t_xoffs+(borderwidth*3)+ii->thumbnail.getWidth(), + t_xoffs+(borderwidth*3)+(*ii)->thumbnail.getWidth(), borderwidth+thumby ); @@ -108,38 +122,40 @@ void chainImageSet::drawGui(int x,int y,bool is_selected){ glTranslatef(subpictx,subpicty,0); - float r=ii->linkRot; + float r=(*ii)->linkRot; if (ii==selected) r+=dragRotate; glRotatef(r,0,0,1); //printf("Sub image: centre at %f,%f \n",ii->link->thumbnail.getAnchorPoint().x,ii->link->thumbnail.getAnchorPoint().y); - ii->link->thumbnail.setAnchorPercent(0.5,0.5); + (*ii)->link->thumbnail.setAnchorPercent(0.5,0.5); - float thescale=ii->linkScale; + float thescale=(*ii)->linkScale; if (ii==selected){ thescale*=(1.0f+dragScale); } - - ii->link->thumbnail.draw( - 0, - 0, - ii->link->thumbnail.getWidth()*thescale, - ii->link->thumbnail.getHeight()*thescale - ); + if ((*ii)->link->thumbnail.isAllocated()){ + + (*ii)->link->thumbnail.draw( + 0, + 0, + (*ii)->link->thumbnail.getWidth()*thescale, + (*ii)->link->thumbnail.getHeight()*thescale + ); + } ofPoint p1=ofPoint( - -(ii->link->thumbnail.getWidth()*thescale*0.5), - -(ii->link->thumbnail.getHeight()*thescale*0.5)); + -((*ii)->link->thumbnail.getWidth()*thescale*0.5), + -((*ii)->link->thumbnail.getHeight()*thescale*0.5)); ofPoint p2=ofPoint( - (ii->link->thumbnail.getWidth()*thescale*0.5), - -(ii->link->thumbnail.getHeight()*thescale*0.5)); + ((*ii)->link->thumbnail.getWidth()*thescale*0.5), + -((*ii)->link->thumbnail.getHeight()*thescale*0.5)); ofPoint p3=ofPoint( - (ii->link->thumbnail.getWidth()*thescale*0.5), - (ii->link->thumbnail.getHeight()*thescale*0.5)); + ((*ii)->link->thumbnail.getWidth()*thescale*0.5), + ((*ii)->link->thumbnail.getHeight()*thescale*0.5)); ofPoint p4=ofPoint( - -(ii->link->thumbnail.getWidth()*thescale*0.5), - (ii->link->thumbnail.getHeight()*thescale*0.5)); + -((*ii)->link->thumbnail.getWidth()*thescale*0.5), + ((*ii)->link->thumbnail.getHeight()*thescale*0.5)); ofDrawLine(p1,p2); ofDrawLine(p2,p3); @@ -153,7 +169,7 @@ void chainImageSet::drawGui(int x,int y,bool is_selected){ } - t_xoffs+=ii->thumbnail.getWidth()+(borderwidth*2); + t_xoffs+=(*ii)->thumbnail.getWidth()+(borderwidth*2); } @@ -181,21 +197,24 @@ attempt to add file to chain. find if file exists in data folder if not make a symbolic link */ - chainImage *image=new chainImage(); // - - loadingImages.push_back(image); - - loader.loadFromDisk(*image,"bogwaterreeds/IMG_9819.JPG"); //filename); + auto image=std::make_unique(); - //if (image.load(filename)){ - image->init(ofPoint(0,0), - currentDefaultImageRatio, + 0.3, //currentDefaultImageRatio, 0 //default rotation ); - printf("Loading file: %s at %f,%f \n",filename.c_str(),pos.x,pos.y); + printf("Loading file: %s linkscale %f\n", + filename.c_str(), + image->linkScale); + + loader.loadFromDisk(*image,filename); + + loadingImages.push_back(std::move(image)); + //if (image.load(filename)){ + + //loadingImages.push_back(image); @@ -223,16 +242,16 @@ void chainImageSet::keyPressed(ofKeyEventArgs &keyargs){ } break; case OF_KEY_UP: - selected->linkPos.y--; + (*selected)->linkPos.y--; break; case OF_KEY_DOWN: - selected->linkPos.y++; + (*selected)->linkPos.y++; break; case OF_KEY_LEFT: - selected->linkPos.x--; + (*selected)->linkPos.x--; break; case OF_KEY_RIGHT: - selected->linkPos.x++; + (*selected)->linkPos.x++; break; case OF_KEY_BACKSPACE:{ images.clear(); @@ -300,15 +319,15 @@ void chainImageSet::keyPressed(ofKeyEventArgs &keyargs){ void chainImageSet::mouseDragged(int x, int y, int button){ switch (button){ case OF_MOUSE_BUTTON_1: - dragPoint=ofPoint(x-clickPoint.x,y-clickPoint.y)*(selected->getHeight()/ofGetWindowHeight()); + dragPoint=ofPoint(x-clickPoint.x,y-clickPoint.y)*((*selected)->getHeight()/ofGetWindowHeight()); break; case OF_MOUSE_BUTTON_2: //alt-click - dragRotate=((clickPoint.x-x)/(selected->thumbnail.getWidth()))*180.0f; + dragRotate=((clickPoint.x-x)/((*selected)->thumbnail.getWidth()))*180.0f; break; case OF_MOUSE_BUTTON_3: //control-click - dragScale=(y-clickPoint.y)/(selected->thumbnail.getHeight()); + dragScale=(y-clickPoint.y)/((*selected)->thumbnail.getHeight()); //if (dragScale*selected->linkScale<0.15){ // dragScale=0.15/selected->linkScale; //} @@ -325,11 +344,11 @@ void chainImageSet::mousePressed(int x, int y, int button){ //-------------------------------------------------------------- void chainImageSet::mouseReleased(int x, int y, int button){ if (images.size()){ - selected->linkPos+=dragPoint; + (*selected)->linkPos+=dragPoint; dragPoint=ofPoint(0,0); - selected->linkScale*=(1.0f+dragScale); + (*selected)->linkScale*=(1.0f+dragScale); dragScale=0.0f; - selected->linkRot+=dragRotate; + (*selected)->linkRot+=dragRotate; dragRotate=0.0f; } } @@ -339,8 +358,8 @@ bool chainImageSet::saveJson(std::string filename){ json["images"] = Json::Value(Json::arrayValue); - for(std::list::iterator ii=images.begin(); ii != images.end(); ii++){ - json["images"].append(ii->toJson()); + for(auto ii=images.begin(); ii != images.end(); ii++){ + json["images"].append((*ii)->toJson()); } @@ -356,23 +375,23 @@ bool chainImageSet::loadJson(std::string _filename){ images.clear(); for (int i=0;i(); + if (image->fromJson(json["images"][i])){ + images.push_back(std::move(image)); } } - for (std::list::iterator ii=images.begin(); ii != images.end(); ii++){ + for (auto ii=images.begin(); ii != images.end(); ii++){ auto li=ii; li++; if (li==images.end()) { li=images.begin(); } - ii->link=&(*li); + (*ii)->link=&(*(*li)); } selected=images.begin(); - currentImage=&(*images.begin()); - currentImage->start(); + currentImage=images.begin(); + (*currentImage)->start(); filename=_filename; return true; @@ -386,33 +405,41 @@ void chainImageSet::updateOutput(){ for (auto i=loadingImages.begin();i!=loadingImages.end();){ - printf("Checking loadingImage: %s\n",(*i)->filename.c_str()); + //printf("Checking loadingImage: %s\n",(*i)->filename.c_str()); - if ((*i)->isAllocated()){ - printf("Finished loadingImage: %s\n",(*i)->filename.c_str()); + if ((*i)->isLoaded){ + printf("Finished loadingImage: %s, linkscale %f\n", + (*i)->filename.c_str(), + (*i)->linkScale + ); - images.push_back(*(*i)); - (*images.rbegin()).link=&(*images.begin()); + images.push_back(std::move(*i)); + (*images.rbegin())->link=&(*(*images.begin())); + (*images.rbegin())->setUseTexture(true); printf("Linked: %s to %s\n", - images.rbegin()->filename.c_str(), - images.begin()->filename.c_str()); + (*images.rbegin())->filename.c_str(), + (*images.rbegin())->link->filename.c_str()); if (images.size()>1){ - (++images.rbegin())->link=&(*(images.rbegin())); + (*(++images.rbegin()))->link=&(*(*images.rbegin())); printf("Linked: %s to %s\n", - (++images.rbegin())->filename.c_str(), - images.rbegin()->filename.c_str()); + (*(++images.rbegin()))->filename.c_str(), + (*(++images.rbegin()))->link->filename.c_str()); } else { selected=images.begin(); - currentImage=&(*images.begin()); - currentImage->start(); + currentImage=images.begin(); + (*currentImage)->start(); + } loadingImages.erase(i); + printf("Images: %i loadingImages %i\n", + images.size(), + loadingImages.size()); } else i++; @@ -420,31 +447,44 @@ void chainImageSet::updateOutput(){ if (images.size()){ - int switchResponse=currentImage->updateOutput(decayFactor); + int switchResponse=(*currentImage)->updateOutput(decayFactor); + switch(switchResponse){ case SWITCH_FORWARD:{ - currentImage=currentImage->link; - currentImage->start(); - ofLogNotice() << "Switched images forward"; - currentImage->updateOutput(decayFactor); + + currentImage++; + + if (currentImage==images.end()){ + currentImage=images.begin(); + } + + ofLogNotice() << "Switched image forward to " << (*currentImage)->filename; + + + (*currentImage)->start(); + (*currentImage)->updateOutput(decayFactor); + break; } case SWITCH_NONE: break; case SWITCH_REVERSE:{ - for (auto ii=images.begin();ii!=images.end();++ii){ - if (ii->link->filename==currentImage->filename){ - currentImage=&(*ii); - currentImage->start(true); - ofLogNotice() << "Switched images reverse"; - currentImage->updateOutput(decayFactor); - break; - } + + if (currentImage==images.begin()){ + currentImage=images.end(); } + + currentImage--; + + (*currentImage)->start(); + ofLogNotice() << "Switched images backward to " << (*currentImage)->filename; + (*currentImage)->updateOutput(decayFactor); break; + } } } + } diff --git a/gui/src/chainImageSet.h b/gui/src/chainImageSet.h index 87b1d11..b7bf868 100644 --- a/gui/src/chainImageSet.h +++ b/gui/src/chainImageSet.h @@ -7,6 +7,8 @@ class chainImageSet{ public: chainImageSet(){ + } + void init(){ currentDefaultImageRatio=0.3; filename=""; outputSize=ofPoint(1024,576); @@ -35,11 +37,19 @@ class chainImageSet{ ofPoint outputSize; - std::list images; + std::list > images; float currentDefaultImageRatio; - std::list::iterator selected; + //how to make selected and currentimage work if images is a list of unique_ptr? + //req: + //A: a container for images + //B: a temporary container for images that are loading + //be able to transfer images from B to A + //C: an iterator to A + //be able to loop through C and identify an element which is pointed to by C + + std::list >::iterator selected; ofPoint clickPoint; ofPoint dragPoint; float dragScale; @@ -48,14 +58,14 @@ class chainImageSet{ std::string filename; - chainImage *currentImage; + std::list >::iterator currentImage; float decayFactor; bool additive; float intensity; - std::vector < std::unique_ptr > loadingImages; + std::vector > loadingImages; threadedChainImageLoader loader; }; \ No newline at end of file diff --git a/gui/src/ofApp.cpp b/gui/src/ofApp.cpp index 2e8fe90..3cc4878 100644 --- a/gui/src/ofApp.cpp +++ b/gui/src/ofApp.cpp @@ -38,6 +38,9 @@ void ofApp::setup(){ sets.push_back(chainImageSet()); sets.push_back(chainImageSet()); selected_set=0; + + sets[0].init(); + sets[1].init(); } //-------------------------------------------------------------- @@ -71,7 +74,7 @@ void ofApp::draw(){ void ofApp::drawOutput(ofEventArgs & args){ ofBackground(0,0,0); -for (int i=0;iload(entry.filename) ) { + if(entry.image->tload(entry.filename) ) { + ofLogNotice() << "Loaded " << entry.image->filename; + images_to_update.send(entry); }else{ ofLogError("threadedChainImageLoader") << "couldn't load file: \"" << entry.filename << "\""; @@ -92,8 +95,7 @@ void threadedChainImageLoader::update(ofEventArgs & a){ // Load 1 image per update so we don't block the gl thread for too long chainImageLoaderEntry entry; if (images_to_update.tryReceive(entry)) { - entry.image->setUseTexture(true); - entry.image->update(); + entry.image->setupTextures(); } } -- cgit v1.2.3