#version 450 #extension GL_EXT_buffer_reference : require struct String { vec2 pos; vec4 color; float size; uint offset; uint length; }; 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) readonly 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(location = 0) out vec4 fragColor; layout(location = 1) out vec2 fragUV; layout(location = 2) out uint code; layout(location = 3) out uint index; layout(location = 4) out uint type; const vec2 square[6] = { vec2(0.0, 0.0), vec2(1.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 0.0), vec2(1.0, 1.0), vec2(0.0, 1.0), }; void main() { Drawable drawable = pc.layer.drawables.d[gl_InstanceIndex]; if(drawable.type == 0) { // Rect gl_Position = pc.context.screen * vec4(square[gl_VertexIndex] * drawable.size + drawable.pos, 0.0, 1.0); } else if(drawable.type == 1){ // Glyph Font font = pc.context.fonts.f[pc.layer.font_index]; Symbol symbol = font.symbols.s[drawable.code]; float fragU = square[gl_VertexIndex].x * symbol.width/font.width; float fragV = square[gl_VertexIndex].y * symbol.height/font.height; float x = (square[gl_VertexIndex].x * symbol.width + symbol.left) * drawable.size.x / font.width; float y = (square[gl_VertexIndex].y * symbol.height - symbol.top) * drawable.size.x / font.height; fragUV = vec2(fragU, fragV); gl_Position = pc.context.screen * vec4(vec2(x, y) + drawable.pos, 0.0, 1.0); } fragColor = drawable.color; code = drawable.code; type = drawable.type; index = pc.layer.font_index; }