Probably a lot idk, I was doing modal editing stuff

main
noah metz 2024-12-03 21:05:10 -07:00
parent 4379e6cd9b
commit 5e2e8f6d30
7 changed files with 345 additions and 614 deletions

@ -8,17 +8,17 @@
typedef struct ClientContextStruct ClientContext; typedef struct ClientContextStruct ClientContext;
typedef bool (*app_text_callback)( typedef void (*app_text_callback)(
ClientContext* context, ClientContext* context,
unsigned int codepoint); unsigned int codepoint);
typedef bool (*app_key_callback)( typedef void (*app_key_callback)(
ClientContext* context, ClientContext* context,
int key, int key,
int action, int action,
int mods); int mods);
typedef bool (*app_button_callback)( typedef void (*app_button_callback)(
ClientContext* context, ClientContext* context,
float x, float x,
float y, float y,
@ -26,12 +26,12 @@ typedef bool (*app_button_callback)(
int action, int action,
int mods); int mods);
typedef bool (*app_scroll_callback)( typedef void (*app_scroll_callback)(
ClientContext* context, ClientContext* context,
double x, double x,
double y); double y);
typedef bool (*app_cursor_callback)( typedef void (*app_cursor_callback)(
ClientContext* context, ClientContext* context,
float x, float x,
float y); float y);
@ -53,15 +53,12 @@ struct ClientContextStruct {
vec3 velocity; vec3 velocity;
vec2 rotation; vec2 rotation;
int32_t key_spin[2]; int32_t spin[2];
vec2 cur_spin;
double distance; double distance;
int32_t zoom; int32_t zoom;
bool camera_mode; float spin_speed;
float key_spin_speed;
float cur_spin_speed;
float zoom_speed; float zoom_speed;
float move_speed; float move_speed;

@ -150,6 +150,8 @@ typedef struct RenderContextStruct {
VkRenderPass render_pass; VkRenderPass render_pass;
VkCommandBuffer* swapchain_command_buffers; VkCommandBuffer* swapchain_command_buffers;
uint64_t swapchain_command_buffer_record_id;
uint64_t* swapchain_command_buffer_record_ids;
FrameContext frame[MAX_FRAMES_IN_FLIGHT]; FrameContext frame[MAX_FRAMES_IN_FLIGHT];

@ -266,11 +266,16 @@ VkResult load_texture(
UIContext* context, UIContext* context,
uint32_t* index); uint32_t* index);
VkResult create_container( VkResult load_container(
ContainerInput* container, ContainerInput* container,
RenderContext* gpu, RenderContext* gpu,
UIContext* context); UIContext* context);
VkResult unload_container(
uint32_t id,
RenderContext* gpu,
UIContext* context);
VkResult create_layer( VkResult create_layer(
uint32_t index, uint32_t index,
LayerInput* input, LayerInput* input,
@ -289,7 +294,7 @@ VkResult update_ui_context_resolution(
RenderContext* gpu); RenderContext* gpu);
VkResult update_ui_string( VkResult update_ui_string(
char* string, const char* string,
uint32_t container_id, uint32_t container_id,
uint32_t layer_index, uint32_t layer_index,
uint32_t string_index, uint32_t string_index,

@ -7,20 +7,54 @@
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#define COLOR_PICK_CONTAINER_ID 0x03 #define COLOR_PICK_CONTAINER_ID 0x02
typedef struct EditorDataStruct { #define MODE_STRING_CONTAINER_ID 0x01
uint32_t selected_region;
typedef enum EditorModeEnum {
MODE_NONE,
MODE_VERTEX,
MODE_NEIGHBOR,
MODE_HEX,
MODE_REGION,
MODE_MAX_ENUM,
} EditorMode;
const char* ModeStrings[] = {
"None",
"Vertex",
"Neighbor",
"Hex",
"Region",
};
typedef struct EditorDataStruct EditorData;
typedef void(*ModeKeyCallback)(EditorData* data, ClientContext* context, int action, int mods);
typedef struct ModeKeyStruct {
int key;
ModeKeyCallback logic;
} ModeKey;
struct EditorDataStruct {
EditorMode mode;
uint32_t clicked_region; ModeKey* mode_keys[MODE_MAX_ENUM];
uint32_t clicked_hex; uint32_t mode_key_counts[MODE_MAX_ENUM];
uint32_t clicked_vertex;
uint32_t selected_max;
uint32_t selected_count;
uint32_t* selected_regions;
uint32_t* selected_hexes;
uint32_t* selected_vertices;
double current_hsv[3]; double current_hsv[3];
vec4 current; vec4 current;
vec4 saved[12]; vec4 saved[12];
char string[10]; char string[10];
int string_len; int string_len;
} EditorData; };
uint32_t hex_color(vec4 color) { uint32_t hex_color(vec4 color) {
@ -475,6 +509,7 @@ SAVED_COLOR_BUTTON_CALLBACK(11);
.button = saved_color_button_callback_##n, \ .button = saved_color_button_callback_##n, \
} }
// TODO: Make load from current state instead of having a default state
VkResult color_ui(ClientContext* context) { VkResult color_ui(ClientContext* context) {
GPUString strings[] = { GPUString strings[] = {
{ {
@ -691,7 +726,7 @@ VkResult color_ui(ClientContext* context) {
.callback_count = sizeof(callbacks)/sizeof(UICallbacks), .callback_count = sizeof(callbacks)/sizeof(UICallbacks),
}; };
return create_container(&container, &context->render, &context->ui); return load_container(&container, &context->render, &context->ui);
} }
VkResult hex_info_ui(ClientContext* context) { VkResult hex_info_ui(ClientContext* context) {
@ -789,495 +824,252 @@ VkResult hex_info_ui(ClientContext* context) {
.layer_count = 1, .layer_count = 1,
}; };
return create_container(&container, &context->render, &context->ui); return load_container(&container, &context->render, &context->ui);
} }
VkResult region_info_ui(ClientContext* context) { VkResult mode_string_ui(ClientContext* context) {
VkResult result;
GPUString strings[] = { GPUString string = {
{ .pos = {0, 32},
.pos = {0, 33},
.color = {1, 1, 1, 1},
.size = 32,
.offset = 0,
.length = 0,
.font = 0,
},
{
.pos = {0, 33 + 1*40},
.color = {1, 1, 1, 1},
.size = 32,
.offset = 11,
.length = 0,
.font = 0, .font = 0,
},
{
.pos = {0, 33 + 2*40},
.color = {1, 1, 1, 1},
.size = 32, .size = 32,
.offset = 18, .length = strlen(ModeStrings[MODE_NONE]),
.length = 0,
.font = 0,
},
{
.pos = {0, 33 + 3*40},
.color = {1, 1, 1, 1}, .color = {1, 1, 1, 1},
.size = 32,
.offset = 25,
.length = 0,
.font = 0,
},
}; };
GPUDrawable drawables[] = { uint32_t codes[8];
{ VK_RESULT(map_string(ModeStrings[MODE_NONE], codes, 0, 0, &context->ui));
.pos = {0, 0},
.size = {225, 155},
.color = {{0.4, 0.4, 0.4, 0.8}, {0.4, 0.4, 0.4, 0.8}, {0.4, 0.4, 0.4, 0.8}, {0.4, 0.4, 0.4, 0.8}},
},
};
LayerInput layer = { LayerInput layer = {
.strings = strings, .max_codes = 8,
.num_strings = sizeof(strings)/sizeof(GPUString), .codes = codes,
.max_strings = sizeof(strings)/sizeof(GPUString) + 4, .num_codes = strlen(ModeStrings[MODE_NONE]),
.max_codes = 100, .num_strings = 1,
.drawables = drawables, .strings = &string,
.num_drawables = sizeof(drawables)/sizeof(GPUDrawable),
}; };
ContainerInput container = { ContainerInput container = {
.id = 0x01, .id = MODE_STRING_CONTAINER_ID,
.size = {225, 155},
.offset = {0, 0},
.anchor = ANCHOR_TOP_RIGHT,
.layers = &layer,
.layer_count = 1, .layer_count = 1,
.layers = &layer,
.anchor = ANCHOR_TOP_LEFT,
.size = {160, 40},
}; };
return create_container(&container, &context->render, &context->ui); return load_container(&container, &context->render, &context->ui);
} }
VkResult update_region_info_ui(ClientContext* context) { VkResult update_mode_string(ClientContext* context, EditorData* data) {
char temp[20]; return update_ui_string(ModeStrings[data->mode], MODE_STRING_CONTAINER_ID, 0, 0, &context->ui, &context->render);
VkResult result; }
EditorData* data = context->app_data;
if(data->selected_region >= MAX_LOADED_REGIONS) {
snprintf(temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x01, 0, 0, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x01, 0, 1, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x01, 0, 2, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x01, 0, 3, &context->ui, &context->render));
} else {
HexRegion* selected_region = context->hex.regions[data->selected_region];
snprintf(temp,
sizeof(temp),
"Region %4d", data->selected_region);
VK_RESULT(update_ui_string(temp, 0x01, 0, 0, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"Q: %4d", selected_region->data.position.q);
VK_RESULT(update_ui_string(temp, 0x01, 0, 1, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"R: %4d", selected_region->data.position.r);
VK_RESULT(update_ui_string(temp, 0x01, 0, 2, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"Y: %4d", selected_region->data.y);
VK_RESULT(update_ui_string(temp, 0x01, 0, 3, &context->ui, &context->render));
}
return VK_SUCCESS;
}
VkResult update_hex_info_ui(ClientContext* context) {
char temp[20];
VkResult result;
EditorData* data = context->app_data;
if(data->clicked_region >= MAX_LOADED_REGIONS) {
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 0, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 1, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 2, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 3, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 4, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 5, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 6, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 7, &context->ui, &context->render));
} else {
HexRegion* region = context->hex.regions[data->clicked_region];
GPUHex* hex = &region->data.hexes[data->clicked_hex];
snprintf(temp,
sizeof(temp),
"%d-%d",
data->clicked_region,
data->clicked_hex);
VK_RESULT(update_ui_string(temp, 0x02, 0, 0, &context->ui, &context->render));
HexCoord hex_world;
hex_qr(data->clicked_hex, &hex_world);
fprintf(stderr, "region: %d\n", data->clicked_region);
HexCoord region_coord = {region->data.position.q, region->data.position.r};
HexCoord region_world;
region_qr(region_coord, &region_world);
hex_add(region_world, &hex_world);
snprintf(
temp,
sizeof(temp),
"%d, %d, %d, %d",
hex_world.q,
hex_world.r,
region->data.y,
data->clicked_vertex);
VK_RESULT(update_ui_string(temp, 0x02, 0, 1, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"%02.02f %02.02f %02.02f",
hex->height[0], hex->height[1], hex->height[2]);
VK_RESULT(update_ui_string(temp, 0x02, 0, 2, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"%02.02f %02.02f %02.02f",
hex->height[3], hex->height[4], hex->height[5]);
VK_RESULT(update_ui_string(temp, 0x02, 0, 3, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"%08X",
hex->color[0]);
VK_RESULT(update_ui_string(temp, 0x02, 0, 4, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"%08X %08X",
hex->color[1], hex->color[2]);
VK_RESULT(update_ui_string(temp, 0x02, 0, 5, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"%08X %08X",
hex->color[3], hex->color[4]);
VK_RESULT(update_ui_string(temp, 0x02, 0, 6, &context->ui, &context->render));
snprintf(
temp,
sizeof(temp),
"%08X %08X",
hex->color[5], hex->color[6]);
VK_RESULT(update_ui_string(temp, 0x02, 0, 7, &context->ui, &context->render));
}
return VK_SUCCESS;
}
bool editor_key_callback(ClientContext* context, int key, int action, int mods) {
uint32_t start, next_region;
if(action != GLFW_PRESS) return false;
void editor_key_callback(ClientContext* context, int key, int action, int mods) {
EditorData* data = context->app_data; EditorData* data = context->app_data;
HexRegion* region = NULL; for(uint32_t i = 0; i < data->mode_key_counts[data->mode]; i++) {
if(data->mode_keys[data->mode][i].key == key) {
switch(key) { data->mode_keys[data->mode][i].logic(data, context, action, mods);
case GLFW_KEY_EQUAL: return;
data->selected_region = add_hex_region(context); }
update_region_info_ui(context);
update_hex_info_ui(context);
break;
case GLFW_KEY_MINUS:
if(data->selected_region < MAX_LOADED_REGIONS) {
free_hex_region(data->selected_region, &context->hex, &context->render);
start = data->selected_region;
next_region = start;
do {
next_region -= 1;
if(next_region > MAX_LOADED_REGIONS) next_region = MAX_LOADED_REGIONS;
if(next_region != MAX_LOADED_REGIONS && context->hex.regions[next_region] != NULL) break;
} while(next_region != start);
if(next_region == start) {
data->selected_region = MAX_LOADED_REGIONS;
} else {
data->selected_region = next_region;
}
update_region_info_ui(context);
update_hex_info_ui(context);
} }
break;
case GLFW_KEY_LEFT_BRACKET:
start = data->selected_region;
next_region = start;
do {
next_region -= 1;
if(next_region > MAX_LOADED_REGIONS) next_region = MAX_LOADED_REGIONS;
if(next_region != MAX_LOADED_REGIONS && context->hex.regions[next_region] != NULL) break;
} while(next_region != start);
data->selected_region = next_region;
update_region_info_ui(context);
break;
case GLFW_KEY_RIGHT_BRACKET:
start = data->selected_region;
next_region = start;
do {
next_region += 1;
if(next_region > MAX_LOADED_REGIONS) next_region = 0;
if(next_region != MAX_LOADED_REGIONS && context->hex.regions[next_region] != NULL) break;
} while(next_region != start);
data->selected_region = next_region;
update_region_info_ui(context);
break;
case GLFW_KEY_I: for(uint32_t i = 0; i < data->mode_key_counts[MODE_NONE]; i++) {
if(data->selected_region < MAX_LOADED_REGIONS) { if(data->mode_keys[MODE_NONE][i].key == key) {
context->hex.regions[data->selected_region]->data.position.q += 1; data->mode_keys[MODE_NONE][i].logic(data, context, action, mods);
add_transfer( return;
&context->hex.regions[data->selected_region]->data.position,
context->hex.regions[data->selected_region]->region,
offsetof(GPUHexRegion, position),
sizeof(uint32_t),
context->render.current_frame,
&context->render);
} }
update_region_info_ui(context);
break;
case GLFW_KEY_K:
if(data->selected_region < MAX_LOADED_REGIONS) {
context->hex.regions[data->selected_region]->data.position.q -= 1;
add_transfer(
&context->hex.regions[data->selected_region]->data.position.q,
context->hex.regions[data->selected_region]->region,
offsetof(GPUHexRegion, position) + offsetof(HexCoord, q),
sizeof(uint32_t),
context->render.current_frame,
&context->render);
} }
update_region_info_ui(context);
break;
case GLFW_KEY_J:
if(data->selected_region < MAX_LOADED_REGIONS) {
context->hex.regions[data->selected_region]->data.position.r += 1;
add_transfer(
&context->hex.regions[data->selected_region]->data.position.r,
context->hex.regions[data->selected_region]->region,
offsetof(GPUHexRegion, position) + offsetof(HexCoord, r),
sizeof(uint32_t),
context->render.current_frame,
&context->render);
} }
update_region_info_ui(context);
break; void spin_cam(ClientContext* context, int action, int mods, unsigned int axis, float amount) {
case GLFW_KEY_L: (void)mods;
if(data->selected_region < MAX_LOADED_REGIONS) { if(action == GLFW_PRESS) context->spin[axis] += amount;
context->hex.regions[data->selected_region]->data.position.r -= 1; else if(action == GLFW_RELEASE) context->spin[axis] -= amount;
add_transfer(
&context->hex.regions[data->selected_region]->data.position.r,
context->hex.regions[data->selected_region]->region,
offsetof(GPUHexRegion, position) + offsetof(HexCoord, r),
sizeof(uint32_t),
context->render.current_frame,
&context->render);
} }
update_region_info_ui(context);
break; void spin_cam_left(EditorData* data, ClientContext* context, int action, int mods) {
case GLFW_KEY_O: (void)data;
if(data->selected_region < MAX_LOADED_REGIONS) { spin_cam(context, action, mods, 0, -1);
context->hex.regions[data->selected_region]->data.y += 1;
add_transfer(
&context->hex.regions[data->selected_region]->data.y,
context->hex.regions[data->selected_region]->region,
offsetof(GPUHexRegion, y),
sizeof(int32_t),
context->render.current_frame,
&context->render);
} }
update_region_info_ui(context);
break; void spin_cam_right(EditorData* data, ClientContext* context, int action, int mods) {
case GLFW_KEY_U: (void)data;
if(data->selected_region < MAX_LOADED_REGIONS) { spin_cam(context, action, mods, 0, 1);
context->hex.regions[data->selected_region]->data.y -= 1;
add_transfer(
&context->hex.regions[data->selected_region]->data.y,
context->hex.regions[data->selected_region]->region,
offsetof(GPUHexRegion, y),
sizeof(int32_t),
context->render.current_frame,
&context->render);
} }
update_region_info_ui(context);
break;
case GLFW_KEY_Y: void spin_cam_up(EditorData* data, ClientContext* context, int action, int mods) {
if(data->clicked_region < MAX_LOADED_REGIONS && data->clicked_vertex != 0) { (void)data;
region = context->hex.regions[data->clicked_region]; spin_cam(context, action, mods, 1, 1);
float height = region->data.hexes[data->clicked_hex].height[data->clicked_vertex-1] + 0.1; }
if(~mods & GLFW_MOD_CONTROL) { void spin_cam_down(EditorData* data, ClientContext* context, int action, int mods) {
uint32_t n_vertex[2], n_hex[2]; (void)data;
HexCoord n_region[2]; spin_cam(context, action, mods, 1, -1);
HexCoord world, region_center; }
region_qr(region->data.position, &region_center); void move_cam(ClientContext* context, int action, int mods, unsigned int axis, float amount) {
hex_qr(data->clicked_hex, &world); (void)mods;
hex_add(region_center, &world); if(action == GLFW_PRESS) context->velocity[axis] += amount;
hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex); else if(action == GLFW_RELEASE) context->velocity[axis] -= amount;
}
uint32_t n0, n1; void move_cam_up(EditorData* data, ClientContext* context, int action, int mods) {
first_matching_region(n_region[0], region->data.y, &n0, &context->hex); (void)data;
first_matching_region(n_region[1], region->data.y, &n1, &context->hex); move_cam(context, action, mods, 1, 1);
}
if(n0 != MAX_LOADED_REGIONS) set_vertex_height(height, n0, n_hex[0], n_vertex[0], context); void move_cam_down(EditorData* data, ClientContext* context, int action, int mods) {
if(n1 != MAX_LOADED_REGIONS) set_vertex_height(height, n1, n_hex[1], n_vertex[1], context); (void)data;
move_cam(context, action, mods, 1, -1);
} }
set_vertex_height(height, data->clicked_region, data->clicked_hex, data->clicked_vertex, context);
update_hex_info_ui(context); void move_cam_left(EditorData* data, ClientContext* context, int action, int mods) {
(void)data;
move_cam(context, action, mods, 0, -1);
} }
break;
case GLFW_KEY_H: void move_cam_right(EditorData* data, ClientContext* context, int action, int mods) {
if(data->clicked_region < MAX_LOADED_REGIONS && data->clicked_vertex != 0) { (void)data;
region = context->hex.regions[data->clicked_region]; move_cam(context, action, mods, 0, 1);
float height = region->data.hexes[data->clicked_hex].height[data->clicked_vertex-1] - 0.1; }
if(~mods & GLFW_MOD_CONTROL) { void move_cam_forward(EditorData* data, ClientContext* context, int action, int mods) {
uint32_t n_vertex[2], n_hex[2]; (void)data;
HexCoord n_region[2]; move_cam(context, action, mods, 2, 1);
HexCoord world, region_center; }
region_qr(region->data.position, &region_center); void move_cam_backwards(EditorData* data, ClientContext* context, int action, int mods) {
hex_qr(data->clicked_hex, &world); (void)data;
hex_add(region_center, &world); move_cam(context, action, mods, 2, -1);
hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex); }
uint32_t n0, n1; void clear_mode(EditorData* data, ClientContext* context, int action, int mods) {
first_matching_region(n_region[0], region->data.y, &n0, &context->hex); (void)mods;
first_matching_region(n_region[1], region->data.y, &n1, &context->hex); if(action == GLFW_PRESS) {
data->mode = MODE_NONE;
update_mode_string(context, data);
data->selected_count = 0;
unload_container(COLOR_PICK_CONTAINER_ID, &context->render, &context->ui);
}
}
if(n0 != MAX_LOADED_REGIONS) set_vertex_height(height, n0, n_hex[0], n_vertex[0], context); void enter_vertex_mode(EditorData* data, ClientContext* context, int action, int mods) {
if(n1 != MAX_LOADED_REGIONS) set_vertex_height(height, n1, n_hex[1], n_vertex[1], context); (void)mods;
if(action == GLFW_PRESS) {
data->mode = MODE_VERTEX;
update_mode_string(context, data);
data->selected_count = 0;
color_ui(context);
} }
set_vertex_height(height, data->clicked_region, data->clicked_hex, data->clicked_vertex, context);
update_hex_info_ui(context);
} }
break;
case GLFW_KEY_E: void enter_neighbor_mode(EditorData* data, ClientContext* context, int action, int mods) {
if(data->clicked_region < MAX_LOADED_REGIONS) { (void)mods;
region = context->hex.regions[data->clicked_region]; if(action == GLFW_PRESS) {
uint32_t n_vertex[2], n_hex[2]; data->mode = MODE_NEIGHBOR;
HexCoord n_region[2]; update_mode_string(context, data);
HexCoord world, region_center; data->selected_count = 0;
color_ui(context);
}
}
if(data->clicked_vertex != 0 && data->clicked_vertex <= 6) { void enter_hex_mode(EditorData* data, ClientContext* context, int action, int mods) {
region_qr(region->data.position, &region_center); (void)mods;
hex_qr(data->clicked_hex, &world); if(action == GLFW_PRESS) {
hex_add(region_center, &world); data->mode = MODE_HEX;
hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex); update_mode_string(context, data);
data->selected_count = 0;
color_ui(context);
}
}
uint32_t n0, n1; void enter_region_mode(EditorData* data, ClientContext* context, int action, int mods) {
first_matching_region(n_region[0], region->data.y, &n0, &context->hex); (void)mods;
first_matching_region(n_region[1], region->data.y, &n1, &context->hex); if(action == GLFW_PRESS) {
data->mode = MODE_REGION;
update_mode_string(context, data);
data->selected_count = 0;
unload_container(COLOR_PICK_CONTAINER_ID, &context->render, &context->ui);
}
}
if(n0 != MAX_LOADED_REGIONS) set_vertex_color(data->current, n0, n_hex[0], n_vertex[0], context); void editor_startup(ClientContext* context) {
if(n1 != MAX_LOADED_REGIONS) set_vertex_color(data->current, n1, n_hex[1], n_vertex[1], context); mode_string_ui(context);
// TODO: Remove when region mode is implemented
add_hex_region(context);
} }
set_vertex_color(data->current, data->clicked_region, data->clicked_hex, data->clicked_vertex, context);
update_hex_info_ui(context); void resize_selected(EditorData* data, unsigned int size) {
uint32_t* new_regions = malloc(sizeof(uint32_t)*size);
uint32_t* new_hexes = malloc(sizeof(uint32_t)*size);
uint32_t* new_vertices = malloc(sizeof(uint32_t)*size);
if(data->selected_regions != NULL) {
memcpy(new_regions, data->selected_regions, data->selected_count);
free(data->selected_regions);
} }
break;
if(data->selected_hexes != NULL) {
memcpy(new_hexes, data->selected_hexes, data->selected_count);
free(data->selected_hexes);
} }
return false; if(data->selected_vertices != NULL) {
memcpy(new_vertices, data->selected_vertices, data->selected_count);
} }
void editor_startup(ClientContext* context) { data->selected_regions = new_regions;
region_info_ui(context); data->selected_hexes = new_hexes;
hex_info_ui(context); data->selected_vertices = new_vertices;
color_ui(context); data->selected_max = size;
} }
int main() { int main() {
EditorData* data = malloc(sizeof(EditorData)); EditorData* data = malloc(sizeof(EditorData));
memset(data, 0, sizeof(EditorData)); memset(data, 0, sizeof(EditorData));
data->selected_region = MAX_LOADED_REGIONS; data->selected_count = 0;
data->clicked_region = MAX_LOADED_REGIONS; resize_selected(data, 1);
data->clicked_hex = UINT32_MAX;
data->clicked_vertex = UINT32_MAX; data->mode_key_counts[MODE_NONE] = 15;
for(int i = 0; i < MODE_MAX_ENUM; i++) {
data->mode_keys[i] = malloc(sizeof(ModeKey)*data->mode_key_counts[i]);
}
// Mode Switches
data->mode_keys[MODE_NONE][0].key = GLFW_KEY_ESCAPE;
data->mode_keys[MODE_NONE][0].logic = clear_mode;
data->mode_keys[MODE_NONE][1].key = GLFW_KEY_V;
data->mode_keys[MODE_NONE][1].logic = enter_vertex_mode;
data->mode_keys[MODE_NONE][2].key = GLFW_KEY_N;
data->mode_keys[MODE_NONE][2].logic = enter_neighbor_mode;
data->mode_keys[MODE_NONE][3].key = GLFW_KEY_H;
data->mode_keys[MODE_NONE][3].logic = enter_hex_mode;
data->mode_keys[MODE_NONE][4].key = GLFW_KEY_R;
data->mode_keys[MODE_NONE][4].logic = enter_region_mode;
// Camera Movement
data->mode_keys[MODE_NONE][5].key = GLFW_KEY_SPACE;
data->mode_keys[MODE_NONE][5].logic = move_cam_up;
data->mode_keys[MODE_NONE][6].key = GLFW_KEY_LEFT_SHIFT;
data->mode_keys[MODE_NONE][6].logic = move_cam_down;
data->mode_keys[MODE_NONE][7].key = GLFW_KEY_LEFT;
data->mode_keys[MODE_NONE][7].logic = move_cam_left;
data->mode_keys[MODE_NONE][8].key = GLFW_KEY_RIGHT;
data->mode_keys[MODE_NONE][8].logic = move_cam_right;
data->mode_keys[MODE_NONE][9].key = GLFW_KEY_UP;
data->mode_keys[MODE_NONE][9].logic = move_cam_forward;
data->mode_keys[MODE_NONE][10].key = GLFW_KEY_DOWN;
data->mode_keys[MODE_NONE][10].logic = move_cam_backwards;
// Camera Spin
data->mode_keys[MODE_NONE][11].key = GLFW_KEY_A;
data->mode_keys[MODE_NONE][11].logic = spin_cam_left;
data->mode_keys[MODE_NONE][12].key = GLFW_KEY_D;
data->mode_keys[MODE_NONE][12].logic = spin_cam_right;
data->mode_keys[MODE_NONE][13].key = GLFW_KEY_W;
data->mode_keys[MODE_NONE][13].logic = spin_cam_up;
data->mode_keys[MODE_NONE][14].key = GLFW_KEY_S;
data->mode_keys[MODE_NONE][14].logic = spin_cam_down;
return run_app(data, editor_startup, NULL, NULL, editor_key_callback, NULL, NULL, NULL); return run_app(data, editor_startup, NULL, NULL, editor_key_callback, NULL, NULL, NULL);
} }

@ -12,7 +12,7 @@ void text_callback(GLFWwindow* window, unsigned int codepoint) {
&context->render, &context->render,
codepoint)) return; codepoint)) return;
if(context->app_text != NULL && context->app_text(context, codepoint)) return; if(context->app_text != NULL) context->app_text(context, codepoint);
} }
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
@ -29,84 +29,7 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
&context->render, &context->render,
key, action, mods)) return; key, action, mods)) return;
if(context->app_key != NULL && context->app_key(context, key, action, mods)) return; if(context->app_key != NULL) context->app_key(context, key, action, mods);
switch(key) {
case GLFW_KEY_A:
if(action == GLFW_PRESS) {
context->key_spin[0] -= 1;
} else if(action == GLFW_RELEASE) {
context->key_spin[0] += 1;
}
break;
case GLFW_KEY_D:
if(action == GLFW_PRESS) {
context->key_spin[0] += 1;
} else if(action == GLFW_RELEASE) {
context->key_spin[0] -= 1;
}
break;
case GLFW_KEY_W:
if(action == GLFW_PRESS) {
context->key_spin[1] += 1;
} else if(action == GLFW_RELEASE) {
context->key_spin[1] -= 1;
}
break;
case GLFW_KEY_S:
if(action == GLFW_PRESS) {
context->key_spin[1] -= 1;
} else if(action == GLFW_RELEASE) {
context->key_spin[1] += 1;
}
break;
case GLFW_KEY_UP:
if(action == GLFW_PRESS) {
context->velocity[2] += 1;
} else if(action == GLFW_RELEASE) {
context->velocity[2] -= 1;
}
break;
case GLFW_KEY_DOWN:
if(action == GLFW_PRESS) {
context->velocity[2] -= 1;
} else if(action == GLFW_RELEASE) {
context->velocity[2] += 1;
}
break;
case GLFW_KEY_LEFT:
if(action == GLFW_PRESS) {
context->velocity[0] -= 1;
} else if(action == GLFW_RELEASE) {
context->velocity[0] += 1;
}
break;
case GLFW_KEY_RIGHT:
if(action == GLFW_PRESS) {
context->velocity[0] += 1;
} else if(action == GLFW_RELEASE) {
context->velocity[0] -= 1;
}
break;
case GLFW_KEY_LEFT_SHIFT:
if(action == GLFW_PRESS) {
context->velocity[1] -= 1;
} else if(action == GLFW_RELEASE) {
context->velocity[1] += 1;
}
break;
case GLFW_KEY_SPACE:
if(action == GLFW_PRESS) {
context->velocity[1] += 1;
} else if(action == GLFW_RELEASE) {
context->velocity[1] -= 1;
}
break;
}
} }
void button_callback(GLFWwindow* window, int button, int action, int mods) { void button_callback(GLFWwindow* window, int button, int action, int mods) {
@ -154,8 +77,6 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) {
} }
} }
if(context->app_button != NULL && context->app_button(context, cursor[0], cursor[1], button, action, mods)) return;
if(ui_intersect(cursor, &context->render, &context->ui, UI_EVENT_BUTTON, &container, &layer, &element, position)) { if(ui_intersect(cursor, &context->render, &context->ui, UI_EVENT_BUTTON, &container, &layer, &element, position)) {
Container* container_ptr = context_container(container, &context->ui); Container* container_ptr = context_container(container, &context->ui);
for(uint32_t c = 0; c < container_ptr->callback_count; c++) { for(uint32_t c = 0; c < container_ptr->callback_count; c++) {
@ -176,15 +97,7 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) {
} }
} }
if(button == GLFW_MOUSE_BUTTON_MIDDLE) { if(context->app_button != NULL) context->app_button(context, cursor[0], cursor[1], button, action, mods);
if(action == GLFW_PRESS) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
context->camera_mode = true;
} else {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
context->camera_mode = false;
}
}
} }
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
@ -203,8 +116,6 @@ void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
&context->render, &context->render,
xoffset, yoffset)) return; xoffset, yoffset)) return;
if(context->app_scroll != NULL && context->app_scroll(context, xoffset, yoffset)) return;
if(ui_intersect( if(ui_intersect(
context->ui.cursor, context->ui.cursor,
&context->render, &context->render,
@ -228,9 +139,9 @@ void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
break; break;
} }
} }
} else {
context->zoom = -yoffset;
} }
if(context->app_scroll != NULL) context->app_scroll(context, xoffset, yoffset);
} }
void cursor_callback(GLFWwindow* window, double xpos, double ypos) { void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
@ -239,18 +150,10 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
uint32_t element; uint32_t element;
uint32_t layer; uint32_t layer;
vec2 position; vec2 position;
vec2 last_cursor = {
context->ui.cursor[0],
context->ui.cursor[1],
};
context->ui.cursor[0] = xpos; context->ui.cursor[0] = xpos;
context->ui.cursor[1] = ypos; context->ui.cursor[1] = ypos;
if(context->camera_mode == true) {
context->cur_spin[0] = (xpos - last_cursor[0])/context->render.swapchain_extent.width*-100;
context->cur_spin[1] = (ypos - last_cursor[1])/context->render.swapchain_extent.height*100;
} else {
if(context->ui.active_callbacks != NULL && context->ui.active_callbacks->cursor != NULL) { if(context->ui.active_callbacks != NULL && context->ui.active_callbacks->cursor != NULL) {
Container* container_ptr = context_container(context->ui.active_container, &context->ui); Container* container_ptr = context_container(context->ui.active_container, &context->ui);
GPUDrawable* drawable_ptr = &container_ptr->layers[context->ui.active_layer].drawables_buffer[context->ui.active_element]; GPUDrawable* drawable_ptr = &container_ptr->layers[context->ui.active_layer].drawables_buffer[context->ui.active_element];
@ -271,8 +174,6 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
(context->ui.cursor[1] - element_pos[1])/element_size[1])) return; (context->ui.cursor[1] - element_pos[1])/element_size[1])) return;
} }
if(context->app_cursor != NULL && context->app_cursor(context, xpos, ypos)) return;
if(ui_intersect(context->ui.cursor, &context->render, &context->ui, UI_EVENT_CURSOR, &container, &layer, &element, position)) { if(ui_intersect(context->ui.cursor, &context->render, &context->ui, UI_EVENT_CURSOR, &container, &layer, &element, position)) {
Container* container_ptr = context_container(container, &context->ui); Container* container_ptr = context_container(container, &context->ui);
for(uint32_t c = 0; c < container_ptr->callback_count; c++) { for(uint32_t c = 0; c < container_ptr->callback_count; c++) {
@ -289,7 +190,8 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
} }
} }
} }
}
if(context->app_cursor != NULL) context->app_cursor(context, xpos, ypos);
} }
int app_main(ClientContext* context) { int app_main(ClientContext* context) {
@ -303,16 +205,13 @@ int app_main(ClientContext* context) {
// Reset callback variables // Reset callback variables
context->zoom = 0; context->zoom = 0;
context->cur_spin[0] = 0;
context->cur_spin[1] = 0;
glfwPollEvents(); glfwPollEvents();
if(context->app_frame != NULL) context->app_frame(context); if(context->app_frame != NULL) context->app_frame(context);
if((context->key_spin[0] != 0 || context->key_spin[1] != 0 || if((context->spin[0] != 0 || context->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->render.framebuffer_recreated == true)) { context->render.framebuffer_recreated == true)) {
@ -322,16 +221,14 @@ int app_main(ClientContext* context) {
VK_RESULT(update_ui_context_resolution(&context->ui, &context->render)); 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->spin[0]*delta_time*context->spin_speed;
context->rotation[0] += (float)context->cur_spin[0]*delta_time*context->cur_spin_speed;
if(context->rotation[0] > 2*M_PI) { if(context->rotation[0] > 2*M_PI) {
context->rotation[0] -= 2*M_PI; context->rotation[0] -= 2*M_PI;
} else if(context->rotation[0] < 0) { } else if(context->rotation[0] < 0) {
context->rotation[0] += 2*M_PI; context->rotation[0] += 2*M_PI;
} }
context->rotation[1] += (float)context->key_spin[1]*delta_time*context->key_spin_speed; context->rotation[1] += (float)context->spin[1]*delta_time*context->spin_speed;
context->rotation[1] += (float)context->cur_spin[1]*delta_time*context->cur_spin_speed;
if(context->rotation[1] > (M_PI/2 - 0.1)) { if(context->rotation[1] > (M_PI/2 - 0.1)) {
context->rotation[1] = (M_PI/2 - 0.1); context->rotation[1] = (M_PI/2 - 0.1);
} else if(context->rotation[1] < 0) { } else if(context->rotation[1] < 0) {
@ -393,8 +290,7 @@ int run_app(
context->rotation[0] = 3*M_PI/2; context->rotation[0] = 3*M_PI/2;
context->rotation[1] = M_PI/4; context->rotation[1] = M_PI/4;
context->distance = 25; context->distance = 25;
context->key_spin_speed = 1.0; context->spin_speed = 1.0;
context->cur_spin_speed = 1.0;
context->zoom_speed = 1.0; context->zoom_speed = 1.0;
context->move_speed = 0.1; context->move_speed = 0.1;

@ -1064,6 +1064,10 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) {
return VK_ERROR_VALIDATION_FAILED_EXT; return VK_ERROR_VALIDATION_FAILED_EXT;
} }
context->swapchain_command_buffer_record_id = 1;
context->swapchain_command_buffer_record_ids = malloc(sizeof(uint64_t)*context->swapchain_image_count);
memset(context->swapchain_command_buffer_record_ids, 0, sizeof(uint64_t)*context->swapchain_image_count);
VK_RESULT(create_image_views( VK_RESULT(create_image_views(
context->device, context->device,
context->swapchain_image_count, context->swapchain_image_count,

@ -227,10 +227,45 @@ VkResult create_ui_pipeline(
return VK_SUCCESS; return VK_SUCCESS;
} }
VkResult create_container( VkResult unload_container(
uint32_t id,
RenderContext* gpu,
UIContext* context) {
uint32_t index = 0xFFFFFFFF;
for(uint32_t i = 0; i < context->max_containers; i++) {
if(context->containers[i].id == id) {
index = i;
break;
}
}
if(index == 0xFFFFFFFF) {
return VK_ERROR_VALIDATION_FAILED_EXT;
}
context->containers[index].id = 0;
for(uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vmaDestroyBuffer(gpu->allocator, context->containers[index].container[i], context->containers[index].container_memory[i]);
context->containers[index].address[i] = 0;
}
context->containers[index].layer_count = 0;
return VK_SUCCESS;
}
VkResult load_container(
ContainerInput* container, ContainerInput* container,
RenderContext* gpu, RenderContext* gpu,
UIContext* context) { UIContext* context) {
if(container == NULL) return VK_ERROR_VALIDATION_FAILED_EXT;
if(container->id == 0) return VK_ERROR_VALIDATION_FAILED_EXT;
for(uint32_t i = 0; i < context->max_containers; i++) {
if(context->containers[i].id == container->id) return VK_ERROR_VALIDATION_FAILED_EXT;
}
uint32_t index = 0xFFFFFFFF; uint32_t index = 0xFFFFFFFF;
for(uint32_t i = 0; i < context->max_containers; i++) { for(uint32_t i = 0; i < context->max_containers; i++) {
if(context->containers[i].id == 0x00000000) { if(context->containers[i].id == 0x00000000) {
@ -1167,7 +1202,7 @@ Container* context_container(uint32_t container_id, UIContext* ui) {
} }
VkResult update_ui_string( VkResult update_ui_string(
char* string, const char* string,
uint32_t container_id, uint32_t container_id,
uint32_t layer_index, uint32_t layer_index,
uint32_t string_index, uint32_t string_index,