Compressed codes to 4 in one glsl uint, added region info ui

main
noah metz 2024-11-10 16:36:01 -07:00
parent a4300a78b1
commit 2a6b96a274
5 changed files with 298 additions and 51 deletions

@ -15,6 +15,10 @@
#define ANCHOR_BOTTOM_RIGHT 3 #define ANCHOR_BOTTOM_RIGHT 3
#define ANCHOR_CENTER 4 #define ANCHOR_CENTER 4
#define DRAWABLE_TYPE_RECT 0
#define DRAWABLE_TYPE_GLYPH 1
#define DRAWABLE_TYPE_IMAGE 2
typedef struct UIPushConstantStruct { typedef struct UIPushConstantStruct {
VkDeviceAddress layer; VkDeviceAddress layer;
float time; float time;
@ -244,4 +248,16 @@ VkResult map_string(
uint32_t font, uint32_t font,
UIContext* context); UIContext* context);
VkResult update_ui_context_resolution(
UIContext* ui,
RenderContext* gpu);
VkResult update_ui_string(
char* string,
uint32_t container_index,
uint32_t layer_index,
uint32_t string_index,
UIContext* ui,
RenderContext* gpu);
#endif #endif

@ -14,13 +14,13 @@ void main() {
vec2 pen = vec2(0.0, 0.0); vec2 pen = vec2(0.0, 0.0);
for(uint i = 0; i < string.len; i++) { for(uint i = 0; i < string.len; i++) {
uint code = pc.layer.codes.c[string.offset + i]; uint code = (pc.layer.codes.c[(string.offset + i)/4] >> ((string.offset + i) % 4)*8) & 0xFF;
Symbol symbol = font.symbols.s[code]; Symbol symbol = font.symbols.s[code];
pc.layer.drawables.d[buffer_pos + i].pos = string.pos + pen; pc.layer.drawables.d[buffer_pos + i].pos = string.pos + pen;
pen += string.size*symbol.advance; pen += string.size*symbol.advance;
pc.layer.drawables.d[buffer_pos + i].size = vec2(string.size, string.size); pc.layer.drawables.d[buffer_pos + i].size = vec2(string.size, string.size);
pc.layer.drawables.d[buffer_pos + i].color = string.color; pc.layer.drawables.d[buffer_pos + i].color = string.color;
pc.layer.drawables.d[buffer_pos + i].var1 = pc.layer.codes.c[string.offset + i]; pc.layer.drawables.d[buffer_pos + i].var1 = code;
pc.layer.drawables.d[buffer_pos + i].var2 = string.font; pc.layer.drawables.d[buffer_pos + i].var2 = string.font;
pc.layer.drawables.d[buffer_pos + i].type = 1; pc.layer.drawables.d[buffer_pos + i].type = 1;
} }

@ -732,20 +732,12 @@ VkResult set_hex_region(HexRegion* region, HexContext* hex, RenderContext* gpu)
return VK_ERROR_UNKNOWN; return VK_ERROR_UNKNOWN;
} }
VkResult result; return add_transfer(
VK_RESULT(add_transfer(
&region->data.hexes, &region->data.hexes,
region->region, region->region,
offsetof(GPUHexRegion, hexes), offsetof(GPUHexRegion, hexes),
sizeof(GPUHex)*REGION_HEX_COUNT, sizeof(GPUHex)*REGION_HEX_COUNT,
gpu->current_frame, gpu->current_frame,
gpu));
return add_transfers(
&region->address,
hex->context,
offsetof(GPUHexContext, regions) + sizeof(VkDeviceAddress)*index,
sizeof(VkDeviceAddress),
gpu); gpu);
} }
@ -792,7 +784,12 @@ VkResult allocate_hex_region(
(*region)->address = buffer_address(gpu->device, (*region)->region); (*region)->address = buffer_address(gpu->device, (*region)->region);
return VK_SUCCESS; return add_transfers(
&(*region)->address,
hex->context,
offsetof(GPUHexContext, regions) + sizeof(VkDeviceAddress)*i,
sizeof(VkDeviceAddress),
gpu);
} }
bool ray_hex_intersect( bool ray_hex_intersect(

@ -1,4 +1,5 @@
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
#include <stdio.h>
#define CGLM_PRINT_PRECISION 10 #define CGLM_PRINT_PRECISION 10
#define CGLM_DEFINE_PRINTS 1 #define CGLM_DEFINE_PRINTS 1
#include "ui.h" #include "ui.h"
@ -41,6 +42,9 @@ typedef struct ClientContextStruct {
float cur_spin_speed; float cur_spin_speed;
float zoom_speed; float zoom_speed;
float move_speed; float move_speed;
uint32_t selected_region;
uint32_t last_selected_region;
} ClientContext; } ClientContext;
void* network_thread(void* data) { void* network_thread(void* data) {
@ -79,42 +83,101 @@ VkResult add_hex_region(ClientContext* context) {
return VK_SUCCESS; return VK_SUCCESS;
} }
VkResult main_thread(ClientContext* context) { char region_info_strs[][20] = {
VkResult result; "Region XXXX",
"Q: XXXX",
"R: XXXX",
"Y: XXXX",
};
uint32_t region_info_str_off[] = {
0,
11,
18,
25,
};
VkResult region_info_ui(ClientContext* context) {
GPUString strings[] = { GPUString strings[] = {
{ {
.pos = {0, 32}, .pos = {0, 33},
.color = {1, 1, 1, 1},
.size = 32,
.offset = region_info_str_off[0],
.length = strlen(region_info_strs[0]),
.font = 0,
},
{
.pos = {0, 33 + 1*40},
.color = {1, 1, 1, 1},
.size = 32, .size = 32,
.color = {1.0, 1.0, 1.0, 1.0}, .offset = region_info_str_off[1],
.offset = 0, .length = strlen(region_info_strs[1]),
.length = 0, .font = 0,
},
{
.pos = {0, 33 + 2*40},
.color = {1, 1, 1, 1},
.size = 32,
.offset = region_info_str_off[2],
.length = strlen(region_info_strs[2]),
.font = 0,
},
{
.pos = {0, 33 + 3*40},
.color = {1, 1, 1, 1},
.size = 32,
.offset = region_info_str_off[3],
.length = strlen(region_info_strs[3]),
.font = 0, .font = 0,
}, },
}; };
GPUDrawable drawables[] = {}; uint32_t codes[43/4];
VkResult result;
VK_RESULT(map_string(region_info_strs[0], codes, region_info_str_off[0], 0, context->ui));
VK_RESULT(map_string(region_info_strs[1], codes, region_info_str_off[1], 0, context->ui));
VK_RESULT(map_string(region_info_strs[2], codes, region_info_str_off[2], 0, context->ui));
VK_RESULT(map_string(region_info_strs[3], codes, region_info_str_off[3], 0, context->ui));
GPUDrawable drawables[] = {
{
.pos = {0, 0},
.size = {225, 155},
.color = {0.4, 0.4, 0.4, 0.4},
},
};
LayerInput layer = { LayerInput layer = {
.strings = strings, .strings = strings,
.num_strings = sizeof(strings)/sizeof(GPUString), .num_strings = sizeof(strings)/sizeof(GPUString),
.max_codes = 50, .max_strings = sizeof(strings)/sizeof(GPUString) + 4,
.codes = codes,
.num_codes = sizeof(codes)/sizeof(uint32_t),
.max_codes = sizeof(codes)/sizeof(uint32_t) + 100,
.drawables = drawables, .drawables = drawables,
.num_drawables = sizeof(drawables)/sizeof(GPUDrawable), .num_drawables = sizeof(drawables)/sizeof(GPUDrawable),
}; };
ContainerInput container = { ContainerInput region_info = {
.id = 1, .id = 0x01,
.size = {WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT}, .size = {225, 155},
.layer_count = 1, .offset = {0, 0},
.anchor = ANCHOR_TOP_RIGHT,
.layers = &layer, .layers = &layer,
.layer_count = 1,
}; };
create_container(&container, context->render, context->ui); return create_container(&region_info, context->render, context->ui);
}
VkResult main_thread(ClientContext* context) {
VkResult result;
VK_RESULT(region_info_ui(context));
// //
int frame = 0;
double last_frame_time = 0; double last_frame_time = 0;
while(glfwWindowShouldClose(context->window) == 0) { while(glfwWindowShouldClose(context->window) == 0) {
double frame_time = glfwGetTime(); double frame_time = glfwGetTime();
@ -128,16 +191,68 @@ VkResult main_thread(ClientContext* context) {
context->cur_spin[1] = 0; context->cur_spin[1] = 0;
glfwPollEvents(); glfwPollEvents();
if(context->selected_region != context->last_selected_region) {
context->last_selected_region = context->selected_region;
HexRegion* selected_region = context->hex->regions[context->selected_region];
snprintf(region_info_strs[0],
sizeof(region_info_strs[0]),
"Region %4d", context->selected_region);
VK_RESULT(update_ui_string(region_info_strs[0], 0, 0, 0, context->ui, context->render));
if(selected_region == NULL) {
snprintf(
region_info_strs[1],
sizeof(region_info_strs[1]),
"");
VK_RESULT(update_ui_string(region_info_strs[1], 0, 0, 1, context->ui, context->render));
snprintf(
region_info_strs[2],
sizeof(region_info_strs[2]),
"");
VK_RESULT(update_ui_string(region_info_strs[2], 0, 0, 2, context->ui, context->render));
snprintf(
region_info_strs[3],
sizeof(region_info_strs[3]),
"");
VK_RESULT(update_ui_string(region_info_strs[3], 0, 0, 3, context->ui, context->render));
} else {
snprintf(
region_info_strs[1],
sizeof(region_info_strs[1]),
"Q: %4d", selected_region->data.q);
VK_RESULT(update_ui_string(region_info_strs[1], 0, 0, 1, context->ui, context->render));
snprintf(
region_info_strs[2],
sizeof(region_info_strs[2]),
"R: %4d", selected_region->data.r);
VK_RESULT(update_ui_string(region_info_strs[2], 0, 0, 2, context->ui, context->render));
snprintf(
region_info_strs[3],
sizeof(region_info_strs[3]),
"Y: %4d", selected_region->data.y);
VK_RESULT(update_ui_string(region_info_strs[3], 0, 0, 3, context->ui, context->render));
}
}
if((context->key_spin[0] != 0 || context->key_spin[1] != 0 || if((context->key_spin[0] != 0 || context->key_spin[1] != 0 ||
context->velocity[0] != 0 || context->velocity[1] != 0 || context->velocity[2] != 0 || context->velocity[0] != 0 || context->velocity[1] != 0 || context->velocity[2] != 0 ||
context->zoom != 0 || context->zoom != 0 ||
context->cur_spin[0] != 0 || context->cur_spin[1] != 0 || context->cur_spin[0] != 0 || context->cur_spin[1] != 0 ||
context->render->framebuffer_recreated == true) && frame > 0) { context->render->framebuffer_recreated == true)) {
if(context->render->framebuffer_recreated == true) { if(context->render->framebuffer_recreated == true) {
context->render->framebuffer_recreated = false; context->render->framebuffer_recreated = false;
VK_RESULT(update_hex_proj(context->render, context->hex)); VK_RESULT(update_hex_proj(context->render, context->hex));
VK_RESULT(update_ui_context_resolution(context->ui, context->render));
} }
context->rotation[0] += (float)context->key_spin[0]*delta_time*context->key_spin_speed; context->rotation[0] += (float)context->key_spin[0]*delta_time*context->key_spin_speed;
@ -183,7 +298,6 @@ VkResult main_thread(ClientContext* context) {
fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result)); fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result));
glfwDestroyWindow(context->window); glfwDestroyWindow(context->window);
} }
frame += 1;
last_frame_time = frame_time; last_frame_time = frame_time;
} }
@ -272,10 +386,27 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
break; break;
case GLFW_KEY_EQUAL: case GLFW_KEY_EQUAL:
if(action == GLFW_RELEASE) { if(action == GLFW_PRESS) {
add_hex_region(context); add_hex_region(context);
} }
break; break;
case GLFW_KEY_LEFT_BRACKET:
if(action == GLFW_PRESS) {
context->selected_region -= 1;
if(context->selected_region > MAX_LOADED_REGIONS) {
context->selected_region = MAX_LOADED_REGIONS;
}
}
break;
case GLFW_KEY_RIGHT_BRACKET:
if(action == GLFW_PRESS) {
context->selected_region += 1;
if(context->selected_region > MAX_LOADED_REGIONS) {
context->selected_region = 0;
}
}
break;
} }
} }
@ -374,6 +505,9 @@ int main() {
.cur_spin_speed = 1.0, .cur_spin_speed = 1.0,
.zoom_speed = 1.0, .zoom_speed = 1.0,
.move_speed = 0.1, .move_speed = 0.1,
.selected_region = MAX_LOADED_REGIONS,
.last_selected_region = 0,
}; };
if(context.window == NULL || context.render == NULL || context.ui == NULL || context.hex == NULL) { if(context.window == NULL || context.render == NULL || context.ui == NULL || context.hex == NULL) {
return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;

@ -705,12 +705,23 @@ VkResult load_font(
.usage = VMA_MEMORY_USAGE_GPU_ONLY, .usage = VMA_MEMORY_USAGE_GPU_ONLY,
}; };
VK_RESULT(vmaCreateImage(gpu->allocator, &image_info, &image_memory_info, &context->fonts[index].image, &context->fonts[index].image_memory, NULL)); VK_RESULT(vmaCreateImage(
gpu->allocator,
&image_info,
&image_memory_info,
&context->fonts[index].image,
&context->fonts[index].image_memory,
NULL));
VkBuffer transfer; VkBuffer transfer;
VmaAllocation transfer_memory; VmaAllocation transfer_memory;
void* mapped; void* mapped;
VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(GPUFont) + image_size*info.num_symbols + sizeof(GPUSymbol)*info.num_symbols, &transfer, &transfer_memory, &mapped)); VK_RESULT(create_transfer_buffer(
gpu->allocator,
sizeof(GPUFont) + image_size*info.num_symbols + sizeof(GPUSymbol)*info.num_symbols,
&transfer,
&transfer_memory,
&mapped));
info.symbol_list = buffer_address(gpu->device, context->fonts[index].symbols); info.symbol_list = buffer_address(gpu->device, context->fonts[index].symbols);
@ -722,8 +733,19 @@ VkResult load_font(
free(symbols); free(symbols);
VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool);
command_copy_buffer(command_buffer, transfer, context->font_infos, image_size*info.num_symbols, index*sizeof(GPUFont), sizeof(GPUFont)); command_copy_buffer(
command_copy_buffer(command_buffer, transfer, context->fonts[index].symbols, image_size*info.num_symbols + sizeof(GPUFont), 0, sizeof(GPUSymbol)*info.num_symbols); command_buffer,
transfer,
context->font_infos,
image_size*info.num_symbols,
index*sizeof(GPUFont),
sizeof(GPUFont));
command_copy_buffer(command_buffer,
transfer,
context->fonts[index].symbols,
image_size*info.num_symbols + sizeof(GPUFont),
0,
sizeof(GPUSymbol)*info.num_symbols);
VkImageMemoryBarrier first_barrier = { VkImageMemoryBarrier first_barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@ -1002,6 +1024,24 @@ VkResult create_ui_descriptor(
return VK_SUCCESS; return VK_SUCCESS;
} }
VkResult update_ui_context_resolution(
UIContext* ui,
RenderContext* gpu) {
ui->data.screen[0] = gpu->window_scale[0] / gpu->swapchain_extent.width;
ui->data.screen[1] = gpu->window_scale[1] / gpu->swapchain_extent.height;
ui->data.extent[0] = gpu->swapchain_extent.width / gpu->window_scale[0];
ui->data.extent[1] = gpu->swapchain_extent.height / gpu->window_scale[1];
ui->data.scale[0] = gpu->window_scale[0];
ui->data.scale[1] = gpu->window_scale[1];
return add_transfer(
&ui->data.screen[0],
ui->context,
offsetof(GPUUIContext, screen),
sizeof(GPUUIContext) - offsetof(GPUUIContext, screen),
gpu->current_frame, gpu);
}
VkResult create_ui_context( VkResult create_ui_context(
uint32_t max_fonts, uint32_t max_fonts,
uint32_t max_textures, uint32_t max_textures,
@ -1015,14 +1055,18 @@ VkResult create_ui_context(
return VK_ERROR_UNKNOWN; return VK_ERROR_UNKNOWN;
} }
VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(GPUUIContext), &context->context, &context->context_memory)); VK_RESULT(create_storage_buffer(
VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(GPUFont)*max_fonts, &context->font_infos, &context->font_infos_memory)); gpu->allocator,
0,
VkBuffer transfer; sizeof(GPUUIContext),
VmaAllocation transfer_context; &context->context,
UIContext* mapped; &context->context_memory));
VK_RESULT(create_storage_buffer(
VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(UIContext), &transfer, &transfer_context, (void**)&mapped)); gpu->allocator,
0,
sizeof(GPUFont)*max_fonts,
&context->font_infos,
&context->font_infos_memory));
context->data.font_infos = buffer_address(gpu->device, context->font_infos); context->data.font_infos = buffer_address(gpu->device, context->font_infos);
context->data.screen[0] = gpu->window_scale[0] / gpu->swapchain_extent.width; context->data.screen[0] = gpu->window_scale[0] / gpu->swapchain_extent.width;
@ -1031,17 +1075,36 @@ VkResult create_ui_context(
context->data.extent[1] = gpu->swapchain_extent.height / gpu->window_scale[1]; context->data.extent[1] = gpu->swapchain_extent.height / gpu->window_scale[1];
context->data.scale[0] = gpu->window_scale[0]; context->data.scale[0] = gpu->window_scale[0];
context->data.scale[1] = gpu->window_scale[1]; context->data.scale[1] = gpu->window_scale[1];
memcpy(mapped, &context->data, sizeof(GPUUIContext));
VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); VK_RESULT(add_transfer(
command_copy_buffer(command_buffer, transfer, context->context, 0, 0, sizeof(GPUUIContext)); &context->data,
VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue)); context->context,
destroy_transfer_buffer(gpu->allocator, transfer, transfer_context); 0,
sizeof(GPUUIContext),
gpu->current_frame,
gpu));
context->address = buffer_address(gpu->device, context->context); context->address = buffer_address(gpu->device, context->context);
VK_RESULT(create_ui_descriptor(gpu->device, max_fonts, max_textures, &context->samplers_layout, &context->textures_layout, &context->samplers, &context->textures, &context->font_samplers, &context->font_textures, &context->fonts_pool, &context->textures_pool)); VK_RESULT(create_ui_descriptor(
gpu->device,
VK_RESULT(create_ui_pipeline(gpu->device, gpu->render_pass, context->samplers_layout, context->textures_layout, &context->pipeline, &context->string_pipeline)); max_fonts,
max_textures,
&context->samplers_layout,
&context->textures_layout,
&context->samplers,
&context->textures,
&context->font_samplers,
&context->font_textures,
&context->fonts_pool,
&context->textures_pool));
VK_RESULT(create_ui_pipeline(
gpu->device,
gpu->render_pass,
context->samplers_layout,
context->textures_layout,
&context->pipeline,
&context->string_pipeline));
context->max_textures = max_textures; context->max_textures = max_textures;
context->max_fonts = max_fonts; context->max_fonts = max_fonts;
@ -1066,6 +1129,7 @@ VkResult map_string(
uint32_t font, uint32_t font,
UIContext* context) { UIContext* context) {
size_t i = 0; size_t i = 0;
memset((uint8_t*)buffer + offset, 0, strlen(text));
while(text[i] != '\0') { while(text[i] != '\0') {
uint32_t mapped = 0xFFFFFFFF; uint32_t mapped = 0xFFFFFFFF;
for(uint32_t j = 0; j < context->fonts[font].num_symbols; j++) { for(uint32_t j = 0; j < context->fonts[font].num_symbols; j++) {
@ -1077,9 +1141,45 @@ VkResult map_string(
if(mapped == 0xFFFFFFFF) { if(mapped == 0xFFFFFFFF) {
return VK_ERROR_UNKNOWN; return VK_ERROR_UNKNOWN;
} }
buffer[i + offset] = mapped; buffer[(i + offset)/4] += mapped << ((i + offset) % 4)*8;
i += 1; i += 1;
} }
return VK_SUCCESS; return VK_SUCCESS;
} }
VkResult update_ui_string(
char* string,
uint32_t container_index,
uint32_t layer_index,
uint32_t string_index,
UIContext* ui,
RenderContext* gpu) {
VkResult result;
Container* container = &ui->containers[container_index];
Layer* layer = &container->layers[layer_index];
layer->strings_buffer[string_index].length = strlen(string);
if(strlen(string) > 0) {
VK_RESULT(map_string(
string,
layer->codes_buffer,
layer->strings_buffer[string_index].offset,
layer->strings_buffer[string_index].font,
ui));
VK_RESULT(add_transfers(
(uint8_t*)layer->codes_buffer + layer->strings_buffer[string_index].offset,
layer->codes,
layer->strings_buffer[string_index].offset,
strlen(string),
gpu));
}
VK_RESULT(add_transfers(
&layer->strings_buffer[string_index].length,
layer->strings,
sizeof(GPUString)*string_index + offsetof(GPUString, length),
sizeof(uint32_t),
gpu));
return VK_SUCCESS;
}