How to run update() and draw() in keyPressed() event

Hi all,

I have used Processing and recently moved into ofx.
I am wondering is it possible to call update() and draw() function in the KeyPressed event, such as the code below.

void testApp::update(){
someUpdateFunction();
}

void testApp::draw(){
someDrawFunction();
}

void testApp::keyPressed(int key) {
switch (key) {
case ‘1’:
draw();
update();
break;
}

Thanks!

Hey @hydro,

It’s good practice to leave update() and draw() to run automatically in the application’s main thread.

If you want to limit your drawing and updating, use boolean functions in your code.

You can disable clearing the screen every frame by calling in ofSetBackgroundAuto(false) in setup()

And then …

void testApp::update(){
       if (bUpdateUpdate){
          someUpdateFunction();
          bUpdateUpdate = false;
      }
}

void testApp::draw(){
    if (bUpdateDraw){
           someDrawFunction();
           bUpdateDraw = false;
    }
}

Thanks for your quick answer Mantissa.
It’s good to know the ofSetBackgroundAuto(false) method.

Drawing in the key event would be useful for quick testing with key event.
Sometimes it’s tedius to set global variables on the header file and implement functions in the cpp file… I think I just have to get used to the new environment.

Thanks again for sharing your thoughts.

@hydro, there’s always multiple ways to approach a task

if you call your draw functions in keyPressed, you would achieve the same effect (as long as background clearing is disabled),

Mantissa,

I set the ofSetBackgroundAuto function and tested with the following code.

for(int i =0; i< 100; i++){
            if(i %10 == 0 ) {
                world.update();
                draw();
            }
        }

I was expecting it updates the scene each time draw() is called but nothing happened.
Probably draw() cannot be called in the for loop?

@hyro, what are you doing within draw()?

i think this approach wouldn’t work, you would only see the results of the last call to draw(). also calling draw() there is actually redundant, since draw() is being called automatically every frame.

if you want to limit when shapes are being drawn, i recommend creating a different function to draw into your world or, again, use booleans in your draw function().

Mantissa,

Sorry my code was not clear.
Not in the draw() but I was trying to call draw() in a for loop in the keyPressed event.

    void testApp::keyPressed(int key) {
    switch (key) {
    case ' ':
      for(int i=0 i < 100; i++){
           if(i % 10 == 0)
            someUpdateFunction();
            draw();
           }
          break;
    }
}

@hyro,

if you’re trying to limit drawing to a given event, try doing that drawing in a separate function. the idea is that, with background clearing disabled, you treat the OpenGL window as a buffer that accumulates all of the shapes that you draw into it. every time you call that separate function to draw additional shapes, they will build up on screen.

void drawShapes(){

  ofSetColor( ofRandom(255), ofRandom(255), ofRandom(255)); 
  ofEllipse( ofRandom(ofGetWidth(), ofRandom(ofGetHeight), 30, 30);

}

note that in the code your shared, because of the ‘break’ statement, that someUpdateFunction() is only running once. also is there any reason to have a for loop with that modulo test in it? why not just count to 10 if you want to draw 10 shapes?

void testApp::keyPressed(int key) {
     switch (key) {
         case ' ':
              for(int i=0 i < 100; i++){
                 if(i % 10 == 0){
                     drawShapes();
                 }
              }
              break;
      }
}