テクスチャで描画する(めんどくさい)
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