gui shader set up

This commit is contained in:
Matthew 2025-08-25 06:07:55 +10:00
parent 775f341a65
commit 19c28de4fd
9 changed files with 91 additions and 42 deletions

View File

@ -2,3 +2,4 @@
src/VulkanRenderer/vma
src/DLibs/external
build
assets

Binary file not shown.

Binary file not shown.

View File

@ -16,7 +16,7 @@
"versions": ["VK_DEBUG_PRINTF"],
"preGenerateCommands-linux": ["./build.sh"],
"preGenerateCommands-windows": [],
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-Jbuild"],
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-Jbuild", "-Jassets"],
"dflags-dmd": ["-P=-DSTBI_NO_SIMD"]
},
]

@ -1 +1 @@
Subproject commit e5f47772a5d879f3cd5848108761271876bbef0e
Subproject commit 5c2a3ab5efa1aaa15ca6f3144655550dd024823a

@ -1 +1 @@
Subproject commit f8d1707450d92bd147a3283527043c86312b3872
Subproject commit f211a29857111a6be26b9cb0e9799ffcb7631df6

View File

@ -10,6 +10,10 @@ import buffer;
import std.stdio;
import std.exception;
const u8[] FONT_BYTES = import("pc-9800.ttf");
const u8[] VERTEX_BYTES = import("gui.vert.spv");
const u8[] FRAGMENT_BYTES = import("gui.frag.spv");
const UI_COUNT = 50000;
struct Editor
@ -52,7 +56,7 @@ struct PushConst
struct Vertex
{
Vec4 col;
Vec4[4] cols;
Vec2 dst_start;
Vec2 dst_end;
Vec2 src_start;
@ -76,7 +80,8 @@ Cycle(Editor* ed)
//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));
DrawRect(ed, 450.0, 450.0, 550.0, 550.0, 0.0, 5.0, 1.0, 20.0, [Vec4(0.2, 0.5, 0.9, 1.0), Vec4(Vec3(0.8), 1.0), Vec4(Vec3(0.8), 1.0), Vec4(Vec3(0.6), 1.0)]);
DrawRect(ed, 450.0, 450.0, 550.0, 550.0, 2.0, 5.0, 1.0, 20.0, [Vec4(Vec3(0.0), 1.0), Vec4(Vec3(0.0), 1.0), Vec4(Vec3(0.0), 1.0), Vec4(Vec3(0.0), 1.0)]);
BeginFrame(&ed.rd);
@ -142,8 +147,7 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
Arena arena = CreateArena(MB(32));
u8[] font_data = LoadFile(&arena, "assets/pc-9800.ttf");
FontFace font = OpenFont(font_data);
FontFace font = OpenFont(cast(u8[])FONT_BYTES);
FontAtlasBuf atlas_buf = CreateAtlas(&arena, font, 14.0, 256);
Editor editor = {
@ -151,7 +155,7 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
arena: arena,
temp_arena: CreateArena(MB(8)),
rd: InitRenderer(handles, MB(32), MB(16)),
font_data: font_data,
font_data: cast(u8[])FONT_BYTES,
font: font,
atlas_buf: atlas_buf,
buffers: MAllocArray!(FlatBuffer)(32),
@ -182,21 +186,24 @@ 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[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 },
Attribute[12] attributes = [
{ binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 0},
{ binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 1},
{ binding: 0, location: 2, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 2},
{ binding: 0, location: 3, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 3},
{ binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof },
{ binding: 0, location: 5, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof },
{ binding: 0, location: 6, format: FMT.RG_F32, offset: Vertex.src_start.offsetof },
{ binding: 0, location: 7, format: FMT.RG_F32, offset: Vertex.src_end.offsetof },
{ binding: 0, location: 8, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof },
{ binding: 0, location: 9, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof },
{ binding: 0, location: 10, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof },
{ binding: 0, location: 11, format: FMT.R_F32, offset: Vertex.raised.offsetof },
];
GfxPipelineInfo ui_info = {
vertex_shader: LoadFile(&editor.temp_arena, "assets/gui.vert.spv"),
frag_shader: LoadFile(&editor.temp_arena, "assets/gui.frag.spv"),
vertex_shader: cast(u8[])VERTEX_BYTES,
frag_shader: cast(u8[])FRAGMENT_BYTES,
input_rate: IR.Instance,
input_rate_stride: Vertex.sizeof,
layout: editor.pipeline_layout,
@ -220,6 +227,8 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
Write(&editor.rd, editor.desc_set, &editor.font_atlas, 0, DT.Image);
SetClearColors(&editor.rd, [0.149, 0.607, 0.768, 1.0], [0.0, 0.0, 0.0, 0.0]);
Reset(&editor.temp_arena);
return editor;
@ -351,7 +360,10 @@ DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec
v.src_end.x = glyph.atlas_right;
v.src_end.y = glyph.atlas_bottom;
v.col = col;
v.cols[0] = col;
v.cols[1] = col;
v.cols[2] = col;
v.cols[3] = col;
AddUIIndices(ed);
}
@ -360,7 +372,7 @@ DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec
}
void
DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, Vec4 col)
DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, f32 raised, Vec4[4] cols)
{
// Y reversed
Vertex* v = ed.vertices.ptr + ed.ui_count;
@ -368,10 +380,11 @@ DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 cor
v.dst_start.y = p0_y;
v.dst_end.x = p1_x;
v.dst_end.y = p1_y;
v.col = col;
v.cols = cols;
v.border_thickness = border;
v.corner_radius = corner;
v.edge_softness = softness;
v.raised = raised;
AddUIIndices(ed);
}

View File

@ -25,9 +25,19 @@ float RoundedRectSDF(vec2 pos, vec2 center, vec2 half_size, float 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)
float ToSRGB(float col)
{
return length(max(abs(pos - center) - size + radius, 0.0)) - radius;
return pow(col, 1.0/2.2);
}
vec4 ToSRGB(vec4 col)
{
return vec4(ToSRGB(col.r), ToSRGB(col.g), ToSRGB(col.b), col.a);
}
vec4 ToLinear(vec4 col)
{
return pow(col, vec4(vec3(2.2), 1.0));
}
void main()
@ -35,15 +45,29 @@ void main()
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 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 %f", FD.dst_pos, FD.dst_center, FD.dst_half_size, sdf_factor);
float border_factor = 1.0;
if (FD.border_thickness != 0.0)
{
vec2 interior_half_size = FD.dst_half_size - vec2(FD.border_thickness);
float interior_radius_reduce_f = min(interior_half_size.x/FD.dst_half_size.x, interior_half_size.y/FD.dst_half_size.y);
float interior_corner_radius = FD.corner_radius * interior_radius_reduce_f * interior_radius_reduce_f;
float inside_d = RoundedRectSDF(FD.dst_pos, FD.dst_center, interior_half_size-softness_padding, interior_corner_radius);
float inside_f = smoothstep(0, 2*softness, inside_d);
border_factor = inside_f;
}
vec4 tex_color = texture(sampler2D(SpriteAtlas, SamplerNearest), FD.uv);
vec4 out_color = FD.color * tex_color * sdf_factor;
debugPrintfEXT("tex_color %v4f", tex_color);
vec4 out_color = FD.color * tex_color * sdf_factor * border_factor;
FragColor = out_color;
}

View File

@ -4,15 +4,18 @@
#include "gui.layout"
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) in vec4 in_col_1;
layout (location = 1) in vec4 in_col_2;
layout (location = 2) in vec4 in_col_3;
layout (location = 3) in vec4 in_col_4;
layout (location = 4) in vec2 in_dst_start;
layout (location = 5) in vec2 in_dst_end;
layout (location = 6) in vec2 in_src_start;
layout (location = 7) in vec2 in_src_end;
layout (location = 8) in float border_thickness;
layout (location = 9) in float corner_radius;
layout (location = 10) in float edge_softness;
layout (location = 11) in float raised;
layout (location = 0) out struct FragDataOut {
vec4 color;
@ -42,8 +45,8 @@ void main()
{
ivec2 tex_size = textureSize(sampler2D(SpriteAtlas, SamplerNearest), 0);
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);
vec4 pos_start = vec4(in_dst_start.x, in_dst_start.y - raised, 0.0, 1.0);
vec4 pos_end = 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);
@ -60,7 +63,14 @@ void main()
vec2(in_src_end.x, in_src_end.y)
);
FragData.color = in_col;
vec4 cols[4] = vec4[4](
in_col_1,
in_col_2,
in_col_3,
in_col_4
);
FragData.color = cols[gl_VertexIndex];
FragData.uv = uvs[gl_VertexIndex] / tex_size;
FragData.dst_pos = pos;
FragData.dst_center = center;
@ -70,5 +80,6 @@ void main()
FragData.raised = raised;
FragData.border_thickness = border_thickness;
gl_Position = vec4(pos.x, pos.y, 0, 1);
vec4 v_pos = PC.projection * vec4(pos.x, pos.y, 0, 1);
gl_Position = vec4(v_pos.x, v_pos.y, 0, 1);
}