2009年11月7日土曜日

zpb-ttfを用いて文字を表示する(cl-glfw)

zpb-ttfとcl-vectorsで適当に表示することはできたが、単純に表示したいだけなら zpb-ttfのみで問題無いんじゃないかと思ったのでやってみた。

(require :asdf)
(asdf:oos 'asdf:load-op :zpb-ttf)
(require :cl-glfw)
(require :cl-glfw-opengl)
(require :cl-glfw-glu)

;;取り合えずxの最小値~最大値が0~1.0となるよう調整。
;;x,yについて実行すべき関数の多値を返す
;;返り値vertex-2fに渡したいので、関数はsingle-floatを返す。
(defun correct (bounding-box)
(let ((xbase (- 0 (zpb-ttf:xmin bounding-box)))
(ybase (- 0 (zpb-ttf:ymin bounding-box))))
(let ((xmax (+ xbase (zpb-ttf:xmax bounding-box))))
(values
(lambda (x)
(coerce (* (+ x xbase) (/ 1 xmax)) 'single-float))
(lambda (y)
(coerce (* (+ y ybase) (/ 1 xmax)) 'single-float))))))

(defun run-test (&optional (ch #\A))
(zpb-ttf:with-font-loader
(font "/usr/share/fonts/truetype/sazanami/sazanami-gothic.ttf")
(let* ((bbox (zpb-ttf:bounding-box font))
(glyph (zpb-ttf:find-glyph ch font))
(frames 0)
t0 t1)
(multiple-value-bind (x-fn y-fn)
(correct bbox)
(glfw:do-window ("test-ttf" 300 300)
((gl:with-setup-projection
(glu:perspective
45d0
(coerce 4/3 'double-float)
0.1d0
50d0))
(setf t0 (glfw:get-time)
t1 (glfw:get-time)))

;;calc FPS
(setf t1 (glfw:get-time))
(when (> (- t1 t0) 1.0)
(glfw:set-window-title
(format nil "test-ttf(~,1f FPS)" (/ frames (- t1 t0))))
(setf frames 0
t0 t1))
(incf frames)

(gl:clear gl:+color-buffer-bit+)
(gl:load-identity)
(gl:translate-f 0.0 0.0 -5.0)

(zpb-ttf:do-contours (contour glyph)
(gl:with-begin gl:+line-loop+
(gl:color-3f 1.0 0.0 0.0)
(zpb-ttf:do-contour-segments (p0 p1 p2) contour
(gl:vertex-2f
(funcall x-fn (zpb-ttf:x p0))
(funcall y-fn (zpb-ttf:y p0)))
(gl:vertex-2f
(funcall x-fn (zpb-ttf:x p2))
(funcall y-fn (zpb-ttf:y p2)))))))))))

問題として、塗りつぶすことをまったく考えてない事がある。

外積だのなんだのを使って内外判定をして、文字の色を塗るか背景色を塗るか選んでから、 gl:line-loop+をgl:+quads+ あたりにかえて書けば良さそうだけど、ベクトルを忘れ去っている似非理系なのでまずは数学のお勉強から始めなければならないみたいだ。

0 件のコメント:

コメントを投稿