From fdc2ab9421c6a38c6bbd9b621c4da4f2c147a773 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Sun, 6 Nov 2022 17:43:00 +0100 Subject: [PATCH] msdf font renderen --- .../assets/res/fonts/roboto.json | 1 + web/pw-visualizer/assets/res/fonts/roboto.png | Bin 0 -> 54869 bytes .../assets/shaders/frag/msdf.glsl | 29 +++ web/pw-visualizer/src/assets.ts | 5 + web/pw-visualizer/src/index.ts | 37 +++- web/pw-visualizer/src/webgl/msdf_text.ts | 181 ++++++++++++++++++ web/pw-visualizer/src/webgl/texture.ts | 10 +- web/pw-visualizer/src/webgl/util.ts | 1 + 8 files changed, 253 insertions(+), 11 deletions(-) create mode 100644 web/pw-visualizer/assets/res/fonts/roboto.json create mode 100644 web/pw-visualizer/assets/res/fonts/roboto.png create mode 100644 web/pw-visualizer/assets/shaders/frag/msdf.glsl create mode 100644 web/pw-visualizer/src/webgl/msdf_text.ts diff --git a/web/pw-visualizer/assets/res/fonts/roboto.json b/web/pw-visualizer/assets/res/fonts/roboto.json new file mode 100644 index 0000000..c84b33d --- /dev/null +++ b/web/pw-visualizer/assets/res/fonts/roboto.json @@ -0,0 +1 @@ +{"atlas":{"type":"msdf","distanceRange":8,"size":24,"width":232,"height":232,"yOrigin":"top"},"metrics":{"emSize":1,"lineHeight":1.171875,"ascender":-0.927734375,"descender":0.244140625,"underlineY":0.09765625,"underlineThickness":0.048828125},"glyphs":[{"unicode":32,"advance":0.2490234375},{"unicode":33,"advance":0.26806640625,"planeBounds":{"left":-0.11254882812500004,"top":-0.89371744791666652,"right":0.38745117187499989,"bottom":0.18961588541666666},"atlasBounds":{"left":78.5,"top":34.5,"right":90.5,"bottom":60.5}},{"unicode":34,"advance":0.32421875,"planeBounds":{"left":-0.12613932291666669,"top":-0.934814453125,"right":0.45719401041666663,"bottom":-0.309814453125},"atlasBounds":{"left":172.5,"top":195.5,"right":186.5,"bottom":210.5}},{"unicode":35,"advance":0.6103515625,"planeBounds":{"left":-0.13850911458333331,"top":-0.89713541666666652,"right":0.77815755208333337,"bottom":0.18619791666666666},"atlasBounds":{"left":91.5,"top":34.5,"right":113.5,"bottom":60.5}},{"unicode":36,"advance":0.568359375,"planeBounds":{"left":-0.13273111979166666,"top":-1.0071614583333335,"right":0.70060221354166663,"bottom":0.28450520833333331},"atlasBounds":{"left":60.5,"top":0.5,"right":80.5,"bottom":31.5}},{"unicode":37,"advance":0.734375,"planeBounds":{"left":-0.12963867187499997,"top":-0.89713541666666652,"right":0.870361328125,"bottom":0.18619791666666666},"atlasBounds":{"left":147.5,"top":34.5,"right":171.5,"bottom":60.5}},{"unicode":38,"advance":0.63916015625,"planeBounds":{"left":-0.14152018229166666,"top":-0.89713541666666652,"right":0.81681315104166663,"bottom":0.18619791666666666},"atlasBounds":{"left":21.5,"top":62.5,"right":44.5,"bottom":88.5}},{"unicode":39,"advance":0.1689453125,"planeBounds":{"left":-0.14371744791666669,"top":-0.9365234375,"right":0.31461588541666663,"bottom":-0.3115234375},"atlasBounds":{"left":160.5,"top":195.5,"right":171.5,"bottom":210.5}},{"unicode":40,"advance":0.34912109375,"planeBounds":{"left":-0.11621093750000004,"top":-0.97265625,"right":0.50878906249999989,"bottom":0.40234375},"atlasBounds":{"left":0.5,"top":0.5,"right":15.5,"bottom":33.5}},{"unicode":41,"advance":0.35302734375,"planeBounds":{"left":-0.15771484375000003,"top":-0.97265625,"right":0.46728515624999989,"bottom":0.40234375},"atlasBounds":{"left":16.5,"top":0.5,"right":31.5,"bottom":33.5}},{"unicode":42,"advance":0.4423828125,"planeBounds":{"left":-0.17293294270833331,"top":-0.89558919270833337,"right":0.61873372395833337,"bottom":-0.10392252604166667},"atlasBounds":{"left":87.5,"top":195.5,"right":106.5,"bottom":214.5}},{"unicode":43,"advance":0.5576171875,"planeBounds":{"left":-0.13932291666666666,"top":-0.767578125,"right":0.69401041666666663,"bottom":0.10742187499999999},"atlasBounds":{"left":47.5,"top":195.5,"right":67.5,"bottom":216.5}},{"unicode":44,"advance":0.22021484375,"planeBounds":{"left":-0.15771484375000003,"top":-0.28979492187499994,"right":0.34228515624999989,"bottom":0.335205078125},"atlasBounds":{"left":147.5,"top":195.5,"right":159.5,"bottom":210.5}},{"unicode":45,"advance":0.32861328125,"planeBounds":{"left":-0.14965820312500003,"top":-0.53165690104166663,"right":0.47534179687499989,"bottom":-0.073323567708333301},"atlasBounds":{"left":216.5,"top":170.5,"right":231.5,"bottom":181.5}},{"unicode":46,"advance":0.279296875,"planeBounds":{"left":-0.11450195312500004,"top":-0.30981445312499989,"right":0.38549804687499989,"bottom":0.19018554687500003},"atlasBounds":{"left":38.5,"top":217.5,"right":50.5,"bottom":229.5}},{"unicode":47,"advance":0.39599609375,"planeBounds":{"left":-0.16642252604166666,"top":-0.887451171875,"right":0.54191080729166663,"bottom":0.23754882812499997},"atlasBounds":{"left":194.5,"top":0.5,"right":211.5,"bottom":27.5}},{"unicode":48,"advance":0.568359375,"planeBounds":{"left":-0.13273111979166666,"top":-0.89713541666666652,"right":0.70060221354166663,"bottom":0.18619791666666666},"atlasBounds":{"left":66.5,"top":62.5,"right":86.5,"bottom":88.5}},{"unicode":49,"advance":0.568359375,"planeBounds":{"left":-0.10481770833333336,"top":-0.89835611979166652,"right":0.56184895833333326,"bottom":0.18497721354166666},"atlasBounds":{"left":108.5,"top":62.5,"right":124.5,"bottom":88.5}},{"unicode":50,"advance":0.568359375,"planeBounds":{"left":-0.13102213541666666,"top":-0.90201822916666652,"right":0.70231119791666663,"bottom":0.18131510416666666},"atlasBounds":{"left":125.5,"top":62.5,"right":145.5,"bottom":88.5}},{"unicode":51,"advance":0.568359375,"planeBounds":{"left":-0.14176432291666666,"top":-0.89713541666666652,"right":0.69156901041666663,"bottom":0.18619791666666666},"atlasBounds":{"left":146.5,"top":62.5,"right":166.5,"bottom":88.5}},{"unicode":52,"advance":0.568359375,"planeBounds":{"left":-0.15283203124999997,"top":-0.89713541666666652,"right":0.72216796875,"bottom":0.18619791666666666},"atlasBounds":{"left":167.5,"top":62.5,"right":188.5,"bottom":88.5}},{"unicode":53,"advance":0.568359375,"planeBounds":{"left":-0.12101236979166667,"top":-0.89225260416666652,"right":0.71232096354166663,"bottom":0.19108072916666666},"atlasBounds":{"left":189.5,"top":62.5,"right":209.5,"bottom":88.5}},{"unicode":54,"advance":0.568359375,"planeBounds":{"left":-0.12443033854166667,"top":-0.89396158854166652,"right":0.70890299479166663,"bottom":0.18937174479166666},"atlasBounds":{"left":91.5,"top":116.5,"right":111.5,"bottom":142.5}},{"unicode":55,"advance":0.568359375,"planeBounds":{"left":-0.13614908854166666,"top":-0.89713541666666652,"right":0.69718424479166663,"bottom":0.18619791666666666},"atlasBounds":{"left":211.5,"top":116.5,"right":231.5,"bottom":142.5}},{"unicode":56,"advance":0.568359375,"planeBounds":{"left":-0.13297526041666666,"top":-0.89713541666666652,"right":0.70035807291666663,"bottom":0.18619791666666666},"atlasBounds":{"left":134.5,"top":143.5,"right":154.5,"bottom":169.5}},{"unicode":57,"advance":0.568359375,"planeBounds":{"left":-0.13907877604166666,"top":-0.90030924479166652,"right":0.69425455729166663,"bottom":0.18302408854166666},"atlasBounds":{"left":175.5,"top":143.5,"right":195.5,"bottom":169.5}},{"unicode":58,"advance":0.26513671875,"planeBounds":{"left":-0.11743164062500004,"top":-0.72542317708333337,"right":0.38256835937499989,"bottom":0.19124348958333331},"atlasBounds":{"left":99.5,"top":170.5,"right":111.5,"bottom":192.5}},{"unicode":59,"advance":0.23779296875,"planeBounds":{"left":-0.16365559895833334,"top":-0.71077473958333337,"right":0.37801106770833331,"bottom":0.33089192708333331},"atlasBounds":{"left":196.5,"top":143.5,"right":209.5,"bottom":168.5}},{"unicode":60,"advance":0.50830078125,"planeBounds":{"left":-0.13964843749999997,"top":-0.70515950520833337,"right":0.6103515625,"bottom":0.086507161458333329},"atlasBounds":{"left":68.5,"top":195.5,"right":86.5,"bottom":214.5}},{"unicode":61,"advance":0.5595703125,"planeBounds":{"left":-0.11433919270833333,"top":-0.65999348958333326,"right":0.67732747395833337,"bottom":0.0066731770833333599},"atlasBounds":{"left":127.5,"top":195.5,"right":146.5,"bottom":211.5}},{"unicode":62,"advance":0.5205078125,"planeBounds":{"left":-0.12215169270833333,"top":-0.70515950520833337,"right":0.66951497395833337,"bottom":0.086507161458333329},"atlasBounds":{"left":107.5,"top":195.5,"right":126.5,"bottom":214.5}},{"unicode":63,"advance":0.48681640625,"planeBounds":{"left":-0.15657552083333331,"top":-0.89908854166666652,"right":0.63509114583333337,"bottom":0.18424479166666666},"atlasBounds":{"left":155.5,"top":143.5,"right":174.5,"bottom":169.5}},{"unicode":64,"advance":0.89501953125,"planeBounds":{"left":-0.1348371154108888,"top":-0.88313802083333337,"right":1.0318295512557778,"bottom":0.40852864583333331},"atlasBounds":{"left":98.5,"top":0.5,"right":126.5,"bottom":31.5}},{"unicode":65,"advance":0.66552734375,"planeBounds":{"left":-0.16674804687499997,"top":-0.89713541666666652,"right":0.833251953125,"bottom":0.18619791666666666},"atlasBounds":{"left":109.5,"top":143.5,"right":133.5,"bottom":169.5}},{"unicode":66,"advance":0.63134765625,"planeBounds":{"left":-0.11132812499999999,"top":-0.89713541666666652,"right":0.763671875,"bottom":0.18619791666666666},"atlasBounds":{"left":210.5,"top":62.5,"right":231.5,"bottom":88.5}},{"unicode":67,"advance":0.65283203125,"planeBounds":{"left":-0.12581380208333331,"top":-0.89713541666666652,"right":0.79085286458333337,"bottom":0.18619791666666666},"atlasBounds":{"left":66.5,"top":143.5,"right":88.5,"bottom":169.5}},{"unicode":68,"advance":0.6533203125,"planeBounds":{"left":-0.099853515625,"top":-0.89713541666666652,"right":0.77514648437499989,"bottom":0.18619791666666666},"atlasBounds":{"left":44.5,"top":143.5,"right":65.5,"bottom":169.5}},{"unicode":69,"advance":0.5654296875,"planeBounds":{"left":-0.11149088541666667,"top":-0.89713541666666652,"right":0.72184244791666663,"bottom":0.18619791666666666},"atlasBounds":{"left":23.5,"top":143.5,"right":43.5,"bottom":169.5}},{"unicode":70,"advance":0.5498046875,"planeBounds":{"left":-0.097493489583333329,"top":-0.89713541666666652,"right":0.69417317708333337,"bottom":0.18619791666666666},"atlasBounds":{"left":89.5,"top":143.5,"right":108.5,"bottom":169.5}},{"unicode":71,"advance":0.68115234375,"planeBounds":{"left":-0.12386067708333333,"top":-0.89713541666666652,"right":0.79280598958333337,"bottom":0.18619791666666666},"atlasBounds":{"left":0.5,"top":143.5,"right":22.5,"bottom":169.5}},{"unicode":72,"advance":0.7109375,"planeBounds":{"left":-0.10335286458333333,"top":-0.89713541666666652,"right":0.81331380208333337,"bottom":0.18619791666666666},"atlasBounds":{"left":188.5,"top":116.5,"right":210.5,"bottom":142.5}},{"unicode":73,"advance":0.2822265625,"planeBounds":{"left":-0.087565104166666699,"top":-0.89713541666666652,"right":0.37076822916666663,"bottom":0.18619791666666666},"atlasBounds":{"left":176.5,"top":116.5,"right":187.5,"bottom":142.5}},{"unicode":74,"advance":0.55517578125,"planeBounds":{"left":-0.16227213541666666,"top":-0.89225260416666652,"right":0.67106119791666663,"bottom":0.19108072916666666},"atlasBounds":{"left":155.5,"top":116.5,"right":175.5,"bottom":142.5}},{"unicode":75,"advance":0.63037109375,"planeBounds":{"left":-0.10359700520833333,"top":-0.89713541666666652,"right":0.81306966145833337,"bottom":0.18619791666666666},"atlasBounds":{"left":132.5,"top":116.5,"right":154.5,"bottom":142.5}},{"unicode":76,"advance":0.54150390625,"planeBounds":{"left":-0.099934895833333329,"top":-0.89713541666666652,"right":0.69173177083333337,"bottom":0.18619791666666666},"atlasBounds":{"left":112.5,"top":116.5,"right":131.5,"bottom":142.5}},{"unicode":77,"advance":0.87548828125,"planeBounds":{"left":-0.10416666666666666,"top":-0.89713541666666652,"right":0.97916666666666652,"bottom":0.18619791666666666},"atlasBounds":{"left":205.5,"top":34.5,"right":231.5,"bottom":60.5}},{"unicode":78,"advance":0.71044921875,"planeBounds":{"left":-0.10359700520833333,"top":-0.89713541666666652,"right":0.81306966145833337,"bottom":0.18619791666666666},"atlasBounds":{"left":68.5,"top":116.5,"right":90.5,"bottom":142.5}},{"unicode":79,"advance":0.6904296875,"planeBounds":{"left":-0.13419596354166666,"top":-0.89713541666666652,"right":0.82413736979166663,"bottom":0.18619791666666666},"atlasBounds":{"left":44.5,"top":116.5,"right":67.5,"bottom":142.5}},{"unicode":80,"advance":0.6396484375,"planeBounds":{"left":-0.099365234375,"top":-0.89713541666666652,"right":0.77563476562499989,"bottom":0.18619791666666666},"atlasBounds":{"left":22.5,"top":116.5,"right":43.5,"bottom":142.5}},{"unicode":81,"advance":0.6904296875,"planeBounds":{"left":-0.13663736979166666,"top":-0.90299479166666652,"right":0.82169596354166663,"bottom":0.30533854166666663},"atlasBounds":{"left":159.5,"top":0.5,"right":182.5,"bottom":29.5}},{"unicode":82,"advance":0.62451171875,"planeBounds":{"left":-0.096923828125,"top":-0.89713541666666652,"right":0.77807617187499989,"bottom":0.18619791666666666},"atlasBounds":{"left":0.5,"top":116.5,"right":21.5,"bottom":142.5}},{"unicode":83,"advance":0.60400390625,"planeBounds":{"left":-0.13574218749999997,"top":-0.89713541666666652,"right":0.7392578125,"bottom":0.18619791666666666},"atlasBounds":{"left":191.5,"top":89.5,"right":212.5,"bottom":115.5}},{"unicode":84,"advance":0.607421875,"planeBounds":{"left":-0.15437825520833331,"top":-0.89713541666666652,"right":0.76228841145833337,"bottom":0.18619791666666666},"atlasBounds":{"left":168.5,"top":89.5,"right":190.5,"bottom":115.5}},{"unicode":85,"advance":0.65234375,"planeBounds":{"left":-0.11035156249999999,"top":-0.89225260416666652,"right":0.7646484375,"bottom":0.19108072916666666},"atlasBounds":{"left":146.5,"top":89.5,"right":167.5,"bottom":115.5}},{"unicode":86,"advance":0.6474609375,"planeBounds":{"left":-0.17602539062499997,"top":-0.89713541666666652,"right":0.823974609375,"bottom":0.18619791666666666},"atlasBounds":{"left":121.5,"top":89.5,"right":145.5,"bottom":115.5}},{"unicode":87,"advance":0.88037109375,"planeBounds":{"left":-0.16129557291666657,"top":-0.89713541666666652,"right":1.0470377604166665,"bottom":0.18619791666666666},"atlasBounds":{"left":91.5,"top":89.5,"right":120.5,"bottom":115.5}},{"unicode":88,"advance":0.6328125,"planeBounds":{"left":-0.16202799479166666,"top":-0.89713541666666652,"right":0.79630533854166663,"bottom":0.18619791666666666},"atlasBounds":{"left":67.5,"top":89.5,"right":90.5,"bottom":115.5}},{"unicode":89,"advance":0.609375,"planeBounds":{"left":-0.17496744791666666,"top":-0.89713541666666652,"right":0.78336588541666663,"bottom":0.18619791666666666},"atlasBounds":{"left":43.5,"top":89.5,"right":66.5,"bottom":115.5}},{"unicode":90,"advance":0.6025390625,"planeBounds":{"left":-0.13378906249999997,"top":-0.89713541666666652,"right":0.7412109375,"bottom":0.18619791666666666},"atlasBounds":{"left":21.5,"top":89.5,"right":42.5,"bottom":115.5}},{"unicode":91,"advance":0.2744140625,"planeBounds":{"left":-0.10652669270833336,"top":-0.99723307291666652,"right":0.43513997395833331,"bottom":0.33610026041666663},"atlasBounds":{"left":32.5,"top":0.5,"right":45.5,"bottom":32.5}},{"unicode":92,"advance":0.41796875,"planeBounds":{"left":-0.15820312499999997,"top":-0.887451171875,"right":0.591796875,"bottom":0.23754882812499997},"atlasBounds":{"left":0.5,"top":34.5,"right":18.5,"bottom":61.5}},{"unicode":93,"advance":0.2744140625,"planeBounds":{"left":-0.16463216145833334,"top":-0.99723307291666652,"right":0.37703450520833331,"bottom":0.33610026041666663},"atlasBounds":{"left":46.5,"top":0.5,"right":59.5,"bottom":32.5}},{"unicode":94,"advance":0.427734375,"planeBounds":{"left":-0.16137695312499997,"top":-0.88761393229166663,"right":0.588623046875,"bottom":-0.17928059895833334},"atlasBounds":{"left":213.5,"top":89.5,"right":231.5,"bottom":106.5}},{"unicode":95,"advance":0.451171875,"planeBounds":{"left":-0.17024739583333331,"top":-0.18229166666666663,"right":0.62141927083333337,"bottom":0.27604166666666669},"atlasBounds":{"left":51.5,"top":217.5,"right":70.5,"bottom":228.5}},{"unicode":96,"advance":0.322265625,"planeBounds":{"left":-0.15226236979166669,"top":-0.92626953125,"right":0.43107096354166663,"bottom":-0.42626953125},"atlasBounds":{"left":23.5,"top":217.5,"right":37.5,"bottom":229.5}},{"unicode":97,"advance":0.54150390625,"planeBounds":{"left":-0.12459309895833333,"top":-0.72249348958333337,"right":0.66707356770833337,"bottom":0.19417317708333331},"atlasBounds":{"left":112.5,"top":170.5,"right":131.5,"bottom":192.5}},{"unicode":98,"advance":0.56298828125,"planeBounds":{"left":-0.12394205729166667,"top":-0.9326171875,"right":0.70939127604166663,"bottom":0.19238281249999997},"atlasBounds":{"left":19.5,"top":34.5,"right":39.5,"bottom":61.5}},{"unicode":99,"advance":0.52392578125,"planeBounds":{"left":-0.12898763020833331,"top":-0.72249348958333337,"right":0.66267903645833337,"bottom":0.19417317708333331},"atlasBounds":{"left":59.5,"top":170.5,"right":78.5,"bottom":192.5}},{"unicode":100,"advance":0.56494140625,"planeBounds":{"left":-0.14615885416666666,"top":-0.9326171875,"right":0.68717447916666663,"bottom":0.19238281249999997},"atlasBounds":{"left":40.5,"top":34.5,"right":60.5,"bottom":61.5}},{"unicode":101,"advance":0.53662109375,"planeBounds":{"left":-0.14322916666666666,"top":-0.72249348958333337,"right":0.69010416666666663,"bottom":0.19417317708333331},"atlasBounds":{"left":17.5,"top":170.5,"right":37.5,"bottom":192.5}},{"unicode":102,"advance":0.3544921875,"planeBounds":{"left":-0.14485677083333334,"top":-0.942626953125,"right":0.52180989583333326,"bottom":0.18237304687499997},"atlasBounds":{"left":61.5,"top":34.5,"right":77.5,"bottom":61.5}},{"unicode":103,"advance":0.56689453125,"planeBounds":{"left":-0.14347330729166666,"top":-0.70670572916666652,"right":0.68986002604166663,"bottom":0.37662760416666663},"atlasBounds":{"left":0.5,"top":62.5,"right":20.5,"bottom":88.5}},{"unicode":104,"advance":0.55517578125,"planeBounds":{"left":-0.11775716145833333,"top":-0.91666666666666652,"right":0.67390950520833337,"bottom":0.16666666666666666},"atlasBounds":{"left":185.5,"top":34.5,"right":204.5,"bottom":60.5}},{"unicode":105,"advance":0.255859375,"planeBounds":{"left":-0.12158203125000004,"top":-0.90616861979166652,"right":0.37841796874999989,"bottom":0.17716471354166666},"atlasBounds":{"left":172.5,"top":34.5,"right":184.5,"bottom":60.5}},{"unicode":106,"advance":0.25048828125,"planeBounds":{"left":-0.21500651041666669,"top":-0.90364583333333337,"right":0.36832682291666663,"bottom":0.38802083333333331},"atlasBounds":{"left":144.5,"top":0.5,"right":158.5,"bottom":31.5}},{"unicode":107,"advance":0.52197265625,"planeBounds":{"left":-0.12272135416666667,"top":-0.91666666666666652,"right":0.71061197916666663,"bottom":0.16666666666666666},"atlasBounds":{"left":126.5,"top":34.5,"right":146.5,"bottom":60.5}},{"unicode":108,"advance":0.255859375,"planeBounds":{"left":-0.1014811197916667,"top":-0.91666666666666652,"right":0.35685221354166663,"bottom":0.16666666666666666},"atlasBounds":{"left":114.5,"top":34.5,"right":125.5,"bottom":60.5}},{"unicode":109,"advance":0.87060546875,"planeBounds":{"left":-0.10636393229166667,"top":-0.70654296875,"right":0.97696940104166652,"bottom":0.16845703124999997},"atlasBounds":{"left":132.5,"top":170.5,"right":158.5,"bottom":191.5}},{"unicode":110,"advance":0.55615234375,"planeBounds":{"left":-0.11775716145833333,"top":-0.70654296875,"right":0.67390950520833337,"bottom":0.16845703124999997},"atlasBounds":{"left":27.5,"top":195.5,"right":46.5,"bottom":216.5}},{"unicode":111,"advance":0.5693359375,"planeBounds":{"left":-0.13199869791666666,"top":-0.72249348958333337,"right":0.70133463541666663,"bottom":0.19417317708333331},"atlasBounds":{"left":38.5,"top":170.5,"right":58.5,"bottom":192.5}},{"unicode":112,"advance":0.56298828125,"planeBounds":{"left":-0.12418619791666667,"top":-0.70914713541666652,"right":0.70914713541666663,"bottom":0.37418619791666663},"atlasBounds":{"left":87.5,"top":62.5,"right":107.5,"bottom":88.5}},{"unicode":113,"advance":0.56787109375,"planeBounds":{"left":-0.14640299479166666,"top":-0.70914713541666652,"right":0.68693033854166663,"bottom":0.37418619791666663},"atlasBounds":{"left":0.5,"top":89.5,"right":20.5,"bottom":115.5}},{"unicode":114,"advance":0.3515625,"planeBounds":{"left":-0.11279296875000004,"top":-0.70654296875,"right":0.51220703124999989,"bottom":0.16845703124999997},"atlasBounds":{"left":179.5,"top":170.5,"right":194.5,"bottom":191.5}},{"unicode":115,"advance":0.5166015625,"planeBounds":{"left":-0.14046223958333331,"top":-0.72249348958333337,"right":0.65120442708333337,"bottom":0.19417317708333331},"atlasBounds":{"left":79.5,"top":170.5,"right":98.5,"bottom":192.5}},{"unicode":116,"advance":0.3330078125,"planeBounds":{"left":-0.17830403645833334,"top":-0.823486328125,"right":0.48836263020833331,"bottom":0.17651367187499997},"atlasBounds":{"left":0.5,"top":170.5,"right":16.5,"bottom":194.5}},{"unicode":117,"advance":0.5556640625,"planeBounds":{"left":-0.11897786458333333,"top":-0.69677734375,"right":0.67268880208333337,"bottom":0.17822265624999997},"atlasBounds":{"left":159.5,"top":170.5,"right":178.5,"bottom":191.5}},{"unicode":118,"advance":0.4951171875,"planeBounds":{"left":-0.17008463541666666,"top":-0.70166015625,"right":0.66324869791666663,"bottom":0.17333984374999997},"atlasBounds":{"left":210.5,"top":143.5,"right":230.5,"bottom":164.5}},{"unicode":119,"advance":0.7431640625,"planeBounds":{"left":-0.17081705729166666,"top":-0.70166015625,"right":0.91251627604166652,"bottom":0.17333984374999997},"atlasBounds":{"left":0.5,"top":195.5,"right":26.5,"bottom":216.5}},{"unicode":120,"advance":0.50341796875,"planeBounds":{"left":-0.16471354166666666,"top":-0.70166015625,"right":0.66861979166666663,"bottom":0.17333984374999997},"atlasBounds":{"left":195.5,"top":170.5,"right":215.5,"bottom":191.5}},{"unicode":121,"advance":0.48681640625,"planeBounds":{"left":-0.17374674479166666,"top":-0.69913736979166652,"right":0.65958658854166663,"bottom":0.38419596354166663},"atlasBounds":{"left":45.5,"top":62.5,"right":65.5,"bottom":88.5}},{"unicode":122,"advance":0.50341796875,"planeBounds":{"left":-0.14143880208333331,"top":-0.70166015625,"right":0.65022786458333337,"bottom":0.17333984374999997},"atlasBounds":{"left":212.5,"top":0.5,"right":231.5,"bottom":21.5}},{"unicode":123,"advance":0.33544921875,"planeBounds":{"left":-0.15901692708333334,"top":-0.94783528645833337,"right":0.50764973958333326,"bottom":0.34383138020833331},"atlasBounds":{"left":127.5,"top":0.5,"right":143.5,"bottom":31.5}},{"unicode":124,"advance":0.2509765625,"planeBounds":{"left":-0.08235677083333337,"top":-0.89371744791666652,"right":0.33430989583333331,"bottom":0.31461588541666663},"atlasBounds":{"left":183.5,"top":0.5,"right":193.5,"bottom":29.5}},{"unicode":125,"advance":0.33544921875,"planeBounds":{"left":-0.17268880208333334,"top":-0.94783528645833337,"right":0.49397786458333331,"bottom":0.34383138020833331},"atlasBounds":{"left":81.5,"top":0.5,"right":97.5,"bottom":31.5}},{"unicode":126,"advance":0.66455078125,"planeBounds":{"left":-0.12581380208333331,"top":-0.58561197916666663,"right":0.79085286458333337,"bottom":-0.0022786458333333044},"atlasBounds":{"left":0.5,"top":217.5,"right":22.5,"bottom":231.5}}],"kerning":[]} diff --git a/web/pw-visualizer/assets/res/fonts/roboto.png b/web/pw-visualizer/assets/res/fonts/roboto.png new file mode 100644 index 0000000000000000000000000000000000000000..3723e709326833bcfb5b580a1edc903215ad6eb4 GIT binary patch literal 54869 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 i;JQ~m&TCz(qW=K%L}9=*{wQMr0000 ) { this.game = game; @@ -168,7 +173,9 @@ export class GameInstance { }); this.masked_image_shader = shaders["masked_image"].create_shader(GL); + this.msdf_shader = shaders["msdf"].create_shader(GL); this.text_factory = defaultLabelFactory(GL, font_texture, this.image_shader); + this.msdf_text_factory = defaultMsdfLabelFactory(GL, robotoMsdfTexture, this.msdf_shader); this.planet_labels = []; this.ship_labels = []; @@ -278,11 +285,11 @@ export class GameInstance { 1, 0, -planets[i * 3], - -planets[i * 3 + 1] - 1.2, + -planets[i * 3 + 1] - 1.171875, 1, ]); - const label = this.text_factory.build(GL, transform); + const label = this.msdf_text_factory.build(GL, transform); this.planet_labels.push(label); this.renderer.addRenderable(label.getRenderable(), LAYERS.planet_label); } @@ -330,7 +337,7 @@ export class GameInstance { this.planet_labels[i].setText( GL, - "*" + planet_ships[i], + "" + planet_ships[i], Align.Middle, Align.Begin ); @@ -375,7 +382,7 @@ export class GameInstance { const renderable = new DefaultRenderable(ib, vao, this.masked_image_shader, [this.ship_texture], {}); this.renderer.addRenderable(renderable, LAYERS.ship); - const label = this.text_factory.build(GL); + const label = this.msdf_text_factory.build(GL); this.ship_labels.push(label); this.renderer.addRenderable(label.getRenderable(), LAYERS.ship_label); @@ -451,10 +458,11 @@ export class GameInstance { this.shader, this.image_shader, this.masked_image_shader, + this.msdf_shader, ]; - // If not playing, still reder with different viewbox, so people can still pan etc. + // If not playing, still render with different viewbox, so that panning is still possible if (!this.playing) { this.last_time = time; @@ -595,6 +603,7 @@ export async function set_instance(source: string): Promise { loadImage(assets.fontPng), loadImage(assets.shipPng), loadImage(assets.earthPng), + loadImage(assets.robotoMsdfPng), ]; const shader_promies = [ @@ -630,7 +639,14 @@ export async function set_instance(source: string): Promise { assets.simpleVertexShader, ), ])(), - + (async () => + <[string, ShaderFactory]>[ + "msdf", + await ShaderFactory.create_factory( + assets.msdfFragmentShader, + assets.simpleVertexShader, + ), + ])(), ]; let shaders_array: [string, ShaderFactory][]; [texture_images, shaders_array] = await Promise.all([ @@ -646,12 +662,15 @@ export async function set_instance(source: string): Promise { const fontTexture = Texture.fromImage(GL, texture_images[0], "font"); const shipTexture = Texture.fromImage(GL, texture_images[1], "ship"); const earthTexture = Texture.fromImage(GL, texture_images[2], "earth"); + const robotoMsdfTexture = Texture.fromImage(GL, texture_images[3], "robotoMsdf"); + game_instance = new GameInstance( Game.new(source), [earthTexture], shipTexture, fontTexture, + robotoMsdfTexture, shaders ); diff --git a/web/pw-visualizer/src/webgl/msdf_text.ts b/web/pw-visualizer/src/webgl/msdf_text.ts new file mode 100644 index 0000000..5bbac20 --- /dev/null +++ b/web/pw-visualizer/src/webgl/msdf_text.ts @@ -0,0 +1,181 @@ +import { Shader, Uniform1f, Uniform4f, UniformMatrix3fv } from "./shader"; +import { Texture } from "./texture"; +import { DefaultRenderable } from "./renderer"; +import { IndexBuffer, VertexBuffer } from "./buffer"; +import { VertexBufferLayout, VertexArray } from "./vertexBufferLayout"; +import { robotoMsdfJson } from "../assets"; +import { GlypInfo } from "./text"; + + +export enum Align { + Begin, + End, + Middle, +} + +export type FontAtlas = { + atlas: AtlasMeta, + metrics: Metrics, + glyphs: Glyph[], +} + +export type AtlasMeta = { + type: string, + distanceRange: number, + size: number, + width: number, + height: number, + yOrigin: string, +} + +export type Metrics = { + emSize: number, + lineHeight: number, + ascender: number, + descender: number, + underlineY: number, + underlineThickness: number, +} + + +export type Glyph = { + unicode: number, + advance: number, + planeBounds?: Bounds, + atlasBounds?: Bounds, +} + +export type Bounds = { + left: number, + bottom: number, + right: number, + top: number, +} + + +export class MsdfLabelFactory { + texture: Texture; + font: FontAtlas; + shader: Shader; + + constructor(gl: WebGLRenderingContext, fontTexture: Texture, font: FontAtlas, shader: Shader) { + this.texture = fontTexture; + this.font = font; + this.shader = shader; + } + + build(gl: WebGLRenderingContext, transform?: UniformMatrix3fv): Label { + return new Label(gl, this.shader, this.texture, this.font, transform); + } +} + +export class Label { + inner: DefaultRenderable; + + font: FontAtlas; + charAtlas: {[unicodeNumber: number]: Glyph}; + + constructor(gl: WebGLRenderingContext, shader: Shader, tex: Texture, font: FontAtlas, transform: UniformMatrix3fv) { + this.font = font; + this.charAtlas = {} + this.font.glyphs.forEach((glyph) => { + this.charAtlas[glyph.unicode] = glyph; + }); + + const uniforms = { + "u_trans": transform, + "u_trans_next": transform, + "u_fgColor": new Uniform4f([1.0, 1.0, 1.0, 1.0]), + "u_bgColor": new Uniform4f([0.0, 0.0, 0.0, 1.0]), + "u_distanceRange": new Uniform1f(font.atlas.distanceRange), + "u_glyphSize": new Uniform1f(font.atlas.size), + }; + const ib = new IndexBuffer(gl, []); + const vb_pos = new VertexBuffer(gl, []); + const vb_tex = new VertexBuffer(gl, []); + + const layout_pos = new VertexBufferLayout(); + layout_pos.push(gl.FLOAT, 2, 4, "a_position"); + + const layout_tex = new VertexBufferLayout(); + layout_tex.push(gl.FLOAT, 2, 4, "a_texCoord"); + + const vao = new VertexArray(); + vao.addBuffer(vb_pos, layout_pos); + vao.addBuffer(vb_tex, layout_tex); + + this.inner = new DefaultRenderable(ib, vao, shader, [tex], uniforms); + } + + getRenderable(): DefaultRenderable { + return this.inner; + } + + setText(gl: WebGLRenderingContext, text: string, h_align = Align.Begin, v_align = Align.Begin) { + const idxs = []; + const verts_pos = []; + const verts_tex = []; + + let xPos = 0; + let yPos = 0; + switch (v_align) { + case Align.Begin: + yPos = -1; + break; + case Align.End: + yPos = 0; + break; + case Align.Middle: + yPos = -0.5; + break; + } + + // track position in the index buffer + let bufPos = 0; + for (let charIndex = 0; charIndex < text.length; charIndex++) { + let char = this.charAtlas[text.charCodeAt(charIndex)] + if (char.atlasBounds && char.planeBounds) { + verts_pos.push(xPos + char.planeBounds.left, yPos-char.planeBounds.top); + verts_pos.push(xPos + char.planeBounds.right, yPos-char.planeBounds.top); + verts_pos.push(xPos + char.planeBounds.left, yPos-char.planeBounds.bottom); + verts_pos.push(xPos + char.planeBounds.right, yPos-char.planeBounds.bottom); + + const atlasWidth = this.font.atlas.width; + const atlasHeight = this.font.atlas.height; + + verts_tex.push(char.atlasBounds.left / atlasWidth, char.atlasBounds.top / atlasHeight); + verts_tex.push(char.atlasBounds.right / atlasWidth, char.atlasBounds.top / atlasHeight); + verts_tex.push(char.atlasBounds.left / atlasWidth, char.atlasBounds.bottom / atlasHeight); + verts_tex.push(char.atlasBounds.right / atlasWidth, char.atlasBounds.bottom / atlasHeight); + + idxs.push(bufPos+0, bufPos+1, bufPos+2); + idxs.push(bufPos+1, bufPos+2, bufPos+3); + bufPos += 4; + } + xPos += char.advance; + } + + let shift = 0; + switch (h_align) { + case Align.End: + shift = xPos; + break; + case Align.Middle: + shift = xPos / 2; + break; + } + + for (let i = 0; i < verts_pos.length; i += 2) { + verts_pos[i] -= shift; + } + + + this.inner.updateIndexBuffer(gl, idxs); + this.inner.updateVAOBuffer(gl, 0, verts_pos); + this.inner.updateVAOBuffer(gl, 1, verts_tex); + } +} + +export function defaultMsdfLabelFactory(gl: WebGLRenderingContext, fontTexture: Texture, shader: Shader): MsdfLabelFactory { + return new MsdfLabelFactory(gl, fontTexture, robotoMsdfJson, shader); +} diff --git a/web/pw-visualizer/src/webgl/texture.ts b/web/pw-visualizer/src/webgl/texture.ts index 9624489..9ebd5c0 100644 --- a/web/pw-visualizer/src/webgl/texture.ts +++ b/web/pw-visualizer/src/webgl/texture.ts @@ -67,8 +67,14 @@ export class Texture { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (name == "font") { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + } else { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + + } gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255])); diff --git a/web/pw-visualizer/src/webgl/util.ts b/web/pw-visualizer/src/webgl/util.ts index 7b55d19..922b016 100644 --- a/web/pw-visualizer/src/webgl/util.ts +++ b/web/pw-visualizer/src/webgl/util.ts @@ -74,6 +74,7 @@ export class Resizer { mouse_pos = [0, 0]; last_drag = [0, 0]; + // x, y, w, h viewbox: number[]; orig_viewbox: number[];