Need help with multi-layer drawing?

Hi,

I hope you’re all doing fine.

I have a background that is redrawn/updated each frame. It shows a vector flow field.

On top of that I want to draw particle trails, one trail segment/line each frame for every particle.

And on top of these some text information should be displayed that is also updated each frame.

The code for each separate layer already works, however I have some trouble drawing everything superimposed!

For the middle layer - the particle trails - I’ve turned the background redrawing off in ofApp::setup(), since otherwise my the trail segments get overdrawn each frame, which I don’t want.
However, this causes the top and bottom layers to not refresh anymore (since the background doesn’t overwrite the previously drawn information).

Now, in a second attempt, I’ve made a FBO for each of the three layers.
However, I need to clear the bottom and top layer on a frame-by-frame basis, which doesn’t seem to be possible? At least, fbo.clear() and ofClear() don’t seem to work like that.

How can I make this work?

1 Like

fbo.clear() is for clearing fbo settings.
Instead, you can use ofClear() or ofBackground() to background color. For example,
‘’’
// 1st layer
fbo1.begin();
ofClear(255);
// draw something
fbo1.end();

// 2nd layer
fbo2.begin();
// ofClear();. // do not clear to paint over prev frame
// draw something
fbo2.end()

1 Like

Oups, I’ve coded a quick example before I saw your answer hrs !
Here it is anyway. You can use a FBO only for the middle layer.

#pragma once
#include "ofMain.h"

class ofApp : public ofBaseApp
{
public:
    void setup() ;
    void draw() ;
    ofFbo fbo;
} ;
#include "ofApp.h"

void ofApp::setup()
{
    fbo.allocate( ofGetWidth(), ofGetHeight() ) ;
    // Start with an empty fbo
    fbo.begin() ;
    ofClear( 0, 0, 0, 0 ) ;
    fbo.end() ;
}

void ofApp::draw()
{
    float t = ofGetElapsedTimef() / 4.f ;
    float w = ofGetWidth() ;
    float h = ofGetHeight() ;

    // Entirely redraw a red curve to the screen, each frame
    ofSetColor( 255, 0, 0 ) ;
    for( float o = 0.f; o < 0.4f; o += 0.005f)
        ofDrawCircle( ofNoise( t + o, 0.f ) * w, ofNoise( t + o, 1.f ) * h, 2.f ) ;

    // Add a single plot to a yellow curve, in the fbo
    fbo.begin() ;
    ofSetColor( 255, 255, 0 ) ;
    ofDrawCircle( ofNoise( t, 2.f ) * w, ofNoise( t, 3.f ) * h, 2.f ) ;
    fbo.end() ;

    // Draw the yellow curve to screen
    ofSetColor( 255 ) ;
    fbo.draw( 0.f, 0.f ) ;

    // Draw text on top of the drawings
    ofDrawBitmapString( "FPS:" + ofToString( ofGetFrameRate()), 10.f, 20.f );
}

2020-11-25-01-26-57

2 Likes

@diff-arch,

you can look also into: https://openframeworks.cc/documentation/graphics/ofGraphics/#!show_ofEnableAlphaBlending
and some of the OF/examples/gl like alphaMaskingShaderExample.

ofFbo has an alpha mode too:
fbo.allocate(400, 400, GL_RGBA); // with alpha, 8 bits red, 8 bits green, 8 bits blue, 8 bits alpha, from 0 to 255 in 256 steps

PS:
Not lightweight and raw solutions but:
Personally, when using multiple drawing layers (video, 3d, text, etc), and to allow different blend modes without having to know OpenGL tunning or to code glsl manually, I used some addons like these ones:




2 Likes

Thanks @hrs, @lilive, and @moebiussurfing.

I think I understand the drawing mechanism a little better now. I wish the documentation was a little more beginner friendly and descriptive at times. I’ve read through most of ofBook, but many things remain a big mystery. :slight_smile:

I wish the documentation was a little more beginner friendly and descriptive at times.

Me too ! This is sometimes quite time consuming to understand some basic features. But I guess the call to donations at the download page is not enough to support a full documentation development.

1 Like