テクスチャで描画する(めんどくさい)
gs -r288 -q -sDEVICE=pnggray -o gs.png courier.ps > courier.json
-q
を忘れるとJSONにゴミが入るので注意
convert gs.png -resize 25% -unsharp 0x1+0.5+0 courier.png
fs
: 公称フォントサイズ。このテクスチャは各セルが32ピクセルになっていて、上下左右1ピクセルを余らせてその中に目一杯の大きさでグリフを書いている。これを1px=1ptで出力したとしたら、何ポイントになるかを示している。
h
・w
: テクスチャ画像の幅と高さ、テクセル単位
th
・tw
: テクスチャセルの幅と高さ、テクセル単位
x0
・y0
: フォント描画開始原点オフセット。頂点座標を作る時に使う。基準座標はグリフのベースラインになっているため、欧文の「y」などはベースラインより下にはみ出す。このため、全部のグリフが収まる箱を計算し、その箱の左下をグリフ原点から見た座標を、フォントが1ptだったときの値で示している。この値にフォントサイズを乗じたものを、描画開始位置に加算したものが頂点の左下座標になる。
x1
・y1: 同様に頂点右上座標の計算に使う。
dx
: 現在の位置を基準として次の文字を書き始める位置を、フォントが1ptだったときの値で示している。
resize
を引っかけて、ウィンドウの幅を変えてもフォントサイズが変わらないように再描画している。
fetch
も拙作loadTexture
もプロミスを返すので、Promise.all
が解決するまで待てばよい(引数になってる配列の中に処理を書いてたりして我ながらちょっとヒドい)。
uAspect.xy
で割っており、uAspect.xy
にはキャンバスのwidth
とheight
のそれぞれ半分を設定している。
$QS
とか見えるけどきっと気のせい
gl_FragColor
の第4成分は1を出力してきたが1以外のデータを出力したらどうなるのか?
gl.enable(gl.BLEND);
でアルファ合成を有効化
gl.blendFuncSeparate
で合成方法を指定
gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA
はRGBに対する合成方法で、FS出力のRGBにAを、既に書かれているRGBに(1-A)を乗じて加算し、結果のRGBとする
gl.ZERO, gl.ONE
はアルファに対する合成方法で、FS出力のAに0、既に書かれているAに1を乗じて加算し、結果のAとする
$QS
はこっそりvanilla.js
に移動
"
と\
はエスケープする必要がある
getBBox
や、2DコンテキストのmeasureText
を使えばJavaScriptだけでできるはず(知らないけどきっとそう)
fs
: 公称フォントサイズ
w
・h
: テクスチャ画像の幅と高さ、ピクセル単位
x0
・y0
・x1
・y1
: フォント描画開始・終了位置の原点オフセット、フォントサイズが1ptの場合の値、頂点座標系
dx
: 次の描画開始位置、フォントサイズが1ptの場合の値、頂点座標系
u0
・v0
・u1
・v1
: テクスチャ上の文字開始・終了位置、PostScript座標系でテクセル単位
drawArrays
の呼び出し回数が増える
drawArrays
の呼び出し回数はフォントテクスチャの数だけで済む
drawArrays
は1回で済む
glFontMap.create(gl)
する
font.load()
する
glFontBuffer.create()
に渡す
fontbuf.appendString()
で好きなだけ文字を書く
fontbuf.prepare()
するとGLのバッファができる
fontbuf.draw()
で描画
prepare
とdraw
が分かれているのは、フォントと文字列が変わらない限り、バッファを再生成する必要がないから
glFontBuffer
を用意しておけばよい
resize
イベントで色が変わるようにしてみた
07 Jul 2024: 初稿
Copyright (C) 2024 akamoz.jp