start on gui

This commit is contained in:
Matthew 2025-08-24 16:28:45 +10:00
parent 2a36233670
commit 2da7af7431
9 changed files with 123 additions and 33 deletions

Binary file not shown.

Binary file not shown.

View File

@ -13,6 +13,7 @@
"sourcePaths": ["src/editor", "src/dlib", "src/dlib/external/xxhash", "src/VulkanRenderer"],
"libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++", "xcb-xfixes", "freetype"],
"libs-windows": [],
"versions": ["VK_DEBUG_PRINTF"],
"preGenerateCommands-linux": ["./build.sh"],
"preGenerateCommands-windows": [],
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-Jbuild"],

@ -1 +1 @@
Subproject commit f3b7536c8e4edea80d3b7ef3e4265e521a050c03
Subproject commit b0d96f26fe727d297c441ce989f3fec45095e3c3

@ -1 +1 @@
Subproject commit 98701be20c223d1130a1f423c8ca3b520c9d4a95
Subproject commit f8d1707450d92bd147a3283527043c86312b3872

View File

@ -41,20 +41,26 @@ struct Editor
u8[] font_data;
FontFace font;
FontAtlasBuf atlas_buf;
UVec2 res;
}
struct PushConst
{
Vec2 res;
Mat4 projection;
}
struct Vertex
{
Vec4 col;
Vec2 dst_start;
Vec2 dst_end;
Vec2 src_start;
Vec2 src_end;
Vec4 col;
f32 border_thickness;
f32 corner_radius;
f32 edge_softness;
f32 raised;
}
void
@ -68,11 +74,18 @@ Cycle(Editor* ed)
f32 h = ed.atlas_buf.atlas.size;
DrawBuffer(ed, 0.0, 0.0, h, ed.active_buffer);
//DrawRect(ed, 200.0, 200.0, 300.0, 300.0, 0.0, 0.0, 0.0, Vec4(0.2, 0.4, 0.8, 1.0));
//DrawRect(ed, 330.0, 330.0, 430.0, 430.0, 0.0, 0.0, 0.0, Vec4(0.2, 0.4, 0.8, 1.0));
DrawRect(ed, 450.0, 450.0, 550.0, 550.0, 0.0, 1.0, 0.0, Vec4(1.0));
BeginFrame(&ed.rd);
UVec2 ext = UVec2(GetExtent(&ed.rd));
ed.pc.res.x = cast(f32)ext.x;
ed.pc.res.y = cast(f32)ext.y;
if (ext != ed.res)
{
ed.res = ext;
Ortho(&ed.pc.projection, 0.0, 0.0, cast(f32)(ext.x), cast(f32)(ext.y), 1000.0, 0.1);
}
BeginRendering(&ed.rd);
@ -169,12 +182,16 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
editor.desc_set = AllocDescSet(&editor.rd, editor.desc_set_layout);
editor.pipeline_layout = CreatePipelineLayout(&editor.rd, editor.desc_set_layout, PushConst.sizeof);
Attribute[5] attributes = [
{ binding: 0, location: 0, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof },
{ binding: 0, location: 1, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof },
{ binding: 0, location: 2, format: FMT.RG_F32, offset: Vertex.src_start.offsetof },
{ binding: 0, location: 3, format: FMT.RG_F32, offset: Vertex.src_end.offsetof },
{ binding: 0, location: 4, format: FMT.RGBA_F32, offset: Vertex.col.offsetof },
Attribute[9] attributes = [
{ binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.col.offsetof },
{ binding: 0, location: 1, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof },
{ binding: 0, location: 2, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof },
{ binding: 0, location: 3, format: FMT.RG_F32, offset: Vertex.src_start.offsetof },
{ binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.src_end.offsetof },
{ binding: 0, location: 5, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof },
{ binding: 0, location: 6, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof },
{ binding: 0, location: 7, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof },
{ binding: 0, location: 8, format: FMT.R_F32, offset: Vertex.raised.offsetof },
];
GfxPipelineInfo ui_info = {
@ -184,6 +201,12 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
input_rate_stride: Vertex.sizeof,
layout: editor.pipeline_layout,
vertex_attributes: attributes,
src_color: BF.SrcAlpha,
dst_color: BF.OneMinusSrcAlpha,
color_op: BO.Add,
src_alpha: BF.One,
dst_alpha: BF.Zero,
alpha_op: BO.Add,
};
assert(CreateGraphicsPipeline(&editor.rd, &editor.pipeline, &ui_info), "Unable to build UI pipeline");
@ -319,9 +342,9 @@ DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec
f32 y_pos = glyph.plane_top * scale;
v.dst_start.x = *x_pos + l;
v.dst_start.y = y + h - y_pos;
v.dst_start.y = y - y_pos;
v.dst_end.x = *x_pos + w + l;
v.dst_end.y = y - y_pos;
v.dst_end.y = y + h - y_pos;
v.src_start.x = glyph.atlas_left;
v.src_start.y = glyph.atlas_top;
@ -336,6 +359,23 @@ DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec
*x_pos += glyph.advance * scale;
}
void
DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, Vec4 col)
{
// Y reversed
Vertex* v = ed.vertices.ptr + ed.ui_count;
v.dst_start.x = p0_x;
v.dst_start.y = p0_y;
v.dst_end.x = p1_x;
v.dst_end.y = p1_y;
v.col = col;
v.border_thickness = border;
v.corner_radius = corner;
v.edge_softness = softness;
AddUIIndices(ed);
}
void
AddUIIndices(Editor* ed)
{

View File

@ -1,18 +1,49 @@
#version 460
#extension GL_GOOGLE_include_directive : require
#extension GL_EXT_debug_printf : require
#include "gui.layout"
layout (location = 0) in struct FragDataIn {
vec4 color;
vec2 uv;
} FragData;
vec2 dst_pos;
vec2 dst_center;
vec2 dst_half_size;
float corner_radius;
float softness;
float raised;
float border_thickness;
} FD;
layout (location = 0) out vec4 FragColor;
float RoundedRectSDF(vec2 pos, vec2 center, vec2 half_size, float radius)
{
vec2 dist = (abs(center - pos) - half_size + vec2(radius));
return min(max(dist.x, dist.y), 0.0) + length(max(dist, 0.0)) - radius;
}
float RoundedRectSDF2(vec2 pos, vec2 center, vec2 size, float radius)
{
return length(max(abs(pos - center) - size + radius, 0.0)) - radius;
}
void main()
{
vec4 tex_color = texture(sampler2D(SpriteAtlas, SamplerNearest), FragData.uv);
FragColor = FragData.color * tex_color;
float softness = FD.softness;
vec2 softness_padding = vec2(max(0, softness*2-1), max(0, softness*2-1));
//float dist = RoundedRectSDF(FD.dst_pos, FD.dst_center, FD.dst_half_size-softness_padding, FD.corner_radius);
float dist = RoundedRectSDF2(FD.dst_pos, FD.dst_center, vec2(1.0), FD.corner_radius);
float sdf_factor = 1.0 - smoothstep(0, 2*softness, dist);
debugPrintfEXT("%v2f %v2f %v2f", FD.dst_pos, FD.dst_center, FD.dst_half_size);
vec4 tex_color = texture(sampler2D(SpriteAtlas, SamplerNearest), FD.uv);
vec4 out_color = FD.color * tex_color * sdf_factor;
FragColor = out_color;
}

