diff --git a/client/include/pipeline.h b/client/include/pipeline.h index 55572ed..5ce2936 100644 --- a/client/include/pipeline.h +++ b/client/include/pipeline.h @@ -32,6 +32,8 @@ typedef struct FontUniformStruct { uint32_t num_symbols; uint32_t width; uint32_t height; + uint32_t space_width; + VkDeviceAddress symbol_list; } FontUniform; typedef struct SymbolInfoStruct { @@ -42,9 +44,7 @@ typedef struct SymbolInfoStruct { typedef struct FontDataStruct { FontUniform info; - SymbolInfo* symbols; - uint32_t* codes; - uint32_t* data; + uint16_t* codes; } FontData; typedef struct FontDescriptorStruct { @@ -95,6 +95,6 @@ typedef struct UIContextStruct { VkResult init_pipelines(VkDevice device, VmaAllocator allocator, VkExtent2D swapchain_extent, VkRenderPass render_pass, Queue transfer_queue, VkCommandPool transfer_pool, UIContext* context); -VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayout layout, VkDescriptorPool pool, FontData* font, VkCommandPool transfer_pool, Queue transfer_queue, FontDescriptor* descriptor); +VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayout layout, VkDescriptorPool pool, FontData* font, SymbolInfo* symbols, uint32_t* atlas, VkCommandPool transfer_pool, Queue transfer_queue, FontDescriptor* descriptor); #endif diff --git a/client/shader_src/ui_text.vert b/client/shader_src/ui_text.vert index e7a8c87..87afc63 100644 --- a/client/shader_src/ui_text.vert +++ b/client/shader_src/ui_text.vert @@ -1,14 +1,26 @@ #version 450 +#extension GL_EXT_buffer_reference : require + +struct Symbol { + uint x; + uint top; + uint width; +}; + +layout(buffer_reference, std430) readonly buffer SymbolList{ + Symbol symbols[]; +}; layout(set = 0, binding = 0) uniform UIUniform { mat4 screen; } ubo; layout(set = 1, binding = 0) uniform FontUniform { - vec2 size; - uint cols; - uint rows; - uint start; + uint num_symbols; + uint width; + uint height; + uint space_width; + SymbolList symbol_list; } font; layout(location = 0) in vec2 inVertexPosition; @@ -21,9 +33,7 @@ layout(location = 0) out vec4 fragColor; layout(location = 1) out vec2 fragUV; void main() { - float row = floor(code/font.cols); - float col = code - row*font.cols; - fragUV = (vec2(col, row) + inVertexPosition) / vec2(font.cols, font.rows); + fragUV = inVertexPosition; fragColor = inColor; gl_Position = ubo.screen * vec4(vec3(inVertexPosition * inSize, 0.0) + inPosition, 1.0); } diff --git a/client/src/main.c b/client/src/main.c index 53004da..d28f66e 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -14,7 +14,7 @@ ColoredRect colored_rect(float width, float height, float r, float g, float b, f return rect; } -VkResult load_font(const char* atlas_file, const char* metadata_file, FontData* font) { +VkResult load_font(const char* atlas_file, const char* metadata_file, FontData* font, SymbolInfo** symbols, uint32_t** image) { FILE* atlas = fopen(atlas_file, "rb"); if(atlas == NULL) { return VK_ERROR_UNKNOWN; @@ -44,9 +44,9 @@ VkResult load_font(const char* atlas_file, const char* metadata_file, FontData* return VK_ERROR_UNKNOWN; } - font->data = malloc(out_size); + *image = malloc(out_size); - result = spng_decode_image(ctx, font->data, out_size, SPNG_FMT_RGBA8, 0); + result = spng_decode_image(ctx, *image, out_size, SPNG_FMT_RGBA8, 0); if(result != SPNG_OK) { return VK_ERROR_UNKNOWN; } @@ -66,6 +66,32 @@ VkResult load_font(const char* atlas_file, const char* metadata_file, FontData* if(atlas == NULL) { return VK_ERROR_UNKNOWN; } + uint16_t symbol_count; + uint8_t ascent, descent; + fread(&symbol_count, 2, 1, metadata); + fread(&ascent, 1, 1, metadata); + fread(&descent, 1, 1, metadata); + + font->info.num_symbols = ntohs(symbol_count); + + *symbols = malloc(sizeof(SymbolInfo)*symbol_count); + font->codes = malloc(sizeof(uint16_t)*symbol_count); + + uint8_t width; + uint8_t top; + uint16_t code; + uint32_t x; + for(uint16_t i = 0; i < symbol_count; i++) { + fread(&code, 2, 1, metadata); + font->codes[i] = ntohs(code); + fread(&x, 4, 1, metadata); + (*symbols)[i].x = ntohl(x); + fread(&width, 1, 1, metadata); + (*symbols)[i].width = width; + fread(&top, 1, 1, metadata); + (*symbols)[i].top = top; + } + fclose(metadata); return VK_SUCCESS; @@ -85,13 +111,15 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) { } FontData test_font = {}; - result = load_font("tools/test.png", "tools/test.meta", &test_font); + uint32_t* test_atlas; + SymbolInfo* test_symbols; + result = load_font("tools/test.png", "tools/test.meta", &test_font, &test_symbols, &test_atlas); if(result != VK_SUCCESS) { return result; } FontDescriptor test_font_descriptor; - result = create_text_descriptor(render_context->device, render_context->allocator, ui_context.font_layout, ui_context.font_pool, &test_font, render_context->transfer_pool, render_context->transfer_queue, &test_font_descriptor); + result = create_text_descriptor(render_context->device, render_context->allocator, ui_context.font_layout, ui_context.font_pool, &test_font, test_symbols, test_atlas, render_context->transfer_pool, render_context->transfer_queue, &test_font_descriptor); if(result != VK_SUCCESS) { return result; } diff --git a/client/src/pipeline.c b/client/src/pipeline.c index dd6ad76..55796e6 100644 --- a/client/src/pipeline.c +++ b/client/src/pipeline.c @@ -442,7 +442,7 @@ VkResult create_text_descriptor_pool(VkDevice device, uint32_t max_sets, VkDescr return VK_SUCCESS; } -VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayout layout, VkDescriptorPool pool, FontData* font, VkCommandPool transfer_pool, Queue transfer_queue, FontDescriptor* descriptor) { +VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayout layout, VkDescriptorPool pool, FontData* font, SymbolInfo* symbols, uint32_t* atlas, VkCommandPool transfer_pool, Queue transfer_queue, FontDescriptor* descriptor) { VkResult result; VkDescriptorSetAllocateInfo set_allocate_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, @@ -474,7 +474,7 @@ VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescr .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, .extent.depth = 1, .extent.width = font->info.width, - .extent.height = font->info.width, + .extent.height = font->info.height, .mipLevels = 1, .arrayLayers = 1, .format = VK_FORMAT_R8G8B8A8_SRGB, @@ -517,7 +517,7 @@ VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescr return result; } memcpy(mapped_staging + image_size, &font->info, sizeof(FontUniform)); - memcpy(mapped_staging, font->data, image_size); + memcpy(mapped_staging, atlas, image_size); vmaUnmapMemory(allocator, staging_memory); VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);