{"id":64,"date":"2011-08-27T01:33:41","date_gmt":"2011-08-26T23:33:41","guid":{"rendered":"http:\/\/blog.ulrichard.ch\/?p=64"},"modified":"2011-08-27T01:33:41","modified_gmt":"2011-08-26T23:33:41","slug":"rendering-text-in-webgl","status":"publish","type":"post","link":"https:\/\/ulrichard.ch\/blog\/?p=64","title":{"rendered":"Rendering Text in WebGL"},"content":{"rendered":"<p>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&#8217;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.<\/p>\n<p>Searching on the internet there are two main approaches:<\/p>\n<ol>\n<li>Render the alphabet or the word in question to an image, and then use that image to texture some triangles.<\/li>\n<li>Trace the outlines of the characters and triangulate the polygons.<\/li>\n<\/ol>\n<p>Although I prefer the second approach, I found an example of the first that looked simple enough on <a href=\"http:\/\/nehe.gamedev.net\/tutorial\/freetype_fonts_in_opengl\/24001\/\">nehe<\/a>. It was based on <a href=\"http:\/\/freetype.org\/index2.html\">FreeType<\/a> and for OpenGL.\u00c2\u00a0 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.<\/p>\n<p>So I looked further, and found the <a href=\"http:\/\/ftgl.sourceforge.net\/docs\/html\/\">FTGL library<\/a> which is also based on <a href=\"http:\/\/freetype.org\/index2.html\">FreeType<\/a>. 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 <a href=\"http:\/\/blog.ulrichard.ch\/wp-uploads\/2011\/08\/TriangleExtractor.diff_.txt\">my patch<\/a> to the FTGL developers and hope for inclusion.<\/p>\n<p>Meanwhile I can render texts in WebGL with my modified version of FTGL &#8230;\u00c2\u00a0 of course it&#8217;s only so easy to do when using <a href=\"http:\/\/www.webtoolkit.eu\/wt\/doc\/reference\/html\/classWt_1_1WGLWidget.html\">Wt::WGLWidget<\/a> from the excellent witty library.<\/p>\n<p>Here is my <a href=\"http:\/\/webglcad.ulrichard.ch\">research prototype<\/a> which now has text.<\/p>\n<p>Here are the important parts of how it&#8217;s done with the modified libftgl:<\/p>\n<p><!--more-->void WebGlWidget::initializeGL()<br \/>\n{<\/p>\n<p>vertices_.clear();<br \/>\nFTGLTriangleExtractorFont font(fontName_.c_str(), vertices_);<br \/>\nfont.FaceSize(textSize_);<br \/>\nfont.Render(txt_.c_str());<\/p>\n<p>const WebGlWidget::ShaderInfo&amp; shinf = wglw.GetShaderByName(&#8220;Text&#8221;);<br \/>\nwglw.useProgram(shinf.shaderProgram_);<\/p>\n<p>vertexPositionAttribute_ = wglw.getAttribLocation(shinf.shaderProgram_, &#8220;aVertexPosition&#8221;);<br \/>\nwglw.enableVertexAttribArray(vertexPositionAttribute_);<\/p>\n<p>vertexBuffer_ = wglw.createBuffer();<br \/>\nwglw.bindBuffer(wglw.ARRAY_BUFFER, vertexBuffer_);<br \/>\nwglw.bufferDatafv(wglw.ARRAY_BUFFER, vertices_.begin(), vertices_.end(), wglw.STATIC_DRAW);<br \/>\n}<\/p>\n<p>void WebGlWidget::paintGL()<br \/>\n{<\/p>\n<p>const WebGlWidget::ShaderInfo&amp; shinf = wglw.GetShaderByName(&#8220;Text&#8221;);<br \/>\nwglw.useProgram(shinf.shaderProgram_);<\/p>\n<p>wglw.bindBuffer(wglw.ARRAY_BUFFER, vertexBuffer_);<br \/>\nwglw.vertexAttribPointer(vertexPositionAttribute_, 3, wglw.FLOAT, false, 3 * 4, 0);<\/p>\n<p>wglw.drawArrays(wglw.TRIANGLE_STRIP, 0, vertices_.size() \/ 3);<\/p>\n<p>}<\/p>\n<h2>Update:<\/h2>\n<p>I now maintain my <a href=\"https:\/\/github.com\/ulrichard\/ftgl\" target=\"_blank\" rel=\"noopener\">changes to ftgl at github<\/a> and in my <a href=\"https:\/\/launchpad.net\/~richi-paraeasy\/+archive\/ppa\/+packages\" target=\"_blank\" rel=\"noopener\">ppa<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;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. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,7,1],"tags":[44,173,245],"class_list":["post-64","post","type-post","status-publish","format-standard","hentry","category-projects","category-software","category-uncategorized","tag-cad","tag-pointline","tag-webgl"],"_links":{"self":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/64","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=64"}],"version-history":[{"count":0,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/64\/revisions"}],"wp:attachment":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=64"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=64"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=64"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}