ofImage/ofFbo not persistent [solved]

Hi all,

quite possibly this is a dumb question, anyway I’d be happy if you could help.

I use multiple text blocks, the drawing of which is quite expensive. Because the Text does not change during runtime (and the text blocks are not really big in pixel size), I want to draw the text blocks only once, store the outcome in images and then draw only these images when needed. Seemed easy: I tried using a vector of fbos - one per text. To my surprise the fbo just showed up very shortly and vanished again. I then tried to transfer the content of an fbo to ofImage. Same result.

ofApp.h:

vector <ofFbo> fontFbo;
vector <ofImage> fontImage;
vector <bool> fontImageInited;

setup():

fontFbo.resize(svgForms.size());
fontImageInited.resize(fontFbo.size());
fontImage.resize(fontFbo.size());
for (int i=0; i < fontFbo.size(); i++) {
	fontFbo[i].allocate(fontFboWith, fontFboHeight, GL_RGBA);
}

draw():

			if (!fontImageInited [i]) {
				// this is done only one (first) time per text block
				fontFbo[i].begin();
				fontFbo[i].clear();
				   ... do the actual drawing ...
				fontFbo[i].end();

				// second try: transfer fbo to ofImage
				ofPixels tempPixels;
				tempPixels.allocate(fontFboWith, fontFboHeight, OF_IMAGE_COLOR_ALPHA);
				fontFbo[i].readToPixels(tempPixels);
				fontImage[i].setFromPixels(tempPixels);
				// tried with and without fontImage[i].update();
				fontImageInited[i] = true;
			}

			// draw fbo/image containing font
			ofSetColor(255, 255, 255, 255);
			//fontFbo[i].draw(0, 0);
			fontImage[i].draw(0, 0);

I don’t understand why the image is not persistent while an ofImage using load() in setup is.
Am I missing something?

Thanks for any hint!
oe

I don’t think you need the images. With the fontFbo[i].draw(0, 0); it should be working. No need to download to RAM.

Besides the fontFbos, are you using another fbo for drawing? You should also call ofClear(0) in there

Also, check out armadillu’s ofxFontStash

Hi chuckleplant.

thanks for answering! In fact I do use oxfFontStash, still framerate goes down to 20 fps from around 140 when I have a fair ammount of text written. Might be a poblem too, but this would be another post.
I am glad to hear that it should work (and I am not just supid). Only it doesn’t. I prepared an app to reproduce the issue (only one fbo involved, no ofImage). Note the framerate set to 1 so that you can better see:

ofApp.h:

#pragma once
#include "ofMain.h"

class ofApp : public ofBaseApp{
	public:
		void setup();
		void update();
		void draw();

		ofFbo fbo;
		bool imageInited;
};

ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
	ofBackground(0);
	imageInited = false;
	fbo.allocate(800, 600, GL_RGBA);
	ofSetFrameRate(1);
	ofLogNotice("---- setup ----");
}

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

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

	if (!imageInited) {
		ofLogNotice("---- initing ----");
		fbo.begin();
		fbo.clear();
		ofBackground(0);
		ofSetColor(150, 200, 120);
		ofDrawCircle(200, 200, 100);
		fbo.end();
		imageInited = true;
	}
    ofLogNotice("---- drawing ----");
	fbo.draw(0,0);
}

Tried this code on Windows 10 OF 0.9.4 vs and Ubuntu 14.04. OF 0.9.8. Outcome is the same. First frame is drawing the fbo, next frame fbo is gone.

Thanks for your help!
oe

can you try to set the color back to white after drawing in the fbo? if not you are tinting the texture of the fbo with that same color, still you should be seeing something.

also a better way to cache a lot of text using only ofTrueTypeFont is:

//.h
ofVboMesh mesh;

//setup:
mesh.append(font.getStringMesh("text", x1, y1));
mesh.append(font.getStringMesh("another text", x2, y2));
....

//draw
font.getFontTexture().bind();
mesh.draw();
font.getFontTexture().unbind();

also the problem is in calling fbo.clear(); which doesn’t clear the fbo background but it destroys the fbo so when you draw the first time you are just drawing the circle without fbo and the second time you are drawing nothing because the fbo is not allocated

1 Like

Aaaah, I knew it, silly I am. Thank you Arturo! Now it makes perfect sense.
I replaced fbo.clear() with ofClear(255, 255, 255, 0); and all is working as expected.

void ofApp::draw(){

	if (!imageInited) {
		fbo.begin();
		ofClear(255, 255, 255, 0);
		ofBackground(0);
		ofSetColor(150, 200, 120);
		ofDrawCircle(200, 200, 100);
		fbo.end();
		imageInited = true;
	}
	ofSetColor(255);
	fbo.draw(0,0);
}

Thank you all & have a great day!
oe