(
name: "Widget",
resources: [
(
name: "fyrox_widgetTexture",
kind: Texture(kind: Sampler2D, fallback: White),
binding: 0
),
(
name: "fyrox_widgetData",
kind: PropertyGroup([
// Autogenerated
]),
binding: 0
),
],
disabled_passes: ["GBuffer", "DirectionalShadow", "PointShadow", "SpotShadow"],
passes: [
(
name: "Forward",
// Drawing parameters explicitly controlled from code.
vertex_shader:
r#"
layout (location = 0) in vec2 vertexPosition;
layout (location = 1) in vec2 vertexTexCoord;
layout (location = 2) in vec4 vertexColor;
out vec2 texCoord;
out vec4 color;
void main()
{
texCoord = vertexTexCoord;
color = vertexColor;
vec3 worldSpaceVertex = fyrox_widgetData.worldMatrix * vec3(vertexPosition, 1.0);
gl_Position = fyrox_widgetData.projectionMatrix * vec4(worldSpaceVertex, 1.0);
}
"#,
fragment_shader:
r#"
// IMPORTANT: UI is rendered in sRGB color space!
out vec4 fragColor;
in vec2 texCoord;
in vec4 color;
float project_point(vec2 a, vec2 b, vec2 p) {
vec2 ab = b - a;
return clamp(dot(p - a, ab) / dot(ab, ab), 0.0, 1.0);
}
int find_stop_index(float t) {
int idx = 0;
for (int i = 0; i < fyrox_widgetData.gradientPointCount; ++i) {
if (t > fyrox_widgetData.gradientStops[i]) {
idx = i;
}
}
return idx;
}
void main()
{
vec2 size = vec2(fyrox_widgetData.boundsMax.x - fyrox_widgetData.boundsMin.x, fyrox_widgetData.boundsMax.y - fyrox_widgetData.boundsMin.y);
vec2 localPosition = (vec2(gl_FragCoord.x, fyrox_widgetData.resolution.y - gl_FragCoord.y) - fyrox_widgetData.boundsMin) / size;
if (fyrox_widgetData.brushType == 0) {
// Solid color
fragColor = fyrox_widgetData.solidColor;
} else {
// Gradient brush
float t = 0.0;
if (fyrox_widgetData.brushType == 1) {
// Linear gradient
t = project_point(fyrox_widgetData.gradientOrigin, fyrox_widgetData.gradientEnd, localPosition);
} else if (fyrox_widgetData.brushType == 2) {
// Radial gradient
t = clamp(length(localPosition - fyrox_widgetData.gradientOrigin), 0.0, 1.0);
}
int current = find_stop_index(t);
int next = min(current + 1, fyrox_widgetData.gradientPointCount);
float delta = fyrox_widgetData.gradientStops[next] - fyrox_widgetData.gradientStops[current];
float mix_factor = (t - fyrox_widgetData.gradientStops[current]) / delta;
fragColor = mix(fyrox_widgetData.gradientColors[current], fyrox_widgetData.gradientColors[next], mix_factor);
}
vec4 diffuseColor = texture(fyrox_widgetTexture, texCoord);
if (fyrox_widgetData.isFont)
{
fragColor.a *= diffuseColor.r;
}
else
{
fragColor *= diffuseColor;
}
fragColor.a *= fyrox_widgetData.opacity;
fragColor *= color;
}
"#,
),
(
name: "Clip",
draw_parameters: DrawParameters(
cull_face: None,
color_write: ColorMask(
red: false,
green: false,
blue: false,
alpha: false,
),
depth_write: false,
stencil_test: None,
depth_test: None,
blend: None,
stencil_op: StencilOp(
fail: Keep,
zfail: Keep,
zpass: Incr,
write_mask: 0xFFFF_FFFF,
),
scissor_box: None
),
vertex_shader:
r#"
layout (location = 0) in vec2 vertexPosition;
void main()
{
vec3 worldSpaceVertex = fyrox_widgetData.worldMatrix * vec3(vertexPosition, 1.0);
gl_Position = fyrox_widgetData.projectionMatrix * vec4(worldSpaceVertex, 1.0);
}
"#,
fragment_shader:
r#"
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0);
}
"#,
)
]
)