yum/DisInfo
Simple HLSL text rendering utilities.
git clone https://git.yummers.dev/yum/DisInfo
a5e0aaf
master
1#ifndef __DISINFO_INC 2#define __DISINFO_INC 3 4/* 5 * A small font rendering library. 6 * 7 * Sample usage: 8 * 9 * fixed4 frag(v2f i) : SV_Target 10 * { 11 * float2 uv = i.uv; 12 * int2 cell_pos; 13 * float2 cell_uv; 14 * float2 res = int2(4, 4); 15 * if (!getBoxLoc(uv, 0.1, 0.9, res, cell_pos, cell_uv)) { 16 * return float4(0, 0, 0, 1); 17 * } 18 * float2 duv = float2(ddx(i.uv.x), ddy(i.uv.y)) / 4; 19 * float4 font_color = renderInBox(67, cell_uv, duv); 20 * 21 * return font_color; 22 * } 23 */ 24 25// `_Font` should be an 8x16 (8 rows, 16 columns) grid of monospace ASCII 26// glyphs. 27Texture2D _Font; 28float4 _Font_TexelSize; 29SamplerState linear_clamp_sampler; 30 31// Returns false if `uv` does not fall within `bounds`. 32bool remapUVSmaller(float2 uv, float2 bottom_left, float2 top_right, 33 out float2 uvr) { 34 if (!(uv.x > bottom_left.x && uv.x < top_right.x && 35 uv.y > bottom_left.y && uv.y < top_right.y)) { 36 return false; 37 } 38 39 uvr = uv - bottom_left; 40 uvr = uvr / (top_right - bottom_left); 41 42 return true; 43} 44 45// bounds: the left/right/top/bottom bounds of the inner UV region, 46// respectively. 47// Always returns true. 48bool remapUVBigger(float2 uv, float2 bottom_left, float2 top_right, 49 out float2 uvr) { 50 uvr = uv * (top_right - bottom_left) + bottom_left; 51 52 return true; 53} 54 55bool getBoxLoc(float2 uv, float2 bottom_left, float2 top_right, 56 int2 res, out int2 cell_pos, out float2 cell_uv) 57{ 58 float2 box_uv; 59 if (!remapUVSmaller(uv, bottom_left, top_right, box_uv)) { 60 return false; 61 } 62 63 // The integer index of the cell pointed to by `uv`, on the interval 64 // [0, res.x - 1] * [0, res.y - 1] 65 cell_pos = fmod(floor(box_uv * res), res); 66 67 float2 box_sz = 1.0 / float2(res); 68 float2 cell_bot_left = cell_pos * box_sz; 69 float2 cell_top_right = (cell_pos + 1) * box_sz; 70 if (!remapUVSmaller(box_uv, cell_bot_left, cell_top_right, cell_uv)) { 71 // This should never happen Clueless 72 return false; 73 } 74 75 return true; 76} 77 78// `c` is a character encoded as ASCII. 79// `duv` is float2(ddx(i.uv.x), ddy(i.uv.y)), where `i.uv` is the UV of the 80// object we're rendering on. 81float4 renderInBox(int c, float2 cell_uv, float2 duv) 82{ 83 int2 bitmap_res = int2(16, 8); 84 int letter_idx = c; 85 int2 letter_pos = int2( 86 bitmap_res.x - (letter_idx % bitmap_res.x), 87 letter_idx / bitmap_res.x); 88 letter_pos.x = bitmap_res.x - letter_pos.x; 89 letter_pos.y = (bitmap_res.y - 1) - letter_pos.y; 90 float2 letter_box_sz = 1.0 / float2(bitmap_res); 91 float2 letter_bot_left = letter_pos * letter_box_sz; 92 float2 letter_top_right = (letter_pos + 1) * letter_box_sz; 93 float2 letter_uv; 94 remapUVBigger(cell_uv, letter_bot_left, letter_top_right, letter_uv); 95 96 float4 font_color = _Font.SampleGrad(linear_clamp_sampler, letter_uv, duv.x, duv.y); 97 return font_color; 98} 99 100#endif // __DISINFO_INC 101