Fixed UI scale

main
noah metz 2024-10-21 09:20:50 -06:00
parent dee33d19b6
commit 35f0ffb46c
6 changed files with 193 additions and 8 deletions

@ -59,6 +59,14 @@ typedef struct FontStorageStruct {
uint32_t index;
} FontStorage;
typedef struct TextureStorageStruct {
VmaAllocation image_memory;
VkImage image;
VkImageView view;
VkSampler sampler;
uint32_t index;
} TextureStorage;
typedef struct UIStringStruct {
vec2 pos;
vec4 color;
@ -126,6 +134,7 @@ typedef struct UIContainerStorageStruct {
typedef struct UIContextStruct {
VkDeviceAddress font_infos;
vec2 screen;
vec2 scale;
} UIContext;
@ -174,6 +183,16 @@ VkResult load_font(
VkBool32 antialias,
FontStorage* memory);
VkResult load_texture(
VkDevice device,
VmaAllocator allocator,
UIContextStorage* context,
uint32_t index,
VkCommandPool transfer_pool,
Queue transfer_queue,
const char* png_file,
TextureStorage* memory);
VkResult create_container(
float x,
float y,
@ -208,6 +227,18 @@ void set_ui_rect(
float a,
UIDrawable* drawable);
void set_ui_image(
float x,
float y,
float width,
float height,
float r,
float g,
float b,
float a,
uint32_t index,
UIDrawable* drawable);
void set_ui_string(
float x,
float y,

@ -21,7 +21,7 @@ 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 pos = (gl_FragCoord.xy - vec2(0.5, 0.5))/pc.context.scale;
vec2 min = pc.layer.container.pos;
vec2 max = min + pc.layer.container.size;
if(pos.x < min.x || pos.y < min.y

@ -38,7 +38,7 @@ void main() {
pos = pos * vec2(symbol.width, symbol.height) + vec2(symbol.left, -symbol.top);
}
gl_Position = vec4((pos * drawable.size + drawable.pos + pc.layer.container.pos) * pc.context.scale, 0.0, 1.0) - vec4(1.0, 1.0, 0.0, 0.0);
gl_Position = vec4((pos * drawable.size + drawable.pos + pc.layer.container.pos) * pc.context.screen * 2, 0.0, 1.0) - vec4(1.0, 1.0, 0.0, 0.0);
fragColor = drawable.color;
code = drawable.code;

@ -90,5 +90,6 @@ layout(std430, buffer_reference) readonly buffer Layer {
layout(std430, buffer_reference) buffer Context {
FontList fonts;
vec2 screen;
vec2 scale;
};

@ -52,7 +52,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) {
mapped_count[0] = 1;
mapped_count[1] = 1;
UIDrawable* mapped_drawable = (UIDrawable*)(mapped + 2*sizeof(uint32_t));
set_ui_rect( 0.0, 0.0, 100.0, 200.0, 1.0, 0.0, 0.0, 1.0, &mapped_drawable[0]);
set_ui_image(0.0, 0.0, 100.0, 200.0, 1.0, 1.0, 1.0, 1.0, 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));

@ -8,6 +8,7 @@
#include "string.h"
#include "vk_mem_alloc.h"
#include "vulkan/vulkan_core.h"
#include "spng.h"
VkShaderModule load_shader_file(const char* path, VkDevice device) {
FILE* file;
@ -366,6 +367,134 @@ VkResult create_layer(
return VK_SUCCESS;
}
VkResult load_texture(
VkDevice device,
VmaAllocator allocator,
UIContextStorage* context,
uint32_t index,
VkCommandPool transfer_pool,
Queue transfer_queue,
const char* png_path,
TextureStorage* memory) {
spng_ctx* spng = spng_ctx_new(0);
if(spng == NULL) {
return VK_ERROR_UNKNOWN;
}
FILE* png_file = fopen(png_path, "rb");
if(png_file == NULL) {
return VK_ERROR_UNKNOWN;
}
fseek(png_file, 0, SEEK_END);
int error = fseek(png_file, 0, SEEK_END);
if(error != 0) {
return VK_ERROR_UNKNOWN;
}
size_t png_size = ftell(png_file);
error = fseek(png_file, 0, SEEK_SET);
if(error != 0) {
return VK_ERROR_UNKNOWN;
}
void* png = malloc(png_size);
if(png == NULL) {
return VK_ERROR_UNKNOWN;
}
size_t read = fread(png, png_size, 1, png_file);
if(read != png_size) {
return VK_ERROR_UNKNOWN;
}
fclose(png_file);
spng_set_png_buffer(spng, png, png_size);
size_t out_size;
spng_decoded_image_size(spng, SPNG_FMT_RGBA8, &out_size);
struct spng_ihdr ihdr;
spng_get_ihdr(spng, &ihdr);
void* image_buffer = malloc(out_size);
if(image_buffer == NULL) {
return VK_ERROR_UNKNOWN;
}
spng_decode_image(spng, image_buffer, out_size, SPNG_FMT_RGBA8, 0);
VkResult result;
VkImageCreateInfo image_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
.extent = {
.width = ihdr.width,
.height = ihdr.height,
.depth = 1,
},
.mipLevels = 1,
.arrayLayers = 1,
.format = VK_FORMAT_R8G8B8A8_SRGB,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.samples = VK_SAMPLE_COUNT_1_BIT,
.imageType = VK_IMAGE_TYPE_2D,
};
VmaAllocationCreateInfo memory_info = {
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
};
VkBuffer transfer;
VmaAllocation transfer_memory;
void* mapped;
VK_RESULT(vmaCreateImage(allocator, &image_info, &memory_info, &memory->image, &memory->image_memory, NULL));
VK_RESULT(create_transfer_buffer(allocator, sizeof(uint32_t)*ihdr.width*ihdr.height, &transfer, &transfer_memory, &mapped));
memcpy(mapped, image_buffer, sizeof(uint32_t)*ihdr.height*ihdr.width);
VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
VkImageMemoryBarrier first_barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.image = memory->image,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.levelCount = 1,
.layerCount = 1,
},
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &first_barrier);
VkBufferImageCopy image_copy = {
.imageExtent = {
},
};
vkCmdCopyBufferToImage(command_buffer, transfer, memory->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy);
VkImageMemoryBarrier second_barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &second_barrier);
VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue));
vkQueueWaitIdle(transfer_queue.handle);
destroy_transfer_buffer(allocator, transfer, transfer_memory);
free(image_buffer);
free(png);
spng_ctx_free(spng);
}
VkResult load_font(
VkDevice device,
VmaAllocator allocator,
@ -462,7 +591,6 @@ VkResult load_font(
VkImageCreateInfo image_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
.extent.depth = 1,
.extent.width = info.width,
@ -564,8 +692,8 @@ VkResult load_font(
VkSamplerCreateInfo sampler_info = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
.magFilter = VK_FILTER_CUBIC_IMG,
.minFilter = VK_FILTER_CUBIC_IMG,
.magFilter = VK_FILTER_NEAREST,
.minFilter = VK_FILTER_NEAREST,
.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
@ -754,8 +882,10 @@ VkResult create_ui_context(
VK_RESULT(create_transfer_buffer(allocator, sizeof(UIContext), &transfer, &transfer_memory, (void**)&mapped));
memory->data.font_infos = buffer_address(device, memory->font_infos);
memory->data.scale[0] = window_scale[0] / swapchain_extent.width;
memory->data.scale[1] = window_scale[1] / swapchain_extent.height;
memory->data.screen[0] = window_scale[0] / swapchain_extent.width;
memory->data.screen[1] = window_scale[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);
@ -793,6 +923,29 @@ void set_ui_rect(
drawable->code = 0;
}
void set_ui_image(
float x,
float y,
float width,
float height,
float r,
float g,
float b,
float a,
uint32_t index,
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 = 2;
drawable->code = index;
}
void set_ui_string(
float x,
float y,