214 lines
5.8 KiB
Rust
214 lines
5.8 KiB
Rust
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);
|