Using ofThread to load Images

I created my own function that inherits from ofThread

#pragma once
#include "ofMain.h"
#include "Products.h"

ofImageThread.h:

class ImageThread: public ofThread {

public:

void threadedFunction(vector<Products> __suggestedProducts);
vector<ofImage> suggestedImages;
void start();
void stop();

private:

};

ofThreadedImage.cpp
void ImageThread::threadedFunction(vector<Products> __suggestedProducts){

while(isThreadRunning()){
    
    if(lock()){
        
        for (int i = 0; i < __suggestedProducts.size(); i++) {        
            
            ofImage tmp;
            suggestedImages.push_back(tmp);
            
            suggestedImages[i].loadImage(__suggestedProducts[i].productImgURL);
            cout << "WE ARE LOADING THE IMAGES IN A SEPARATE THREAD" << endl;
            
        }           
        unlock();            
    }else{         
        ofLogWarning("threadedFunction()") << "Unable to lock mutex.";
    }        
}

}

void ImageThread::start(){   
 startThread();
} 
void ImageThread::stop(){   
 stopThread();
}

I basically want to load images from a url. The products object gets populated at certain point and then it passes the url to load my images. And then in the ofApp.cpp I do this:

void ofApp::setup(){
    threadedImage.start()
{

 void ofApp::update(){
    if (lid.lidIsInBottle && families->returnFamilySelected() != -1 && runSuggestions) {
            int i = families->returnFamilySelected();
           
            suggestedProducts = returnProductSuggestions(notes[i]->products, bottledNotes);
            getRequestToURL();
            
            ///here we pass the object to the thread to load the images
           suggestedImages.threadedFunction(suggestedProducts);
           //we pass the element to a vector of Images. 
            testImages = threadedImage.suggestedImages;

           runSuggestions = false;// we make sure we run this only once, so we turn it off                
            
      
        }
 {

So when I run this. Nothing happens when I tried to draw the images:

 void ofApp::draw(){
    if (testImages.size() > 0){
        for (int i = 0; i < testImages.size(); i++) {
          testImages[i].draw(300, 300 + (i * 80));
          cout << "DRAWGING THE IMAGES SUGGESTED" << endl;
        }
      }
  }

Any idea of what I’m doing wrong here? Thanks.

You cannot do any OpenGL work outside of the main thread. When you call loadImage(...), internally the ofImage object automatically attempts to upload the pixels data into a texture on the graphics card (it does this using OpenGL). Since you are trying to do this in a thread outside of the main thread, it fails to upload the texture to the graphics card and without that you can’t draw it.

In addons like ofxIpVideoGrabber I start off by disabling texture use. See this:

Then once we’re back in the main thread (during the update() method) we load the pixels into a new ofImage, which uploads the texture to the graphics card. This can also be accomplished by calling the update() method on the ofImage that previously had setUseTexture(false);.

Also, double underscore name prefixes are generally reserved for the compiler’s internal use. In this case, it’s probably fine (and not the cause of the problem), but just be aware of it :wink:

Makes a lot of sense, and thanks for the tip in rewards of using double underscores :wink:

1 Like