#version 450 #extension GL_EXT_buffer_reference : require struct Symbol { int top; uint left; uint width; uint height; uint advance; }; struct Character { vec3 pos; vec4 color; float size; uint code; }; struct String { vec3 pos; vec4 color; float size; uint offset; uint len; }; layout(buffer_reference, std430) readonly buffer SymbolList{ Symbol symbols[]; }; layout(buffer_reference, std430) writeonly buffer CharacterList{ Character characters[]; }; layout(buffer_reference, std430) readonly buffer Characters{ uint codes[]; }; layout(buffer_reference, std430) readonly buffer Strings{ String strings[]; }; layout(set = 0, binding = 0) uniform Font { uint num_symbols; uint width; uint height; SymbolList symbol_list; } font; layout(buffer_reference, std430) buffer DrawCommand { uint vertex_count; uint instance_count; uint first_vertx; uint first_instance; }; layout(buffer_reference, std430) readonly buffer Pointers { Strings strings; Characters codes; CharacterList characters; DrawCommand draw; }; layout(std430, push_constant) uniform Push { Pointers pointers; } push; layout(local_size_x = 1) in; void main() { uint gID = gl_GlobalInvocationID.x; String string = push.pointers.strings.strings[gID]; uint buffer_pos = atomicAdd(push.pointers.draw.instance_count, string.len); float x = 0; for(uint i = 0; i < string.len; i++) { Symbol symbol = font.symbol_list.symbols[push.pointers.codes.codes[string.offset + i]]; push.pointers.characters.characters[buffer_pos + i].pos = string.pos + vec3(x, 0, 0); x += string.size*symbol.advance/font.width; push.pointers.characters.characters[buffer_pos + i].size = string.size; push.pointers.characters.characters[buffer_pos + i].color = string.color; push.pointers.characters.characters[buffer_pos + i].code = push.pointers.codes.codes[string.offset + i]; } }