Moved highlight/point/ray to a list instead of static hover/click/selected

main
noah metz 2024-11-24 21:44:36 -07:00
parent f2af2b8055
commit 4379e6cd9b
9 changed files with 290 additions and 287 deletions

@ -2,10 +2,15 @@
#define HEX_H
#include "gpu.h"
#include "vulkan/vulkan_core.h"
#define MAX_RAYS 10
#define MAX_HIGHLIGHTS 10
#define MAX_POINTS 10
#define MAX_LOADED_REGIONS 2500
#define REGION_SIZE 10
#define REGION_HEX_COUNT (3*REGION_SIZE*(REGION_SIZE-1)+1)
#define MAX_LOADED_REGIONS (51*51)
#define HEX_X 0.75
#define SQRT3 1.732050807568877193176604123436845839023590087890625
#define HEX_Z (SQRT3/2)
@ -49,20 +54,35 @@ typedef struct HexRegionStruct {
GPUHexRegion data;
} HexRegion;
typedef struct GPURayStruct {
vec4 start;
vec4 end;
vec4 color;
} GPURay;
typedef struct GPUHighlightStruct {
vec4 color;
uint32_t region;
uint32_t hex;
float offset;
} GPUHighlight;
typedef struct GPUPointStruct {
vec4 color;
uint32_t region;
uint32_t hex;
uint32_t vertex;
float size;
float offset;
} GPUPoint;
typedef struct GPUHexContextStruct {
mat4 proj;
mat4 view;
vec4 click_start;
vec4 click_end;
vec4 hover_start;
vec4 hover_end;
uint32_t current_map;
uint32_t clicked_region;
uint32_t clicked_hex;
uint32_t clicked_vertex;
uint32_t hovered_region;
uint32_t hovered_hex;
uint32_t hovered_vertex;
VkDeviceAddress rays;
VkDeviceAddress points;
VkDeviceAddress highlights;
VkDeviceAddress regions[MAX_LOADED_REGIONS];
} GPUHexContext;
@ -71,14 +91,23 @@ typedef struct HexContextStruct {
VkBuffer context[MAX_FRAMES_IN_FLIGHT];
VmaAllocation context_memory[MAX_FRAMES_IN_FLIGHT];
VkBuffer rays[MAX_FRAMES_IN_FLIGHT];
VkBuffer points[MAX_FRAMES_IN_FLIGHT];
VkBuffer highlights[MAX_FRAMES_IN_FLIGHT];
VmaAllocation rays_memory[MAX_FRAMES_IN_FLIGHT];
VmaAllocation points_memory[MAX_FRAMES_IN_FLIGHT];
VmaAllocation highlights_memory[MAX_FRAMES_IN_FLIGHT];
GPURay rays_buffer[MAX_RAYS];
GPUHighlight highlights_buffer[MAX_HIGHLIGHTS];
GPUPoint points_buffer[MAX_POINTS];
mat4 inverse;
GraphicsPipeline graphics;
GraphicsPipeline highlight_pipeline;
GraphicsPipeline point_pipeline;
#ifdef DRAW_HEX_RAYS
GraphicsPipeline ray_pipeline;
#endif
HexRegion* regions[MAX_LOADED_REGIONS];
GPUHexContext data;
@ -130,16 +159,6 @@ VkResult update_hex_view(
RenderContext* gpu,
HexContext* hex);
VkResult update_hex_hover(
double cursor[2],
HexContext* hex,
RenderContext* gpu);
VkResult update_hex_click(
double cursor[2],
HexContext* hex,
RenderContext* gpu);
void hex_qr(uint32_t hex, HexCoord* world);
void region_qr(HexCoord region, HexCoord* world);
@ -154,5 +173,4 @@ void hex_vertex_neighbors(
void first_matching_region(HexCoord coord, int y, uint32_t* region, HexContext* context);
#endif

@ -11,20 +11,47 @@ layout(std430, buffer_reference) readonly buffer Region {
Hex hexes[];
};
struct Highlight {
vec4 color;
uint region;
uint hex;
float offset;
};
layout(std430, buffer_reference) readonly buffer HighlightList {
Highlight h[];
};
struct Point {
vec4 color;
uint region;
uint hex;
uint vertex;
float size;
float offset;
};
layout(std430, buffer_reference) readonly buffer PointList {
Point p[];
};
struct Ray {
vec4 start;
vec4 end;
vec4 color;
};
layout(std430, buffer_reference) readonly buffer RayList {
Ray r[];
};
layout(std430, buffer_reference) readonly buffer HexContext {
mat4 proj;
mat4 view;
vec4 click_start;
vec4 click_end;
vec4 hover_start;
vec4 hover_end;
uint current_map;
uint clicked_region;
uint clicked_hex;
uint clicked_vertex;
uint hovered_region;
uint hovered_hex;
uint hovered_vertex;
RayList rays;
PointList points;
HighlightList highlights;
Region regions[];
};

@ -6,51 +6,48 @@
layout(location = 0) flat out vec4 color;
void main() {
uint hex_index;
Region region;
float raise = 0.01;
if(gl_InstanceIndex == 0) {
hex_index = pc.context.clicked_hex;
region = pc.context.regions[pc.context.clicked_region];
color = vec4(0.5, 0.5, 0.5, 0.3);
uint hex_index = pc.context.highlights.h[gl_InstanceIndex].hex;
if(hex_index != 0xFFFFFFFF) {
Region region = pc.context.regions[pc.context.highlights.h[gl_InstanceIndex].region];
color = pc.context.highlights.h[gl_InstanceIndex].color;
float raise = pc.context.highlights.h[gl_InstanceIndex].offset;
vec2 region_qr = vec2(region.q, region.r);
vec4 region_pos = vec4(0, 0, 0, 0);
region_pos.x = (region_qr.x+region_qr.y/2)*region_width - region_qr.y*x/2;
region_pos.z = 0.75*region_qr.y*region_height + 0.25*region_qr.y*z + 0.5*region_qr.x*z;
float radius = 0;
float ring = 0;
int side = 0;
if(hex_index != 0) {
radius = floor(0.5 + sqrt(12*hex_index-3)/6);
ring = hex_index - (3*radius*radius - 3*radius + 1);
side = int(floor(ring/radius));
}
vec4 position = vertices[indices[gl_VertexIndex]]
+ (starts[side]*radius)
+ (direction[side]*(ring-(radius*side)))
+ region_pos;
if(gl_VertexIndex % 3 == 0) {
position.y = (region.hexes[hex_index].heights[0] +
region.hexes[hex_index].heights[1] +
region.hexes[hex_index].heights[2] +
region.hexes[hex_index].heights[3] +
region.hexes[hex_index].heights[4] +
region.hexes[hex_index].heights[5])/6 + region.y;
} else {
position.y = region.hexes[hex_index].heights[indices[gl_VertexIndex]-1] + region.y;
}
position.y += raise;
gl_Position = pc.context.proj * pc.context.view * position;
} else {
hex_index = pc.context.hovered_hex;
region = pc.context.regions[pc.context.hovered_region];
color = vec4(0.25, 0.25, 0.25, 0.3);
gl_Position = vec4(0, 0, 0, 0);
color = vec4(0, 0, 0, 0);
}
vec2 region_qr = vec2(region.q, region.r);
vec4 region_pos = vec4(0, 0, 0, 0);
region_pos.x = (region_qr.x+region_qr.y/2)*region_width - region_qr.y*x/2;
region_pos.z = 0.75*region_qr.y*region_height + 0.25*region_qr.y*z + 0.5*region_qr.x*z;
float radius = 0;
float ring = 0;
int side = 0;
if(hex_index != 0) {
radius = floor(0.5 + sqrt(12*hex_index-3)/6);
ring = hex_index - (3*radius*radius - 3*radius + 1);
side = int(floor(ring/radius));
}
vec4 position = vertices[indices[gl_VertexIndex]]
+ (starts[side]*radius)
+ (direction[side]*(ring-(radius*side)))
+ region_pos;
if(gl_VertexIndex % 3 == 0) {
position.y = (region.hexes[hex_index].heights[0] +
region.hexes[hex_index].heights[1] +
region.hexes[hex_index].heights[2] +
region.hexes[hex_index].heights[3] +
region.hexes[hex_index].heights[4] +
region.hexes[hex_index].heights[5])/6 + region.y;
} else {
position.y = region.hexes[hex_index].heights[indices[gl_VertexIndex]-1] + region.y;
}
position.y += raise;
gl_Position = pc.context.proj * pc.context.view * position;
}

@ -6,49 +6,39 @@
layout(location = 0) flat out vec4 color;
void main() {
uint hex_index;
uint vertex_index;
Region region;
float raise;
if(gl_InstanceIndex == 0) {
hex_index = pc.context.clicked_hex;
region = pc.context.regions[pc.context.clicked_region];
vertex_index = pc.context.clicked_vertex;
color = vec4(1, 0, 0, 1);
gl_PointSize = 15;
raise = 0.01;
uint hex_index = pc.context.points.p[gl_InstanceIndex].hex;
uint vertex_index = pc.context.points.p[gl_InstanceIndex].vertex;
Region region = pc.context.regions[pc.context.points.p[gl_InstanceIndex].region];
float raise = pc.context.points.p[gl_InstanceIndex].offset;
if(hex_index != 0xFFFFFFFF) {
color = pc.context.points.p[gl_InstanceIndex].color;
gl_PointSize = pc.context.points.p[gl_InstanceIndex].size;
vec2 region_qr = vec2(region.q, region.r);
vec4 region_pos = vec4(0, 0, 0, 0);
region_pos.x = (region_qr.x+region_qr.y/2)*region_width - region_qr.y*x/2;
region_pos.z = 0.75*region_qr.y*region_height + 0.25*region_qr.y*z + 0.5*region_qr.x*z;
float radius = 0;
float ring = 0;
int side = 0;
if(hex_index != 0) {
radius = floor(0.5 + sqrt(12*hex_index-3)/6);
ring = hex_index - (3*radius*radius - 3*radius + 1);
side = int(floor(ring/radius));
}
vec4 position = vertices[vertex_index]
+ (starts[side]*radius)
+ (direction[side]*(ring-(radius*side)))
+ region_pos;
position.y = region.hexes[hex_index].heights[vertex_index-1] + region.y + raise;
gl_Position = pc.context.proj * pc.context.view * position;
} else {
hex_index = pc.context.hovered_hex;
region = pc.context.regions[pc.context.hovered_region];
vertex_index = pc.context.hovered_vertex;
color = vec4(0, 1, 0, 1);
gl_PointSize = 10;
raise = 0.015;
gl_Position = vec4(0, 0, 0, 0);
color = vec4(0, 0, 0, 0);
}
vec2 region_qr = vec2(region.q, region.r);
vec4 region_pos = vec4(0, 0, 0, 0);
region_pos.x = (region_qr.x+region_qr.y/2)*region_width - region_qr.y*x/2;
region_pos.z = 0.75*region_qr.y*region_height + 0.25*region_qr.y*z + 0.5*region_qr.x*z;
float radius = 0;
float ring = 0;
int side = 0;
if(hex_index != 0) {
radius = floor(0.5 + sqrt(12*hex_index-3)/6);
ring = hex_index - (3*radius*radius - 3*radius + 1);
side = int(floor(ring/radius));
}
vec4 position = vertices[vertex_index]
+ (starts[side]*radius)
+ (direction[side]*(ring-(radius*side)))
+ region_pos;
position.y = region.hexes[hex_index].heights[vertex_index-1] + region.y + raise;
gl_Position = pc.context.proj * pc.context.view * position;
}

@ -6,19 +6,10 @@
layout(location = 0) flat out vec4 color;
void main() {
if(gl_InstanceIndex == 0) {
color = vec4(1, 0, 0, 1);
if(gl_VertexIndex == 0) {
gl_Position = pc.context.proj * pc.context.view * pc.context.click_start;
} else {
gl_Position = pc.context.proj * pc.context.view * pc.context.click_end;
}
if(gl_VertexIndex == 0) {
gl_Position = pc.context.proj * pc.context.view * pc.context.rays.r[gl_InstanceIndex].start;
} else {
color = vec4(0, 1, 0, 1);
if(gl_VertexIndex == 0) {
gl_Position = pc.context.proj * pc.context.view * pc.context.hover_start;
} else {
gl_Position = pc.context.proj * pc.context.view * pc.context.hover_end;
}
gl_Position = pc.context.proj * pc.context.view * pc.context.rays.r[gl_InstanceIndex].end;
}
color = pc.context.rays.r[gl_InstanceIndex].color;
}

@ -33,15 +33,13 @@ void record_hex_draw(VkCommandBuffer command_buffer, HexContext* hex, double tim
vkCmdDraw(command_buffer, 18, REGION_HEX_COUNT*MAX_LOADED_REGIONS, 0, 0);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, hex->point_pipeline.pipeline);
vkCmdDraw(command_buffer, 1, 2, 0, 0);
vkCmdDraw(command_buffer, 1, MAX_POINTS, 0, 0);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, hex->highlight_pipeline.pipeline);
vkCmdDraw(command_buffer, 18, 2, 0, 0);
vkCmdDraw(command_buffer, 18, MAX_HIGHLIGHTS, 0, 0);
#ifdef DRAW_HEX_RAYS
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, hex->ray_pipeline.pipeline);
vkCmdDraw(command_buffer, 2, 2, 0, 0);
#endif
}
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) {

@ -11,9 +11,9 @@
typedef struct EditorDataStruct {
uint32_t selected_region;
uint32_t last_clicked_region;
uint32_t last_clicked_hex;
uint32_t last_clicked_vertex;
uint32_t clicked_region;
uint32_t clicked_hex;
uint32_t clicked_vertex;
double current_hsv[3];
vec4 current;
@ -862,10 +862,8 @@ VkResult update_region_info_ui(ClientContext* context) {
char temp[20];
VkResult result;
EditorData* data = context->app_data;
HexRegion* selected_region = context->hex.regions[data->selected_region];
if(selected_region == NULL) {
if(data->selected_region >= MAX_LOADED_REGIONS) {
snprintf(temp,
sizeof(temp),
"");
@ -889,6 +887,7 @@ VkResult update_region_info_ui(ClientContext* context) {
"");
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);
@ -919,10 +918,10 @@ VkResult update_region_info_ui(ClientContext* context) {
VkResult update_hex_info_ui(ClientContext* context) {
char temp[20];
VkResult result;
HexRegion* region = context->hex.regions[context->hex.data.clicked_region];
EditorData* data = context->app_data;
if(region == NULL) {
if(data->clicked_region >= MAX_LOADED_REGIONS) {
snprintf(
temp,
sizeof(temp),
@ -971,17 +970,19 @@ VkResult update_hex_info_ui(ClientContext* context) {
"");
VK_RESULT(update_ui_string(temp, 0x02, 0, 7, &context->ui, &context->render));
} else {
GPUHex* hex = &region->data.hexes[context->hex.data.clicked_hex];
HexRegion* region = context->hex.regions[data->clicked_region];
GPUHex* hex = &region->data.hexes[data->clicked_hex];
snprintf(temp,
sizeof(temp),
"%d-%d",
context->hex.data.clicked_region,
context->hex.data.clicked_hex);
data->clicked_region,
data->clicked_hex);
VK_RESULT(update_ui_string(temp, 0x02, 0, 0, &context->ui, &context->render));
HexCoord hex_world;
hex_qr(context->hex.data.clicked_hex, &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);
@ -994,7 +995,7 @@ VkResult update_hex_info_ui(ClientContext* context) {
hex_world.q,
hex_world.r,
region->data.y,
context->hex.data.clicked_vertex);
data->clicked_vertex);
VK_RESULT(update_ui_string(temp, 0x02, 0, 1, &context->ui, &context->render));
snprintf(
@ -1059,21 +1060,23 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
break;
case GLFW_KEY_MINUS:
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;
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);
}
update_region_info_ui(context);
update_hex_info_ui(context);
break;
case GLFW_KEY_LEFT_BRACKET:
@ -1101,7 +1104,7 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
break;
case GLFW_KEY_I:
if(context->hex.regions[data->selected_region] != NULL) {
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,
@ -1114,7 +1117,7 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
update_region_info_ui(context);
break;
case GLFW_KEY_K:
if(context->hex.regions[data->selected_region] != NULL) {
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,
@ -1127,7 +1130,7 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
update_region_info_ui(context);
break;
case GLFW_KEY_J:
if(context->hex.regions[data->selected_region] != NULL) {
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,
@ -1140,7 +1143,7 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
update_region_info_ui(context);
break;
case GLFW_KEY_L:
if(context->hex.regions[data->selected_region] != NULL) {
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,
@ -1153,7 +1156,7 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
update_region_info_ui(context);
break;
case GLFW_KEY_O:
if(context->hex.regions[data->selected_region] != NULL) {
if(data->selected_region < MAX_LOADED_REGIONS) {
context->hex.regions[data->selected_region]->data.y += 1;
add_transfer(
&context->hex.regions[data->selected_region]->data.y,
@ -1166,7 +1169,7 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
update_region_info_ui(context);
break;
case GLFW_KEY_U:
if(context->hex.regions[data->selected_region] != NULL) {
if(data->selected_region < MAX_LOADED_REGIONS) {
context->hex.regions[data->selected_region]->data.y -= 1;
add_transfer(
&context->hex.regions[data->selected_region]->data.y,
@ -1180,9 +1183,9 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
break;
case GLFW_KEY_Y:
region = context->hex.regions[context->hex.data.clicked_region];
if(region != NULL && context->hex.data.clicked_vertex != 0) {
float height = region->data.hexes[context->hex.data.clicked_hex].height[context->hex.data.clicked_vertex-1] + 0.1;
if(data->clicked_region < MAX_LOADED_REGIONS && data->clicked_vertex != 0) {
region = context->hex.regions[data->clicked_region];
float height = region->data.hexes[data->clicked_hex].height[data->clicked_vertex-1] + 0.1;
if(~mods & GLFW_MOD_CONTROL) {
uint32_t n_vertex[2], n_hex[2];
@ -1190,9 +1193,9 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
HexCoord world, region_center;
region_qr(region->data.position, &region_center);
hex_qr(context->hex.data.clicked_hex, &world);
hex_qr(data->clicked_hex, &world);
hex_add(region_center, &world);
hex_vertex_neighbors(context->hex.data.clicked_vertex, world, n_vertex, n_region, n_hex);
hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex);
uint32_t n0, n1;
first_matching_region(n_region[0], region->data.y, &n0, &context->hex);
@ -1201,15 +1204,15 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
if(n0 != MAX_LOADED_REGIONS) set_vertex_height(height, n0, n_hex[0], n_vertex[0], context);
if(n1 != MAX_LOADED_REGIONS) set_vertex_height(height, n1, n_hex[1], n_vertex[1], context);
}
set_vertex_height(height, context->hex.data.clicked_region, context->hex.data.clicked_hex, context->hex.data.clicked_vertex, context);
set_vertex_height(height, data->clicked_region, data->clicked_hex, data->clicked_vertex, context);
update_hex_info_ui(context);
}
break;
case GLFW_KEY_H:
region = context->hex.regions[context->hex.data.clicked_region];
if(region != NULL && context->hex.data.clicked_vertex != 0) {
float height = region->data.hexes[context->hex.data.clicked_hex].height[context->hex.data.clicked_vertex-1] - 0.1;
if(data->clicked_region < MAX_LOADED_REGIONS && data->clicked_vertex != 0) {
region = context->hex.regions[data->clicked_region];
float height = region->data.hexes[data->clicked_hex].height[data->clicked_vertex-1] - 0.1;
if(~mods & GLFW_MOD_CONTROL) {
uint32_t n_vertex[2], n_hex[2];
@ -1217,9 +1220,9 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
HexCoord world, region_center;
region_qr(region->data.position, &region_center);
hex_qr(context->hex.data.clicked_hex, &world);
hex_qr(data->clicked_hex, &world);
hex_add(region_center, &world);
hex_vertex_neighbors(context->hex.data.clicked_vertex, world, n_vertex, n_region, n_hex);
hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex);
uint32_t n0, n1;
first_matching_region(n_region[0], region->data.y, &n0, &context->hex);
@ -1228,23 +1231,23 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
if(n0 != MAX_LOADED_REGIONS) set_vertex_height(height, n0, n_hex[0], n_vertex[0], context);
if(n1 != MAX_LOADED_REGIONS) set_vertex_height(height, n1, n_hex[1], n_vertex[1], context);
}
set_vertex_height(height, context->hex.data.clicked_region, context->hex.data.clicked_hex, context->hex.data.clicked_vertex, 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:
region = context->hex.regions[context->hex.data.clicked_region];
if(region != NULL) {
if(data->clicked_region < MAX_LOADED_REGIONS) {
region = context->hex.regions[data->clicked_region];
uint32_t n_vertex[2], n_hex[2];
HexCoord n_region[2];
HexCoord world, region_center;
if(context->hex.data.clicked_vertex != 0) {
if(data->clicked_vertex != 0 && data->clicked_vertex <= 6) {
region_qr(region->data.position, &region_center);
hex_qr(context->hex.data.clicked_hex, &world);
hex_qr(data->clicked_hex, &world);
hex_add(region_center, &world);
hex_vertex_neighbors(context->hex.data.clicked_vertex, world, n_vertex, n_region, n_hex);
hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex);
uint32_t n0, n1;
first_matching_region(n_region[0], region->data.y, &n0, &context->hex);
@ -1253,7 +1256,7 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
if(n0 != MAX_LOADED_REGIONS) set_vertex_color(data->current, n0, n_hex[0], n_vertex[0], context);
if(n1 != MAX_LOADED_REGIONS) set_vertex_color(data->current, n1, n_hex[1], n_vertex[1], context);
}
set_vertex_color(data->current, context->hex.data.clicked_region, context->hex.data.clicked_hex, context->hex.data.clicked_vertex, context);
set_vertex_color(data->current, data->clicked_region, data->clicked_hex, data->clicked_vertex, context);
update_hex_info_ui(context);
}
break;
@ -1262,18 +1265,6 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
return false;
}
void editor_frame(ClientContext* context) {
EditorData* data = context->app_data;
if(data->last_clicked_region != context->hex.data.clicked_region ||
data->last_clicked_hex != context->hex.data.clicked_hex ||
data->last_clicked_vertex != context->hex.data.clicked_vertex) {
data->last_clicked_region = context->hex.data.clicked_region;
data->last_clicked_hex = context->hex.data.clicked_hex;
data->last_clicked_vertex = context->hex.data.clicked_vertex;
update_hex_info_ui(context);
}
}
void editor_startup(ClientContext* context) {
region_info_ui(context);
hex_info_ui(context);
@ -1284,7 +1275,9 @@ int main() {
EditorData* data = malloc(sizeof(EditorData));
memset(data, 0, sizeof(EditorData));
data->selected_region = MAX_LOADED_REGIONS;
data->last_clicked_region = MAX_LOADED_REGIONS;
data->clicked_region = MAX_LOADED_REGIONS;
data->clicked_hex = UINT32_MAX;
data->clicked_vertex = UINT32_MAX;
return run_app(data, editor_startup, editor_frame, NULL, editor_key_callback, NULL, NULL, NULL);
return run_app(data, editor_startup, NULL, NULL, editor_key_callback, NULL, NULL, NULL);
}

@ -176,7 +176,6 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) {
}
}
update_hex_click(cursor, &context->hex, &context->render);
if(button == GLFW_MOUSE_BUTTON_MIDDLE) {
if(action == GLFW_PRESS) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
@ -289,8 +288,6 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
break;
}
}
} else {
update_hex_hover(context->ui.cursor, &context->hex, &context->render);
}
}
}

@ -705,9 +705,7 @@ VkResult create_hex_context(
VkResult result;
VK_RESULT(create_hex_pipeline(gpu, &context->graphics));
#ifdef DRAW_HEX_RAYS
VK_RESULT(create_ray_pipeline(gpu, &context->ray_pipeline));
#endif
VK_RESULT(create_hex_highlight_pipeline(gpu, &context->highlight_pipeline));
VK_RESULT(create_point_pipeline(gpu, &context->point_pipeline));
@ -727,7 +725,48 @@ VkResult create_hex_context(
&context->context[i],
&context->context_memory[i]));
context->address[i] = buffer_address(gpu->device, context->context[i]);
VK_RESULT(create_storage_buffer(
gpu->allocator,
0,
sizeof(GPURay)*MAX_RAYS,
&context->rays[i],
&context->rays_memory[i]));
VK_RESULT(create_storage_buffer(
gpu->allocator,
0,
sizeof(GPUPoint)*MAX_POINTS,
&context->points[i],
&context->points_memory[i]));
VK_RESULT(create_storage_buffer(
gpu->allocator,
0,
sizeof(GPUHighlight)*MAX_HIGHLIGHTS,
&context->highlights[i],
&context->highlights_memory[i]));
}
for(uint32_t i = 0; i < MAX_HIGHLIGHTS; i++) {
uint32_t temp = 0xFFFFFFFF;
VK_RESULT(add_transfers(
&temp,
context->highlights,
sizeof(GPUHighlight)*i + offsetof(GPUHighlight, hex),
sizeof(uint32_t),
gpu));
}
for(uint32_t i = 0; i < MAX_POINTS; i++) {
uint32_t temp = 0xFFFFFFFF;
VK_RESULT(add_transfers(
&temp,
context->points,
sizeof(GPUPoint)*i + offsetof(GPUPoint, hex),
sizeof(uint32_t),
gpu));
}
VK_RESULT(add_transfers(
&context->data,
context->context,
@ -735,6 +774,37 @@ VkResult create_hex_context(
sizeof(GPUHexContext),
gpu));
for(uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
VkDeviceAddress rays, points, highlights;
rays = buffer_address(gpu->device, context->rays[i]);
points = buffer_address(gpu->device, context->points[i]);
highlights = buffer_address(gpu->device, context->highlights[i]);
VK_RESULT(add_transfer(
&rays,
context->context[i],
offsetof(GPUHexContext, rays),
sizeof(VkDeviceAddress),
i,
gpu));
VK_RESULT(add_transfer(
&points,
context->context[i],
offsetof(GPUHexContext, points),
sizeof(VkDeviceAddress),
i,
gpu));
VK_RESULT(add_transfer(
&highlights,
context->context[i],
offsetof(GPUHexContext, highlights),
sizeof(VkDeviceAddress),
i,
gpu));
}
return VK_SUCCESS;
}
@ -1072,84 +1142,6 @@ void cursor_to_world_ray(RenderContext* gpu, mat4 inverse, double cursor[2], vec
glm_mat4_mulv(inverse, transformed_end, end);
}
VkResult update_hex_hover(
double cursor[2],
HexContext* hex,
RenderContext* gpu) {
cursor_to_world_ray(
gpu,
hex->inverse,
cursor,
hex->data.hover_start,
hex->data.hover_end);
add_transfers(
&hex->data.hover_start,
hex->context,
offsetof(GPUHexContext, hover_start),
sizeof(vec4)*2,
gpu);
float distance;
if(ray_world_intersect(
&distance,
&hex->data.hovered_vertex,
&hex->data.hovered_region,
&hex->data.hovered_hex,
hex->data.hover_start,
hex->data.hover_end,
hex)) {
add_transfers(
&hex->data.hovered_region,
hex->context,
offsetof(GPUHexContext, hovered_region),
sizeof(uint32_t)*3,
gpu);
}
return VK_SUCCESS;
}
VkResult update_hex_click(
double cursor[2],
HexContext* hex,
RenderContext* gpu) {
VkResult result;
float distance;
cursor_to_world_ray(
gpu,
hex->inverse,
cursor,
hex->data.click_start,
hex->data.click_end);
VK_RESULT(add_transfers(
&hex->data.click_start,
hex->context,
offsetof(GPUHexContext, click_start),
sizeof(vec4)*2,
gpu));
if(ray_world_intersect(
&distance,
&hex->data.clicked_vertex,
&hex->data.clicked_region,
&hex->data.clicked_hex,
hex->data.click_start,
hex->data.click_end,
hex)) {
VK_RESULT(add_transfers(
&hex->data.clicked_region,
hex->context,
offsetof(GPUHexContext, clicked_region),
sizeof(uint32_t)*3,
gpu));
}
return VK_SUCCESS;
}
void hex_qr(uint32_t hex, HexCoord* world) {
float radius = 0;
float ring = 0;