From 5260a59db5317633c472737c1cb08d4ca0f28830 Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Mon, 14 Oct 2024 14:59:49 -0600 Subject: [PATCH] Got glyphs rendering from a 1D font atlas --- client/include/pipeline.h | 2 ++ client/shader_src/ui_text.vert | 12 ++++++++++-- client/src/main.c | 4 ++-- client/src/pipeline.c | 33 ++++++++++++++++++++++++++++++--- client/src/render.c | 6 ++++++ 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/client/include/pipeline.h b/client/include/pipeline.h index 5ce2936..a19642a 100644 --- a/client/include/pipeline.h +++ b/client/include/pipeline.h @@ -48,8 +48,10 @@ typedef struct FontDataStruct { } FontData; typedef struct FontDescriptorStruct { + VmaAllocation symbol_memory; VmaAllocation uniform_memory; VmaAllocation image_memory; + VkBuffer symbols; VkBuffer uniform; VkImage image; VkImageView view; diff --git a/client/shader_src/ui_text.vert b/client/shader_src/ui_text.vert index 87afc63..214c1da 100644 --- a/client/shader_src/ui_text.vert +++ b/client/shader_src/ui_text.vert @@ -33,8 +33,16 @@ layout(location = 0) out vec4 fragColor; layout(location = 1) out vec2 fragUV; void main() { - fragUV = inVertexPosition; + Symbol symbol = font.symbol_list.symbols[code]; + + float fragU = (inVertexPosition.x*symbol.width + symbol.x) / font.width; + float fragV = inVertexPosition.y + symbol.top / font.height; + float x = inVertexPosition.x * inSize.x * symbol.width / font.height; + float y = (inVertexPosition.y + float(symbol.top)/float(font.height)) * inSize.y; + + fragUV = vec2(fragU, fragV); + fragColor = inColor; - gl_Position = ubo.screen * vec4(vec3(inVertexPosition * inSize, 0.0) + inPosition, 1.0); + gl_Position = ubo.screen * vec4(vec3(x, y, 0.0) + inPosition, 1.0); } diff --git a/client/src/main.c b/client/src/main.c index d28f66e..0aa4dd3 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -184,7 +184,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) { text[0].color[3] = 1.0f; text[0].pos[0] = 200.0f; text[0].pos[1] = 200.0f; - text[0].code = 0; + text[0].code = 1; text[1].size[0] = 200.0f; text[1].size[1] = 200.0f; @@ -194,7 +194,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) { text[1].color[3] = 1.0f; text[1].pos[0] = 400.0f; text[1].pos[1] = 200.0f; - text[1].code = 1; + text[1].code = 14; vmaUnmapMemory(render_context->allocator, text_memory); diff --git a/client/src/pipeline.c b/client/src/pipeline.c index 55796e6..7fb0d40 100644 --- a/client/src/pipeline.c +++ b/client/src/pipeline.c @@ -456,6 +456,20 @@ VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescr return result; } + VkBufferCreateInfo symbol_buffer_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .size = sizeof(SymbolInfo)*font->info.num_symbols, + }; + VmaAllocationCreateInfo symbol_memory_info = { + .usage = VMA_MEMORY_USAGE_GPU_ONLY, + }; + result = vmaCreateBuffer(allocator, &symbol_buffer_info, &symbol_memory_info, &descriptor->symbols, &descriptor->symbol_memory, NULL); + if(result != VK_SUCCESS) { + return result; + } + VkBufferCreateInfo uniform_buffer_info = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, @@ -497,7 +511,7 @@ VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescr .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .size = sizeof(FontUniform) + image_size, + .size = sizeof(FontUniform) + image_size + sizeof(SymbolInfo)*font->info.num_symbols, }; VmaAllocationCreateInfo staging_memory_info = { @@ -516,18 +530,31 @@ VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescr if(result != VK_SUCCESS) { return result; } + memcpy(mapped_staging + image_size + sizeof(FontUniform), symbols, sizeof(SymbolInfo)*font->info.num_symbols); + VkBufferDeviceAddressInfo address_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + .buffer = descriptor->symbols, + }; + font->info.symbol_list = vkGetBufferDeviceAddress(device, &address_info); memcpy(mapped_staging + image_size, &font->info, sizeof(FontUniform)); memcpy(mapped_staging, atlas, image_size); vmaUnmapMemory(allocator, staging_memory); VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); - VkBufferCopy copy_info = { + VkBufferCopy uniform_copy_info = { .size = sizeof(FontUniform), .srcOffset = image_size, .dstOffset = 0, }; - vkCmdCopyBuffer(command_buffer, staging_buffer, descriptor->uniform, 1, ©_info); + vkCmdCopyBuffer(command_buffer, staging_buffer, descriptor->uniform, 1, &uniform_copy_info); + + VkBufferCopy symbol_copy_info = { + .size = sizeof(SymbolInfo)*font->info.num_symbols, + .srcOffset = image_size + sizeof(FontUniform), + .dstOffset = 0, + }; + vkCmdCopyBuffer(command_buffer, staging_buffer, descriptor->symbols, 1, &symbol_copy_info); VkImageMemoryBarrier first_barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, diff --git a/client/src/render.c b/client/src/render.c index 40a35d3..d94e624 100644 --- a/client/src/render.c +++ b/client/src/render.c @@ -333,6 +333,10 @@ VkResult create_logical_device(VkPhysicalDevice physical_device, VkSurfaceKHR su queue_create_info[1].pQueuePriorities = &default_queue_priority; } + VkPhysicalDeviceVulkan13Features features_13 = { + .dynamicRendering = VK_TRUE, + }; + VkPhysicalDeviceVulkan12Features features_12 = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, .bufferDeviceAddress = VK_TRUE, @@ -342,6 +346,7 @@ VkResult create_logical_device(VkPhysicalDevice physical_device, VkSurfaceKHR su .descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE, .descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE, .descriptorBindingSampledImageUpdateAfterBind = VK_TRUE, + .pNext = &features_13, }; VkPhysicalDeviceFeatures device_features = { @@ -378,6 +383,7 @@ VkResult create_memory_allocator(VkInstance instance, VkPhysicalDevice physical_ .instance = instance, .physicalDevice = physical_device, .device = device, + .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, }; VkResult result = vmaCreateAllocator(&allocator_create_info, allocator);