Skip to content

Instantly share code, notes, and snippets.

@arielm
Last active December 16, 2015 01:08
Show Gist options
  • Save arielm/5352546 to your computer and use it in GitHub Desktop.
Save arielm/5352546 to your computer and use it in GitHub Desktop.
Updated test case for Cinder's gl::TextureFont
/*
* TESTING UNICODE FONT RENDERING WITH gl::TextureFont
*
* FOLLOW-UP QUESTION IN THE CINDER FORUM:
* https://forum.libcinder.org/#Topic/23286000001505051
*
* COMMENTS:
* 1) IDEALLY, WE WOULD LIKE TO BE ABLE TO PRECALCULATE THE SIZE
* OF A TextBox AND TO COMPUTE ITS LAYOUT IN THE SAME PASS
* 2) THE CURRENT SYSTEM FOR DISPLAYING ARBITRARY SCALED TEXT
* IS NOT PRACTICAL
* 3) USING RGBA TEXTURES IS NOT OPTIMAL IN TERM OF GPU MEMORY
* AND IT FORCES US TO DEAL WITH PREMULTIPLICATION
*/
#include "cinder/app/AppNative.h"
#include "cinder/gl/TextureFont.h"
using namespace ci;
using namespace ci::app;
using namespace std;
const string text = "This is a long sentence that should split over a few good lines, hopefully!";
const ColorA color = ColorA(1, 1, 0, 1);
const float alpha = 0.85f;
const float scale = 0.75f;
const Vec2f anchor = Vec2f(30, 50);
class Application : public AppNative
{
public:
Font font;
gl::TextureFontRef textureFont;
TextBox textBox;
Rectf bounds;
vector<pair<uint16_t,Vec2f>> glyphMeasures;
gl::TextureFont::DrawOptions options;
void setup();
void draw();
};
void Application::setup()
{
/*
* XXX: PREMULTIPLICATION IS REQUIRED IN ORDER TO AVOID "DIRTY TEXT" WHEN SCALE IS NOT 1.0
* XXX: MIPMAPPING IS REQUIRED FOR PROPER AND EFFICIENT SCALING
* XXX: NO NEED TO MONOPOLIZE A HUGE 1024x1024 TEXTURE
*/
gl::TextureFont::Format format;
format.textureWidth(512).textureHeight(512).premultiply(true).enableMipmapping();
font = Font("Helvetica", 32);
textureFont = gl::TextureFont::create(font, format, gl::TextureFont::defaultChars());
/*
* ISSUE 1: THIS IS CREATING A DEFAULT Font WHICH ENDS-UP BEHING UNUSED
*/
textBox = TextBox().font(font).text(text).size(320, TextBox::GROW);
/*
* ISSUE 2, PART A: THIS IS INVOKING TextBox::createLines()
*/
Vec2f size = textBox.measure() * scale;
bounds = Rectf(0, 0, size.x, size.y);
/*
* ISSUE 2, PART B: THIS IS (AGAIN) INVOKING TextBox::createLines()
*/
glyphMeasures = textBox.measureGlyphs();
/*
* XXX: PIXEL-SNAP MUST BE DISABLED FOR SCALING TO WORK PROPERLY
*/
options = gl::TextureFont::DrawOptions().pixelSnap(false).scale(scale);
// ---
/*
* XXX: REQUIRED IN ORDER TO AVOID "DIRTY TEXT" WHEN SCALE IS NOT 1.0
*/
gl::enableAlphaBlending(true);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
}
void Application::draw()
{
gl::clear(Color(0.5f, 0.5f, 0.5f), false);
gl::setMatricesWindow(getWindowSize());
// ---
gl::color(Color(1.0f, 0.5f, 0.0f));
gl::drawSolidRect(bounds + anchor);
/*
* XXX: COLOR MUST BE MULTIPLIED BY ALPHA
*/
gl::color(color * alpha);
textureFont->drawGlyphs(glyphMeasures, Vec2f(0, textureFont->getAscent()) * scale + anchor, options);
}
CINDER_APP_NATIVE(Application, RendererGl(0))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment