Just like OpenGL and most rendering engines that I know of, WebGL has no builtin support for text rendering. And on top of that, I can’t use the approach we use in PointLine at the moment. PointLine gets the outlines for the characters from the Windows GDI. So I was looking for something cross platform.
Searching on the internet there are two main approaches:
- Render the alphabet or the word in question to an image, and then use that image to texture some triangles.
- Trace the outlines of the characters and triangulate the polygons.
Although I prefer the second approach, I found an example of the first that looked simple enough on nehe. It was based on FreeType and for OpenGL. I started converting it to WebGL, but it was not as easy as it looked. It makes heavy use of display lists which are not available in WebGL.
So I looked further, and found the FTGL library which is also based on FreeType. It sounded like just what I need, but for OpenGL. So, I extended the library to allow me to extract the triangles for processing in WebGL. I sent my patch to the FTGL developers and hope for inclusion.
Meanwhile I can render texts in WebGL with my modified version of FTGL …Â of course it’s only so easy to do when using Wt::WGLWidget from the excellent witty library.
Here is my research prototype which now has text.
Here are the important parts of how it’s done with the modified libftgl:
void WebGlWidget::initializeGL()
{
vertices_.clear();
FTGLTriangleExtractorFont font(fontName_.c_str(), vertices_);
font.FaceSize(textSize_);
font.Render(txt_.c_str());
const WebGlWidget::ShaderInfo& shinf = wglw.GetShaderByName(“Text”);
wglw.useProgram(shinf.shaderProgram_);
vertexPositionAttribute_ = wglw.getAttribLocation(shinf.shaderProgram_, “aVertexPosition”);
wglw.enableVertexAttribArray(vertexPositionAttribute_);
vertexBuffer_ = wglw.createBuffer();
wglw.bindBuffer(wglw.ARRAY_BUFFER, vertexBuffer_);
wglw.bufferDatafv(wglw.ARRAY_BUFFER, vertices_.begin(), vertices_.end(), wglw.STATIC_DRAW);
}
void WebGlWidget::paintGL()
{
const WebGlWidget::ShaderInfo& shinf = wglw.GetShaderByName(“Text”);
wglw.useProgram(shinf.shaderProgram_);
wglw.bindBuffer(wglw.ARRAY_BUFFER, vertexBuffer_);
wglw.vertexAttribPointer(vertexPositionAttribute_, 3, wglw.FLOAT, false, 3 * 4, 0);
wglw.drawArrays(wglw.TRIANGLE_STRIP, 0, vertices_.size() / 3);
}
Update:
I now maintain my changes to ftgl at github and in my ppa.
Leave a Reply