View File

@ -5,5 +5,5 @@ layout (set = 0, binding = 1) uniform sampler SamplerNearest;
layout (set = 1, binding = 0) uniform texture2D SpriteAtlas;
layout (push_constant) uniform Constants {
vec2 res;
mat4 projection;
} PC;

View File

@ -4,22 +4,33 @@
#include "gui.layout"
layout (location = 0) in vec2 in_dst_start;
layout (location = 1) in vec2 in_dst_end;
layout (location = 2) in vec2 in_src_start;
layout (location = 3) in vec2 in_src_end;
layout (location = 4) in vec4 in_col;
layout (location = 0) in vec4 in_col;
layout (location = 1) in vec2 in_dst_start;
layout (location = 2) in vec2 in_dst_end;
layout (location = 3) in vec2 in_src_start;
layout (location = 4) in vec2 in_src_end;
layout (location = 5) in float border_thickness;
layout (location = 6) in float corner_radius;
layout (location = 7) in float edge_softness;
layout (location = 8) in float raised;
layout (location = 0) out struct FragDataOut {
vec4 color;
vec2 uv;
vec2 dst_pos;
vec2 dst_center;
vec2 dst_half_size;
float corner_radius;
float softness;
float raised;
float border_thickness;
} FragData;
vec2 Vertices[4] = vec2[4](
vec2(-1.0, +1.0),
vec2(-1.0, -1.0),
vec2(+1.0, +1.0),
vec2(+1.0, -1.0)
vec2(-1.0, +1.0),
vec2(+1.0, -1.0),
vec2(+1.0, +1.0)
);
vec2 rotate(vec2 coords, float theta)
@ -31,9 +42,12 @@ void main()
{
ivec2 tex_size = textureSize(sampler2D(SpriteAtlas, SamplerNearest), 0);
vec2 dst_half_size = (in_dst_end - in_dst_start) / 2;
vec2 dst_center = (in_dst_end + in_dst_start) / 2;
vec2 dst_pos = (Vertices[gl_VertexIndex] * dst_half_size + dst_center);
vec4 pos_start = PC.projection * vec4(in_dst_start.x, in_dst_start.y, 0.0, 1.0);
vec4 pos_end = PC.projection * vec4(in_dst_end.x, in_dst_end.y, 0.0, 1.0);
vec2 half_size = ((pos_end.xy - pos_start.xy) / 2);
vec2 center = ((pos_end.xy + pos_start.xy) / 2);
vec2 pos = (Vertices[gl_VertexIndex] * half_size + center);
vec2 src_half_size = (in_src_end - in_src_start) / 2;
vec2 src_center = (in_src_end + in_src_start) / 2;
@ -48,9 +62,13 @@ void main()
FragData.color = in_col;
FragData.uv = uvs[gl_VertexIndex] / tex_size;
FragData.dst_pos = pos;
FragData.dst_center = center;
FragData.dst_half_size = half_size;
FragData.corner_radius = corner_radius;
FragData.softness = edge_softness;
FragData.raised = raised;
FragData.border_thickness = border_thickness;
gl_Position = vec4(2 * dst_pos.x / PC.res.x - 1,
2 * dst_pos.y / PC.res.y - 1,
0,
1);
gl_Position = vec4(pos.x, pos.y, 0, 1);
}