diff --git a/client/Makefile b/client/Makefile index 0bed5d8..0c19234 100644 --- a/client/Makefile +++ b/client/Makefile @@ -59,10 +59,10 @@ debug: roleplay $(EXTRA_DEBUG_REQUIREMENTS) $(SPV_FILES) $(GDB) roleplay %.vert.spv: %.vert - glslangValidator -V -o $@ $< + glslc -o $@ $< %.frag.spv: %.frag - glslangValidator -V -o $@ $< + glslc -o $@ $< %.comp.spv: %.comp - glslangValidator -V -o $@ $< + glslc -o $@ $< diff --git a/client/include/ui.h b/client/include/ui.h index 9a58d74..b95f1da 100644 --- a/client/include/ui.h +++ b/client/include/ui.h @@ -67,25 +67,6 @@ typedef struct UIStringStruct { uint32_t length; } UIString; -typedef struct UIlayerStorageStruct { - VkBuffer strings; - VkBuffer codes; - VkBuffer drawables; - VkBuffer layer; - - VmaAllocation strings_memory; - VmaAllocation drawables_memory; - VmaAllocation codes_memory; - VmaAllocation layer_memory; - - VkDeviceAddress address; - - uint32_t max_strings; - uint32_t max_codes; - uint32_t max_drawables; - uint32_t drawable_count; -} UILayerStorage; - typedef struct UIDrawableStruct { vec2 pos; vec2 size; @@ -104,12 +85,49 @@ typedef struct UILayerStruct { DispatchCommand dispatch_strings; uint32_t font_index; - uint32_t drawable_count; + uint32_t max_drawables; + uint32_t max_codes; + uint32_t max_strings; + uint32_t num_drawables; + + VkDeviceAddress container; } UILayer; +typedef struct UIlayerStorageStruct { + VkBuffer strings; + VkBuffer codes; + VkBuffer drawables; + VkBuffer layer; + + VmaAllocation strings_memory; + VmaAllocation drawables_memory; + VmaAllocation codes_memory; + VmaAllocation layer_memory; + + VkDeviceAddress address; + + UILayer data; +} UILayerStorage; + +typedef struct UIContainerStruct { + vec2 pos; + vec2 size; +} UIContainer; + +typedef struct UIContainerStorageStruct { + VkBuffer container; + + VmaAllocation container_memory; + + VkDeviceAddress address; + + UIContainer data; +} UIContainerStorage; + typedef struct UIContextStruct { VkDeviceAddress font_infos; - mat4 screen; + vec2 screen; + vec2 scale; } UIContext; typedef struct UIContextStorageStruct { @@ -129,6 +147,8 @@ typedef struct UIContextStorageStruct { GraphicsPipeline pipeline; ComputePipeline string_pipeline; + + UIContext data; } UIContextStorage; VkResult create_ui_context( @@ -155,6 +175,17 @@ VkResult load_font( VkBool32 antialias, FontStorage* memory); +VkResult create_container( + float x, + float y, + float width, + float height, + VkDevice device, + VmaAllocator allocator, + VkCommandPool transfer_pool, + Queue transfer_queue, + UIContainerStorage* memory); + VkResult create_layer( uint32_t max_strings, uint32_t max_codes, @@ -164,5 +195,37 @@ VkResult create_layer( VmaAllocator allocator, VkCommandPool transfer_pool, Queue transfer_queue, + UIContainerStorage* container, UILayerStorage* memory); + +void set_ui_rect( + float x, + float y, + float width, + float height, + float r, + float g, + float b, + float a, + UIDrawable* drawable); + +void set_ui_string( + float x, + float y, + float size, + float r, + float g, + float b, + float a, + uint32_t length, + uint32_t offset, + UIString* string); + +VkResult set_ui_codes( + const char * text, + uint32_t* buffer, + uint32_t offset, + uint32_t* charmap, + uint32_t charmap_size); + #endif diff --git a/client/shader_src/string.comp b/client/shader_src/string.comp index af76c70..73e2aa7 100644 --- a/client/shader_src/string.comp +++ b/client/shader_src/string.comp @@ -1,93 +1,11 @@ #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; -}; +#include "ui_common.glsl" layout(std430, push_constant) uniform PushConstant { - UIContext context; - UILayer layer; + Context context; + Layer layer; } pc; layout(local_size_x = 1) in; diff --git a/client/shader_src/ui.frag b/client/shader_src/ui.frag index 0779f76..d9f9e9c 100644 --- a/client/shader_src/ui.frag +++ b/client/shader_src/ui.frag @@ -1,5 +1,13 @@ #version 450 -#extension GL_EXT_nonuniform_qualifier : enable +#extension GL_EXT_nonuniform_qualifier : require +#extension GL_EXT_buffer_reference : require + +#include "ui_common.glsl" + +layout(std430, push_constant) uniform PushConstant { + Context context; + Layer layer; +} pc; layout(set = 0, binding = 0) uniform sampler font_samplers[]; layout(set = 1, binding = 0) uniform texture2DArray font_textures[]; @@ -13,6 +21,13 @@ layout(location = 4) flat in uint type; layout(location = 0) out vec4 outColor; void main() { + vec2 pos = gl_FragCoord.xy - vec2(0.5, 0.5); + vec2 min = pc.layer.container.pos; + vec2 max = min + pc.layer.container.size; + if(pos.x < min.x || pos.y < min.y + || pos.x > max.x || pos.y > max.y) { + discard; + } if(type == 0) { outColor = fragColor; } else if(type == 1) { diff --git a/client/shader_src/ui.vert b/client/shader_src/ui.vert index b01cd5e..5be859c 100644 --- a/client/shader_src/ui.vert +++ b/client/shader_src/ui.vert @@ -1,91 +1,11 @@ #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; -}; +#include "ui_common.glsl" layout(std430, push_constant) uniform PushConstant { - UIContext context; - UILayer layer; + Context context; + Layer layer; } pc; layout(location = 0) out vec4 fragColor; @@ -104,24 +24,28 @@ const vec2 square[6] = { }; void main() { + vec2 scale = pc.context.scale / pc.context.screen; Drawable drawable = pc.layer.drawables.d[gl_InstanceIndex]; + vec2 pos = square[gl_VertexIndex]; 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); + float scalex = float(symbol.width)/float(font.width); + float scaley = float(symbol.height)/float(font.height); + float offx = float(symbol.left)/float(font.width); + float offy = float(symbol.top)/float(font.height); + + fragUV = pos * vec2(scalex, scaley); + pos = pos * vec2(scalex, scaley) + vec2(offx, -offy); } + gl_Position = vec4((pos * drawable.size + drawable.pos + pc.layer.container.pos) * scale, 0.0, 1.0) - vec4(1.0, 1.0, 0.0, 0.0); + fragColor = drawable.color; code = drawable.code; type = drawable.type; diff --git a/client/shader_src/ui_common.glsl b/client/shader_src/ui_common.glsl new file mode 100644 index 0000000..c6565eb --- /dev/null +++ b/client/shader_src/ui_common.glsl @@ -0,0 +1,95 @@ +struct DrawCommand { + uint vertex_count; + uint instance_count; + uint fist_vertex; + uint first_instance; +}; + +layout(std430, buffer_reference) buffer DrawCommandList { + DrawCommand d[]; +}; + +struct DispatchCommand { + uint x; + uint y; + uint z; +}; + +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[]; +}; + +struct String { + vec2 pos; + vec4 color; + float size; + uint offset; + uint len; +}; + +layout(std430, buffer_reference) readonly buffer StringList { + String s[]; +}; + +layout(std430, buffer_reference) readonly buffer CodeList { + uint c[]; +}; + +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 Container { + vec2 pos; + vec2 size; +}; + +layout(std430, buffer_reference) readonly buffer Layer { + StringList strings; + CodeList codes; + DrawableList drawables; + + DrawCommand draw; + DispatchCommand dispatch; + + uint font_index; + uint max_drawables; + uint max_codes; + uint max_strings; + uint num_drawables; + + Container container; +}; + +layout(std430, buffer_reference) buffer Context { + FontList fonts; + vec2 screen; + vec2 scale; +}; diff --git a/client/src/main.c b/client/src/main.c index 318ffda..38e2f47 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -13,6 +13,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) { FT_Library library; UIContextStorage ui; + UIContainerStorage container; UILayerStorage layers[2]; FontStorage font; @@ -40,8 +41,10 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) { VK_RESULT(load_font(render->device, render->allocator, &ui, 0, render->transfer_pool, render->transfer_queue, library, "test.ttf", 16, VK_TRUE, &font)); - VK_RESULT(create_layer(10, 100, 200, 0, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &layers[0])); - VK_RESULT(create_layer(10, 100, 200, 0, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &layers[1])); + VK_RESULT(create_container(100, 100, 200, 200, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &container)); + + VK_RESULT(create_layer(10, 100, 10, 0, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &container, &layers[0])); + VK_RESULT(create_layer(10, 100, 10, 0, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &container, &layers[1])); VK_RESULT(create_transfer_buffer(render->allocator, 2*sizeof(uint32_t) + 2*sizeof(UIDrawable) + sizeof(UIString) + 100*sizeof(uint32_t), &transfer, &transfer_memory, &mapped)); @@ -49,44 +52,17 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) { mapped_count[0] = 1; mapped_count[1] = 1; UIDrawable* mapped_drawable = (UIDrawable*)(mapped + 2*sizeof(uint32_t)); - mapped_drawable[0].pos[0] = 0.0; - mapped_drawable[0].pos[1] = 0.0; - mapped_drawable[0].size[0] = 200.0; - mapped_drawable[0].size[1] = 200.0; - mapped_drawable[0].color[0] = 1.0; - mapped_drawable[0].color[1] = 0.0; - mapped_drawable[0].color[2] = 0.0; - mapped_drawable[0].color[3] = 1.0; - mapped_drawable[0].type = 0; - - mapped_drawable[1].pos[0] = 200.0; - mapped_drawable[1].pos[1] = 0.0; - mapped_drawable[1].size[0] = 200.0; - mapped_drawable[1].size[1] = 200.0; - mapped_drawable[1].color[0] = 0.0; - mapped_drawable[1].color[1] = 1.0; - mapped_drawable[1].color[2] = 0.0; - mapped_drawable[1].color[3] = 1.0; - mapped_drawable[1].type = 0; + set_ui_rect( 0.0, 0.0, 100.0, 200.0, 1.0, 0.0, 0.0, 1.0, &mapped_drawable[0]); + set_ui_rect(100.0, 0.0, 100.0, 200.0, 0.0, 1.0, 0.0, 1.0, &mapped_drawable[1]); UIString* mapped_string = (UIString*)(mapped + 2*sizeof(uint32_t) + 2*sizeof(UIDrawable)); - mapped_string->pos[0] = 0.0; - mapped_string->pos[1] = 200.0; - mapped_string->size = 100.0; - mapped_string->color[0] = 1.0; - mapped_string->color[1] = 1.0; - mapped_string->color[2] = 1.0; - mapped_string->color[3] = 1.0; - mapped_string->length = 100; - mapped_string->offset = 0; + set_ui_string(0.0, 100.0, 16.0, 1.0, 1.0, 1.0, 1.0, 5, 0, &mapped_string[0]); uint32_t* mapped_codes = (uint32_t*)(mapped + 2*sizeof(uint32_t) + 2*sizeof(UIDrawable) + sizeof(UIString)); - for(uint32_t i = 0; i < 100; i++) { - mapped_codes[i] = i; - } + VK_RESULT(set_ui_codes("Hello", mapped_codes, 0, font.charmap, font.num_symbols)); VkCommandBuffer command_buffer = command_begin_single(render->device, render->transfer_pool); - command_copy_buffer(command_buffer, transfer, layers[0].layer, 0, offsetof(UILayer, drawable_count), sizeof(uint32_t)); - command_copy_buffer(command_buffer, transfer, layers[1].layer, 0, offsetof(UILayer, drawable_count), sizeof(uint32_t)); + command_copy_buffer(command_buffer, transfer, layers[0].layer, 0, offsetof(UILayer, num_drawables), sizeof(uint32_t)); + command_copy_buffer(command_buffer, transfer, layers[1].layer, 0, offsetof(UILayer, num_drawables), sizeof(uint32_t)); command_copy_buffer(command_buffer, transfer, layers[1].layer, sizeof(uint32_t), offsetof(UILayer, dispatch_strings) + offsetof(DispatchCommand, x), sizeof(uint32_t)); command_copy_buffer(command_buffer, transfer, layers[0].drawables, 2*sizeof(uint32_t), 0, sizeof(UIDrawable)); diff --git a/client/src/render.c b/client/src/render.c index 35a761c..33003ef 100644 --- a/client/src/render.c +++ b/client/src/render.c @@ -1051,7 +1051,7 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, }; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &draw_command_barrier_1, 0, NULL); - command_copy_buffer(command_buffer, layers[i].layer, layers[i].layer, offsetof(UILayer, drawable_count), offsetof(UILayer, draw) + offsetof(DrawCommand, instance_count), sizeof(uint32_t)); + command_copy_buffer(command_buffer, layers[i].layer, layers[i].layer, offsetof(UILayer, num_drawables), offsetof(UILayer, draw) + offsetof(DrawCommand, instance_count), sizeof(uint32_t)); VkBufferMemoryBarrier draw_command_barrier_2 = { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .buffer = layers[i].layer, @@ -1077,7 +1077,7 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .buffer = layers[i].drawables, .offset = 0, - .size = sizeof(UIDrawable)*layers[i].max_drawables, + .size = sizeof(UIDrawable)*layers[i].data.max_drawables, .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, }; diff --git a/client/src/ui.c b/client/src/ui.c index 99262d8..f715067 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -273,6 +273,41 @@ VkResult create_ui_pipeline( return VK_SUCCESS; } +VkResult create_container( + float x, + float y, + float width, + float height, + VkDevice device, + VmaAllocator allocator, + VkCommandPool transfer_pool, + Queue transfer_queue, + UIContainerStorage* memory) { + VkResult result; + + VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIContainer), &memory->container, &memory->container_memory)); + + VkBuffer transfer; + VmaAllocation transfer_memory; + void* mapped; + VK_RESULT(create_transfer_buffer(allocator, sizeof(UIContainer), &transfer, &transfer_memory, &mapped)); + + memory->data.pos[0] = x; + memory->data.pos[1] = y; + memory->data.size[0] = width; + memory->data.size[1] = height; + memcpy(mapped, &memory->data, sizeof(UIContainer)); + + VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); + command_copy_buffer(command_buffer, transfer, memory->container, 0, 0, sizeof(UIContainer)); + VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue)); + destroy_transfer_buffer(allocator, transfer, transfer_memory); + + memory->address = buffer_address(device, memory->container); + + return VK_SUCCESS; +} + VkResult create_layer( uint32_t max_strings, uint32_t max_codes, @@ -282,39 +317,40 @@ VkResult create_layer( VmaAllocator allocator, VkCommandPool transfer_pool, Queue transfer_queue, + UIContainerStorage* container, UILayerStorage* memory) { VkResult result; - memory->max_strings = max_strings; - memory->max_codes = max_codes; - memory->max_drawables = max_drawables; - VK_RESULT(create_storage_buffer(allocator, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, sizeof(UILayer), &memory->layer, &memory->layer_memory)); VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIString)*max_strings, &memory->strings, &memory->strings_memory)) - VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIDrawable)*max_drawables, &memory->drawables, &memory->drawables_memory)); + VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIDrawable)*(max_drawables + max_codes), &memory->drawables, &memory->drawables_memory)); VK_RESULT(create_storage_buffer(allocator, 0, sizeof(uint32_t)*max_codes, &memory->codes, &memory->codes_memory)); VkBuffer transfer; VmaAllocation transfer_memory; - UILayer* mapped; - VK_RESULT(create_transfer_buffer(allocator, sizeof(UILayer), &transfer, &transfer_memory, (void**)&mapped)); + void* mapped; + VK_RESULT(create_transfer_buffer(allocator, sizeof(UILayer), &transfer, &transfer_memory, &mapped)); - mapped->strings = buffer_address(device, memory->strings); - mapped->codes = buffer_address(device, memory->codes); + memory->data.strings = buffer_address(device, memory->strings); + memory->data.codes = buffer_address(device, memory->codes); - mapped->drawables = buffer_address(device, memory->drawables); + memory->data.drawables = buffer_address(device, memory->drawables); - mapped->draw.first_vertex = 0; - mapped->draw.vertex_count = 6; - mapped->draw.first_instance = 0; - mapped->draw.instance_count = 0; + memory->data.draw.first_vertex = 0; + memory->data.draw.vertex_count = 6; + memory->data.draw.first_instance = 0; + memory->data.draw.instance_count = 0; - mapped->dispatch_strings.x = 0; - mapped->dispatch_strings.y = 1; - mapped->dispatch_strings.z = 1; + memory->data.dispatch_strings.x = 0; + memory->data.dispatch_strings.y = 1; + memory->data.dispatch_strings.z = 1; - mapped->font_index = font_index; - mapped->drawable_count = 0; + memory->data.font_index = font_index; + memory->data.max_drawables = max_drawables; + memory->data.max_strings = max_strings; + memory->data.num_drawables = 0; + memory->data.container = container->address; + memcpy(mapped, &memory->data, sizeof(UILayer)); VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); command_copy_buffer(command_buffer, transfer, memory->layer, 0, 0, sizeof(UILayer)); @@ -717,14 +753,12 @@ VkResult create_ui_context( VK_RESULT(create_transfer_buffer(allocator, sizeof(UIContext), &transfer, &transfer_memory, (void**)&mapped)); - mapped->font_infos = buffer_address(device, memory->font_infos); - vec3 screen_offset = {-1.0, -1.0, 0.0}; - vec3 screen_scale = { - 1.0/(float)swapchain_extent.width*window_scale[0], - 1.0/(float)swapchain_extent.height*window_scale[1], 1.0}; - glm_mat4_identity(mapped->screen); - glm_translate(mapped->screen, screen_offset); - glm_scale(mapped->screen, screen_scale); + memory->data.font_infos = buffer_address(device, memory->font_infos); + memory->data.screen[0] = swapchain_extent.width; + memory->data.screen[1] = swapchain_extent.height; + memory->data.scale[0] = window_scale[0]; + memory->data.scale[1] = window_scale[1]; + memcpy(mapped, &memory->data, sizeof(UIContext)); VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); command_copy_buffer(command_buffer, transfer, memory->context, 0, 0, sizeof(UIContext)); @@ -738,3 +772,72 @@ VkResult create_ui_context( return VK_SUCCESS; } + +void set_ui_rect( + float x, + float y, + float width, + float height, + float r, + float g, + float b, + float a, + UIDrawable* drawable) { + drawable->pos[0] = x; + drawable->pos[1] = y; + drawable->size[0] = width; + drawable->size[1] = height; + drawable->color[0] = r; + drawable->color[1] = g; + drawable->color[2] = b; + drawable->color[3] = a; + drawable->type = 0; + drawable->code = 0; +} + +void set_ui_string( + float x, + float y, + float size, + float r, + float g, + float b, + float a, + uint32_t length, + uint32_t offset, + UIString* string) { + string->pos[0] = x; + string->pos[1] = y; + string->size = size; + string->color[0] = r; + string->color[1] = g; + string->color[2] = b; + string->color[3] = a; + string->length = length; + string->offset = offset; +} + +VkResult set_ui_codes( + const char * text, + uint32_t* buffer, + uint32_t offset, + uint32_t* charmap, + uint32_t charmap_size) { + size_t i = 0; + while(text[i] != '\0') { + uint32_t mapped = 0xFFFFFFFF; + for(uint32_t j = 0; j < charmap_size; j++) { + if(charmap[j] == (uint32_t)text[i]) { + mapped = j; + break; + } + } + if(mapped == 0xFFFFFFFF) { + return VK_ERROR_UNKNOWN; + } + buffer[i] = mapped; + i += 1; + } + + return VK_SUCCESS; +}