Draw first frame only

I’m trying to get recreate functionality similar to processing’s noLoop() function. I understand that there is no real way to stop the drawing loop, which is fine, but I’m doing a calculation that seems to take much more than a frame to complete and I only need to do it once. Here’s my code:

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();

    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);

    bool drawEnabled;
};
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    drawEnabled = true;
    ofSetBackgroundAuto(false);
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
    if (drawEnabled) {
        for (float x = 0; x < ofGetWidth(); x++) {
            for (float y = 0; y < ofGetHeight(); y++) {
                float xOff = x / ofGetWidth();
                float yOff = y / ofGetHeight();

                int color = ofNoise(xOff, yOff) * 255;
                ofSetColor(color, color, color);

                ofDrawRectangle(x, y, 1, 1);
            }
        }
        drawEnabled = false;
    }
    cout << ofGetFrameNum() << endl;
}

...

Some observations:

Since this code seems to run longer than one frame, what seems to happen is 1 frame goes by, the drawing isn’t complete yet, so OF skips to the next frame, disabling drawEnabled, resulting in a grey screen.

If I remove the drawEnabled check, my noise does draw after a few frames, but then continues to try and draw throughout the life of the program, which is what I’m trying to avoid.

Any thoughts? How can I get this to draw once and once only?

Oops sorry for the previous post.

For such jobs, I use ofxFBOTexture addon. I draw the stuff onto the ofxFBOTexture once, then I draw it on the screen when it is needed.

you can also use plain ofFbo, ofxFboTexture is really old and was deprecated once ofFbo was in the core.

in any case i think what you are seeing is that openFrameworks as opposed to processing clears the background automatically so you don’t see the drawing cause it’s deleted after the first frame.

you can disable auto background clearing calling ofSetBackgroundAuto(false) in setup

Thank you both for the replies!

@arturo I’ve set ofSetBackgroundAuto to false already but is hasn’t seemed to have helped. I’ll check out ofFbo.

the ofFbo worked great! For future reference for anyone else trying to solve a similar problem, here’s my relevant code:

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();

// --- omitted method definitions ---

    ofFbo buffer;
};
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    buffer.allocate(ofGetWidth(), ofGetHeight());
    buffer.begin();
        for (float x = 0; x < ofGetWidth(); x++) {
            for (float y = 0; y < ofGetHeight(); y++) {
                float xOff = x / ofGetWidth();
                float yOff = y / ofGetHeight();

                int color = ofNoise(xOff, yOff) * 255;
                ofSetColor(color);

                ofDrawRectangle(x, y, 1, 1);
            }
        }
    buffer.end();
}

//--------------------------------------------------------------
void ofApp::draw(){
    buffer.draw(0, 0);
}

Ok I must confess that we still use oF 0.8.0 :slightly_smiling:
But we switch to 0.8.4 this week :slightly_smiling: