#version 450 #extension GL_EXT_buffer_reference : require struct String { vec2 pos; vec4 color; float size; uint offset; uint len; }; layout(std430, buffer_reference) readonly buffer StringList { String s[]; }; struct Drawable { vec2 pos; vec2 size; vec4 color; uint type; uint code; }; layout(std430, buffer_reference) writeonly buffer DrawableList { Drawable d[]; }; layout(std430, buffer_reference) readonly buffer CodeList { uint c[]; }; struct DrawCommand { uint vertex_count; uint instance_count; uint fist_vertex; uint first_instance; }; struct DispatchCommand { uint x; uint y; uint z; }; layout(std430, buffer_reference) buffer UILayer { StringList strings; CodeList codes; DrawableList drawables; DrawCommand draw; DispatchCommand dispatch; uint font_index; uint drawable_count; }; struct Symbol { int top; uint left; uint width; uint height; uint advance; }; layout(std430, buffer_reference) buffer SymbolList { Symbol s[]; }; struct Font { SymbolList symbols; uint num_symbols; uint width; uint height; }; layout(std430, buffer_reference) buffer FontList { Font f[]; }; layout(std430, buffer_reference) buffer UIContext { FontList fonts; mat4 screen; }; layout(std430, push_constant) uniform PushConstant { UIContext context; UILayer layer; } pc; layout(local_size_x = 1) in; void main() { uint gID = gl_GlobalInvocationID.x; String string = pc.layer.strings.s[gID]; Font font = pc.context.fonts.f[pc.layer.font_index]; uint buffer_pos = atomicAdd(pc.layer.draw.instance_count, string.len); float x = 0; for(uint i = 0; i < string.len; i++) { uint code = pc.layer.codes.c[string.offset + i]; Symbol symbol = font.symbols.s[code]; pc.layer.drawables.d[buffer_pos + i].pos = string.pos + vec2(x, 0); x += string.size*symbol.advance/font.width; pc.layer.drawables.d[buffer_pos + i].size = vec2(string.size, string.size); pc.layer.drawables.d[buffer_pos + i].color = string.color; pc.layer.drawables.d[buffer_pos + i].code = pc.layer.codes.c[string.offset + i]; pc.layer.drawables.d[buffer_pos + i].type = 1; } }