use super::trackball::Trackball; use super::CodePiece; use crate::impl_code_piece; use glsl::syntax::ShaderStage; use glsl::syntax::TranslationUnit; use glsl::transpiler::glsl::show_translation_unit; use glsl_quasiquote::glsl; pub struct FontVertex(pub ShaderStage); pub struct FontFragment(pub ShaderStage); pub struct FontGeometry(pub ShaderStage); impl FontVertex { pub fn new() -> Self { let raw = glsl! { // texcoord (left top, right bottom) layout(location = 0) in vec4 texcoord; // Relative position (x, y, width, height) layout(location = 1) in vec4 relative_position; out VS_OUT { vec4 texcoord; vec4 pos; } vs_out; void main() { vs_out.texcoord = texcoord; vs_out.pos = relative_position; } }; Self(raw) } } impl FontGeometry { pub fn new() -> Self { let mut transform = Trackball::new().0; let raw = glsl! { layout(points) in; layout(triangle_strip, max_vertices = 4) out; // Uniforms uniform vec3 location; uniform vec3 anchor; uniform vec2 viewport; // Texture Shape uniform vec2 atlas_shape; out vec2 v_texCoord; out vec2 UV_coord; in VS_OUT { vec4 texcoord; vec4 pos; } gs_in[]; void main() { vec4 pos = gs_in[0].pos; float x, y, width, hgt; // Char position and size x = pos.x; y = pos.y; width = pos.z; hgt = pos.w; // texcoord vec2 tex_coord_lt = gs_in[0].texcoord.xy / atlas_shape; vec2 tex_coord_rb = gs_in[0].texcoord.zw / atlas_shape; // uv_coord vec2 uv_coord_lt = gs_in[0].texcoord.xy; vec2 uv_coord_rb = gs_in[0].texcoord.zw; // Char Size vec2 size = vec2(width, hgt); // Base Text Location vec3 base_pos = location + anchor; // base_pos in NDC vec4 ndc_base_pos = transform(position(base_pos)); // Screen Space vec2 screen_base_pos = viewport * ((ndc_base_pos.xy / ndc_base_pos.w) + 1.0) / 2.0; // Billboard Type vec2 left_top = screen_base_pos + vec2(x, y); vec2 right_bottom = left_top + size; vec2 ndc_left_top = (2.0 * left_top / viewport - 1.0); vec2 ndc_right_bottom = (2.0 * right_bottom / viewport - 1.0); // Emit vertices gl_Position = vec4(ndc_left_top.x, ndc_right_bottom.y, ndc_base_pos.z / ndc_base_pos.w, 1.0); v_texCoord = vec2(tex_coord_lt.x, tex_coord_rb.y); UV_coord = vec2(uv_coord_lt.x, uv_coord_rb.y); EmitVertex(); gl_Position = vec4(ndc_right_bottom.xy, ndc_base_pos.z / ndc_base_pos.w, 1.0); v_texCoord = tex_coord_rb; UV_coord = uv_coord_rb; EmitVertex(); gl_Position = vec4(ndc_left_top.xy, ndc_base_pos.z / ndc_base_pos.w, 1.0); v_texCoord = tex_coord_lt; UV_coord = uv_coord_lt; EmitVertex(); gl_Position = vec4(ndc_right_bottom.x, ndc_left_top.y, ndc_base_pos.z / ndc_base_pos.w, 1.0); v_texCoord = vec2(tex_coord_rb.x, tex_coord_lt.y); UV_coord = vec2(uv_coord_rb.x, uv_coord_lt.y); EmitVertex(); EndPrimitive(); } }; transform.extend(raw); Self(transform) } } impl FontFragment { pub fn new() -> Self { let raw = glsl! { uniform sampler2D atlas_data; in vec2 v_texCoord; in vec2 UV_coord; uniform vec4 uClipUV; uniform vec4 uSdfConfig; uniform int uMode; uniform vec4 uBorder; uniform vec4 uStroke; uniform vec4 uFill; float getUVScale(vec2 sdfUV) { float dx = dFdx(sdfUV.x); float dy = dFdy(sdfUV.y); return (sqrt(dx * dx + dy * dy) + sqrt(dy * dy + dx * dx)) * 0.5; } struct SDF { float outer; float inner; }; vec4 getTexture(vec2 uv) { return texture(atlas_data, uv); } vec4 getMask(vec4 color, vec2 uv, vec2 st) { return color; // 默认不修改颜色 } out vec4 fragColor; void main() { vec4 fillColor = uFill; vec4 strokeColor = uStroke; float scale = getUVScale(UV_coord); vec4 texture = getTexture(v_texCoord); float dis = texture.r; // float sdfRaw = 0.0; // float mark = 0.0; // float sdf; // float sdfRadius = uSdfConfig.x; // float expand = uBorder.x; // float bleed = uBorder.y; // float d = (texture.r - 0.75) * sdfRadius; // float s = (d + expand / uSdfConfig.y) / scale + 0.5 + bleed; // sdf = s; // Assuming SDF returns a single float, adjust as necessary // if (uMode == -2) { // fillColor = vec4(texture.rgb, fillColor.a); // } // // Compute mask based on SDF // float mask = clamp(sdf, 0.0, 1.0); // Final color blending logic here // fragColor = vec4(fillColor.rgb + mark, mask + mark); fragColor = vec4(dis,dis,dis,dis); } }; Self(raw) } } impl_code_piece!(FontVertex, 0); impl_code_piece!(FontGeometry, 0); impl_code_piece!(FontFragment, 0);