OpenGLで日本語を描画する(FTGL)
なんとOpenGLでは不可能。別のライブラリFTGL
を使う。
成果物
調査
どうやらFTGL
というのがそれっぽい。Pythonバインディングも発見。
FTGLはfreetypeというライブラリを使ったものっぽい。
インストール
freetype
freetype
はすでにインストール済みだった。
$ apt search freetype libfreetype6/stable,stable,now 2.9.1-3+deb10u1 armhf [インストール済み、自動] FreeType 2 font engine, shared library files libfreetype6-dev/stable,stable,now 2.9.1-3+deb10u1 armhf [インストール済み] FreeType 2 font engine, development files
FTGL
FTGL
は以下の名前っぽい。
$ apt search ftgl ソート中... 完了 全文検索... 完了 libftgl-dev/stable,stable 2.4.0-2 armhf development files for libftgl libftgl2/stable,stable 2.4.0-2 armhf library to render text in OpenGL using FreeType
sudo apt -y install libftgl-dev
python-FTGL
pipでftgl
を調査するとPyFTGL
というのがあった。
$ pip search ftgl sippy-ftgl (0.1.0) - Python binding for FTGL using SIP PyFTGL (0.4b) - Python FTGL binding $ pip3 search ftgl sippy-ftgl (0.1.0) - Python binding for FTGL using SIP PyFTGL (0.4b) - Python FTGL binding
pip install PyFTGL pip3 install PyFTGL
ERROR: Could not find a version that satisfies the requirement PyFTGL (from versions: none) ERROR: No matching distribution found for PyFTGL WARNING: You are using pip version 19.3.1; however, version 20.0.2 is available. You should consider upgrading via the 'pip install --upgrade pip' command.
インストールできなかった……。
GitHubで見つけたヤツを使ってみる。
git clone https://github.com/mugwort-rc/python-ftgl
cd python-ftgl
python setup.py build
python3 setup.py build
ビルドはエラー無く終了。成功したっぽい。
公式サイトには書いてなかったが、以下のようにインストールする必要がある。
sudo python setup.py install sudo python3 setup.py install
フォント
使うフォントのパスを探す。
fc-list
$ fc-list | grep vl /usr/share/fonts/truetype/vlgothic/VL-PGothic-Regular.ttf: VL Pゴシック,VL PGothic:style=regular /usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf: VL ゴシック,VL Gothic:style=regular
コード
main.py
import ftgl font = ftgl.FTGLPixmapFont("/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf") font.FaceSize(72) font.Render("Hello World!")
python main.py python3 main.py
Traceback (most recent call last): File "main.py_", line 8, in <module> font = ftgl.FTGLPixmapFont("Arial.ttf") AttributeError: 'module' object has no attribute 'FTGLPixmapFont'
FTGLPixmapFont
がないだと?
APIを確認しよう。
import ftgl print(dir(ftgl))
['ALIGN_CENTER', 'ALIGN_FRONT', 'ALIGN_JUSTIFY', 'ALIGN_RIGHT', 'FTBBox', 'FTBitmapFont', 'FTBitmapGlyph', 'FTBuffer', 'FTBufferFont', 'FTBufferGlyph', 'FTExtrudeFont', 'FTExtrudeGlyph', 'FTFont', 'FTGlyph', 'FTLayout', 'FTOutlineFont', 'FTOutlineGlyph', 'FTPixmapFont', 'FTPixmapGlyph', 'FTPoint', 'FTPolygonFont', 'FTPolygonGlyph', 'FTSimpleLayout', 'FTTextureFont', 'FTTextureGlyph', 'RENDER_ALL', 'RENDER_BACK', 'RENDER_FRONT', 'RENDER_SIDE', 'RenderMode', 'TextAlignment', '__builtins__', '__doc__', '__file__', '__ftgl', '__name__', '__package__', '__path__']
いや、名前ちゃうやん。公式に書いてあることはメチャクチャだ。ReadMeに騙された。もうお前なんて読まない。
import ftgl print(dir(ftgl)) font = ftgl.FTGLPixmapFont("Arial.ttf") #font = ftgl.FTPixmapFont("/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf") font.FaceSize(72) font.Render("Hello World!")
いや、名前ちゃうやん。公式に書いてあることはメチャクチャすぎ。ReadMeに騙された。もうお前なんて読まない。
python main.py
エラーは出ない。けどなにも表示されない。OpenGLで表示するよう処理せねばならないのだろう。
ぐぐってみた。
なんか類似だけど別のリポジトリ。こいつのコードをパクって修正する。
example2.py
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * import ftgl #import ftgl fonts = [] width = 600 height = 600 def do_ortho(): w, h = width, height glViewport(0, 0, w, h) glMatrixMode(GL_PROJECTION) glLoadIdentity() size = max(w, h) / 2.0 aspect = float(w) / float(h) if w <= h: aspect = float(h) / float(w) glOrtho(-size, size, -size*aspect, size*aspect, -100000.0, 100000.0) else: glOrtho(-size*aspect, size*aspect, -size, size, -100000.0, 100000.0) glScaled(aspect, aspect, 1.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def draw_scene(): string = [] chars = [] string.append(u'日本語も描画できる!') chars[:] = [] for i in range(1, 32): chars.append(chr(i)) string.append("".join(chars)) chars[:] = [] for i in range(32, 64): chars.append(chr(i)) string.append("".join(chars)) chars[:] = [] for i in range(64, 96): chars.append(chr(i)) string.append("".join(chars)) chars[:] = [] for i in range(96, 128): chars.append(chr(i)) string.append("".join(chars)) chars[:] = [] for i in range(128, 160): chars.append(chr(i)) string.append("".join(chars)) chars[:] = [] for i in range(160, 192): chars.append(chr(i)) string.append("".join(chars)) chars[:] = [] for i in range(192, 224): chars.append(chr(i)) string.append("".join(chars)) chars[:] = [] for i in range(224, 256): chars.append(chr(i)) string.append("".join(chars)) glColor3f(1.0, 1.0, 1.0) for i, font in enumerate(fonts): x = -250.0 yild = 20.0 for j in range(0, 4): y = 275.0 - i * 120.0 - j * yild if i >= 3: glRasterPos(x, y) font.Render(string[j]) elif i == 2: glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glPushMatrix() glTranslatef(x, y, 0.0) font.Render(string[j]) glPopMatrix() glDisable(GL_TEXTURE_2D) glDisable(GL_BLEND) else: glPushMatrix() glTranslatef(x, y, 0.0) font.Render(string[j]) glPopMatrix() def on_display(): glClear(GL_COLOR_BUFFER_BIT) do_ortho() draw_scene() glutSwapBuffers() def on_reshape(w, h): width, height = w, h def on_key(key, x, y): if key == '\x1b': sys.exit(1) if __name__ == '__main__': glutInitWindowSize(width, height) glutInit(sys.argv) glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE) glutCreateWindow("Pyftgl Demo") glClearColor(0.0, 0.0, 0.0, 0.0) try: fonts = [ # ftgl.OutlineFont(sys.argv[1]), # ftgl.PolygonFont(sys.argv[1]), # ftgl.TextureFont(sys.argv[1]), # ftgl.BitmapFont(sys.argv[1]), # ftgl.PixmapFont(sys.argv[1]), ftgl.FTOutlineFont(sys.argv[1]), ftgl.FTPolygonFont(sys.argv[1]), ftgl.FTTextureFont(sys.argv[1]), ftgl.FTBitmapFont(sys.argv[1]), ftgl.FTPixmapFont(sys.argv[1]), ] for font in fonts: font.FaceSize(24, 72) except: import traceback traceback.print_exc() print("usage:", sys.argv[0], "font_filename.ttf") # print "usage:", sys.argv[0], "font_filename.ttf" sys.exit(0) glutDisplayFunc(on_display) glutReshapeFunc(on_reshape) glutKeyboardUpFunc(on_key) glutMainLoop()
実行
python example2.py /usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf
第1引数は使いたいフォントパス。
所感
疲れた……。なんでこんなツギハギせにゃならんの? 文字くらい書けるようにしてくれや。
対象環境
- Raspbierry pi 4 Model B
- Raspbian buster 10.0 2019-09-26 ※
- bash 5.0.3(1)-release
$ uname -a Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux