ofTrueTypeFont looks clunky (like slow framerate) while translating

I’ve been using some ofTrueTypeFonts in my recent project, and have been playing with translating text. When moving slowly across the screen, I’ve found that the text looks like it move “chunkier” than shapes do when translating. A quick example:

void ofApp::setup(){
    mProgramBook118.load("fonts/ProgramOT-Book.otf", 118, true, true);
    mTextPosition = new ofPoint(0, ofGetWidth()/3.0);
}

//--------------------------------------------------------------
void ofApp::update(){
    mTextPosition->x += 0.2;
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofBackground(64);
    ofSetColor(255);
    mProgramBook118.drawString("hello world", mTextPosition->x, mTextPosition->y);
    ofDrawRectangle(mTextPosition->x, mTextPosition->y, 400, 100);
}

I find when I run this, the rectangle looks to smoothly translate from the left edge to the right edge, but the text noticeably looks like it’s “snapping” to the next pixel every 10 frames or so, almost as if I had a really low framerate (but the frame rate holds steady at 60 fps).

Does anyone have suggestions on what I might be able to do to alleviate this?

Hey!

You might have better luck rendering the text to a single mesh (via an fbo) and using the bounds of the text to allocate.

Then drawing the FBO could be smoother when translating.

Theo

the problem is that ofTrueTypeFont doesn’t do subpixel antialiasing so only when drawn in integer positions it’ll look correct, if you draw it at for example 20.5, 10 the antialiasing won’t look good.

there’s no easy solution, implementing subpixel antialiasing needs to be done in a special shader that uses the rgb components.

Hey guys! Thanks for the quick responses!

Wow, this totally cracked the tip of an iceberg of things I didn’t know much about. I’ll try out the FBO method; it seems like the most direct way to get to where I want, as rectangles seem to draw and move just fine.

That said – why is it that text isn’t subpixel aliased, but it appears that geometric shapes are? I suppose this isn’t really relevant to my question, but now I’m curious how things work under the hood :slight_smile:

thanks again!

So, drawing from a FBO seems to have resolved my issue, but introduced a new one – placing the text inside of the FBO is surprisingly tricky!

I had to remember:

  • ofTrueTypeFont is drawn with an inverted y-coordinate relative to geometric shapes
  • the font needed to be placed high enough that the descenders don’t run off of the frame buffer

and now it appears that drawing starting at x = 0 isn’t correct, because my final letters are being clipped (see the bottom piece of text):

It’s not clear which of the ofTrueTypeMethods would get me the right spacing – playing around with multiples of getLetterSpacing() seems to work, but that doesn’t seem like the “right” way to do it.

You could try using a vbo & mesh:

//do this once
    ofVboMesh mesh;
    mesh = font.getStringMesh("sentence",0,0);

// draw
    ofTranslate(x, y);
    font.getFontTexture().bind();
    mesh.draw();
    font.getFontTexture().unbind();

some more info in this excellent thread: Animating lots of font objects on 2d paths

Thanks!

I’m not too familiar with VBOs – is this a more efficient way to draw than using an FBO and then drawing it?

@morphogencc
there is more info here: https://github.com/openframeworks/openFrameworks/issues/5138

in short the fbo will give you the best / smoothest rendering for motion - you can get pretty similar quality with the approach @Kj1 mentioned though.