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 #define HEX_H
#include "gpu.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_SIZE 10
#define REGION_HEX_COUNT (3*REGION_SIZE*(REGION_SIZE-1)+1) #define REGION_HEX_COUNT (3*REGION_SIZE*(REGION_SIZE-1)+1)
#define MAX_LOADED_REGIONS (51*51)
#define HEX_X 0.75 #define HEX_X 0.75
#define SQRT3 1.732050807568877193176604123436845839023590087890625 #define SQRT3 1.732050807568877193176604123436845839023590087890625
#define HEX_Z (SQRT3/2) #define HEX_Z (SQRT3/2)
@ -49,20 +54,35 @@ typedef struct HexRegionStruct {
GPUHexRegion data; GPUHexRegion data;
} HexRegion; } 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 { typedef struct GPUHexContextStruct {
mat4 proj; mat4 proj;
mat4 view; mat4 view;
vec4 click_start;
vec4 click_end;
vec4 hover_start;
vec4 hover_end;
uint32_t current_map; uint32_t current_map;
uint32_t clicked_region; VkDeviceAddress rays;
uint32_t clicked_hex; VkDeviceAddress points;
uint32_t clicked_vertex; VkDeviceAddress highlights;
uint32_t hovered_region;
uint32_t hovered_hex;
uint32_t hovered_vertex;
VkDeviceAddress regions[MAX_LOADED_REGIONS]; VkDeviceAddress regions[MAX_LOADED_REGIONS];
} GPUHexContext; } GPUHexContext;
@ -71,14 +91,23 @@ typedef struct HexContextStruct {
VkBuffer context[MAX_FRAMES_IN_FLIGHT]; VkBuffer context[MAX_FRAMES_IN_FLIGHT];
VmaAllocation context_memory[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; mat4 inverse;
GraphicsPipeline graphics; GraphicsPipeline graphics;
GraphicsPipeline highlight_pipeline; GraphicsPipeline highlight_pipeline;
GraphicsPipeline point_pipeline; GraphicsPipeline point_pipeline;
#ifdef DRAW_HEX_RAYS
GraphicsPipeline ray_pipeline; GraphicsPipeline ray_pipeline;
#endif
HexRegion* regions[MAX_LOADED_REGIONS]; HexRegion* regions[MAX_LOADED_REGIONS];
GPUHexContext data; GPUHexContext data;
@ -130,16 +159,6 @@ VkResult update_hex_view(
RenderContext* gpu, RenderContext* gpu,
HexContext* hex); 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 hex_qr(uint32_t hex, HexCoord* world);
void region_qr(HexCoord region, 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); void first_matching_region(HexCoord coord, int y, uint32_t* region, HexContext* context);
#endif #endif

@ -11,20 +11,47 @@ layout(std430, buffer_reference) readonly buffer Region {
Hex hexes[]; 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 { layout(std430, buffer_reference) readonly buffer HexContext {
mat4 proj; mat4 proj;
mat4 view; mat4 view;
vec4 click_start;
vec4 click_end;
vec4 hover_start;
vec4 hover_end;
uint current_map; uint current_map;
uint clicked_region; RayList rays;
uint clicked_hex; PointList points;
uint clicked_vertex; HighlightList highlights;
uint hovered_region;
uint hovered_hex;
uint hovered_vertex;
Region regions[]; Region regions[];
}; };

@ -6,51 +6,48 @@
layout(location = 0) flat out vec4 color; layout(location = 0) flat out vec4 color;
void main() { void main() {
uint hex_index; uint hex_index = pc.context.highlights.h[gl_InstanceIndex].hex;
Region region; if(hex_index != 0xFFFFFFFF) {
float raise = 0.01; Region region = pc.context.regions[pc.context.highlights.h[gl_InstanceIndex].region];
if(gl_InstanceIndex == 0) { color = pc.context.highlights.h[gl_InstanceIndex].color;
hex_index = pc.context.clicked_hex; float raise = pc.context.highlights.h[gl_InstanceIndex].offset;
region = pc.context.regions[pc.context.clicked_region];
color = vec4(0.5, 0.5, 0.5, 0.3); 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 { } else {
hex_index = pc.context.hovered_hex; gl_Position = vec4(0, 0, 0, 0);
region = pc.context.regions[pc.context.hovered_region]; color = vec4(0, 0, 0, 0);
color = vec4(0.25, 0.25, 0.25, 0.3);
} }
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; layout(location = 0) flat out vec4 color;
void main() { void main() {
uint hex_index; uint hex_index = pc.context.points.p[gl_InstanceIndex].hex;
uint vertex_index; uint vertex_index = pc.context.points.p[gl_InstanceIndex].vertex;
Region region; Region region = pc.context.regions[pc.context.points.p[gl_InstanceIndex].region];
float raise; float raise = pc.context.points.p[gl_InstanceIndex].offset;
if(hex_index != 0xFFFFFFFF) {
color = pc.context.points.p[gl_InstanceIndex].color;
if(gl_InstanceIndex == 0) { gl_PointSize = pc.context.points.p[gl_InstanceIndex].size;
hex_index = pc.context.clicked_hex;
region = pc.context.regions[pc.context.clicked_region]; vec2 region_qr = vec2(region.q, region.r);
vertex_index = pc.context.clicked_vertex;
color = vec4(1, 0, 0, 1); vec4 region_pos = vec4(0, 0, 0, 0);
gl_PointSize = 15; region_pos.x = (region_qr.x+region_qr.y/2)*region_width - region_qr.y*x/2;
raise = 0.01; 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 { } else {
hex_index = pc.context.hovered_hex; gl_Position = vec4(0, 0, 0, 0);
region = pc.context.regions[pc.context.hovered_region]; color = vec4(0, 0, 0, 0);
vertex_index = pc.context.hovered_vertex;
color = vec4(0, 1, 0, 1);
gl_PointSize = 10;
raise = 0.015;
} }
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; layout(location = 0) flat out vec4 color;
void main() { void main() {
if(gl_InstanceIndex == 0) { if(gl_VertexIndex == 0) {
color = vec4(1, 0, 0, 1); gl_Position = pc.context.proj * pc.context.view * pc.context.rays.r[gl_InstanceIndex].start;
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;
}
} else { } else {
color = vec4(0, 1, 0, 1); gl_Position = pc.context.proj * pc.context.view * pc.context.rays.r[gl_InstanceIndex].end;
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;
}
} }
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); vkCmdDraw(command_buffer, 18, REGION_HEX_COUNT*MAX_LOADED_REGIONS, 0, 0);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, hex->point_pipeline.pipeline); 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); 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); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, hex->ray_pipeline.pipeline);
vkCmdDraw(command_buffer, 2, 2, 0, 0); vkCmdDraw(command_buffer, 2, 2, 0, 0);
#endif
} }
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) { void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) {

@ -11,9 +11,9 @@
typedef struct EditorDataStruct { typedef struct EditorDataStruct {
uint32_t selected_region; uint32_t selected_region;
uint32_t last_clicked_region; uint32_t clicked_region;
uint32_t last_clicked_hex; uint32_t clicked_hex;
uint32_t last_clicked_vertex; uint32_t clicked_vertex;
double current_hsv[3]; double current_hsv[3];
vec4 current; vec4 current;
@ -862,10 +862,8 @@ VkResult update_region_info_ui(ClientContext* context) {
char temp[20]; char temp[20];
VkResult result; VkResult result;
EditorData* data = context->app_data; EditorData* data = context->app_data;
HexRegion* selected_region = context->hex.regions[data->selected_region];
if(data->selected_region >= MAX_LOADED_REGIONS) {
if(selected_region == NULL) {
snprintf(temp, snprintf(temp,
sizeof(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)); VK_RESULT(update_ui_string(temp, 0x01, 0, 3, &context->ui, &context->render));
} else { } else {
HexRegion* selected_region = context->hex.regions[data->selected_region];
snprintf(temp, snprintf(temp,
sizeof(temp), sizeof(temp),
"Region %4d", data->selected_region); "Region %4d", data->selected_region);
@ -919,10 +918,10 @@ VkResult update_region_info_ui(ClientContext* context) {
VkResult update_hex_info_ui(ClientContext* context) { VkResult update_hex_info_ui(ClientContext* context) {
char temp[20]; char temp[20];
VkResult result; 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( snprintf(
temp, temp,
sizeof(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)); VK_RESULT(update_ui_string(temp, 0x02, 0, 7, &context->ui, &context->render));
} else { } 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, snprintf(temp,
sizeof(temp), sizeof(temp),
"%d-%d", "%d-%d",
context->hex.data.clicked_region, data->clicked_region,
context->hex.data.clicked_hex); data->clicked_hex);
VK_RESULT(update_ui_string(temp, 0x02, 0, 0, &context->ui, &context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 0, &context->ui, &context->render));
HexCoord hex_world; 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_coord = {region->data.position.q, region->data.position.r};
HexCoord region_world; HexCoord region_world;
region_qr(region_coord, &region_world); region_qr(region_coord, &region_world);
@ -994,7 +995,7 @@ VkResult update_hex_info_ui(ClientContext* context) {
hex_world.q, hex_world.q,
hex_world.r, hex_world.r,
region->data.y, region->data.y,
context->hex.data.clicked_vertex); data->clicked_vertex);
VK_RESULT(update_ui_string(temp, 0x02, 0, 1, &context->ui, &context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 1, &context->ui, &context->render));
snprintf( snprintf(
@ -1059,21 +1060,23 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
break; break;
case GLFW_KEY_MINUS: case GLFW_KEY_MINUS:
free_hex_region(data->selected_region, &context->hex, &context->render); if(data->selected_region < MAX_LOADED_REGIONS) {
start = data->selected_region; free_hex_region(data->selected_region, &context->hex, &context->render);
next_region = start; start = data->selected_region;
do { next_region = start;
next_region -= 1; do {
if(next_region > MAX_LOADED_REGIONS) next_region = MAX_LOADED_REGIONS; next_region -= 1;
if(next_region != MAX_LOADED_REGIONS && context->hex.regions[next_region] != NULL) break; if(next_region > MAX_LOADED_REGIONS) next_region = MAX_LOADED_REGIONS;
} while(next_region != start); if(next_region != MAX_LOADED_REGIONS && context->hex.regions[next_region] != NULL) break;
if(next_region == start) { } while(next_region != start);
data->selected_region = MAX_LOADED_REGIONS; if(next_region == start) {
} else { data->selected_region = MAX_LOADED_REGIONS;
data->selected_region = next_region; } 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; break;
case GLFW_KEY_LEFT_BRACKET: case GLFW_KEY_LEFT_BRACKET:
@ -1101,7 +1104,7 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
break; break;
case GLFW_KEY_I: 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; context->hex.regions[data->selected_region]->data.position.q += 1;
add_transfer( add_transfer(
&context->hex.regions[data->selected_region]->data.position, &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); update_region_info_ui(context);
break; break;
case GLFW_KEY_K: 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; context->hex.regions[data->selected_region]->data.position.q -= 1;
add_transfer( add_transfer(
&context->hex.regions[data->selected_region]->data.position.q, &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); update_region_info_ui(context);
break; break;
case GLFW_KEY_J: 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; context->hex.regions[data->selected_region]->data.position.r += 1;
add_transfer( add_transfer(
&context->hex.regions[data->selected_region]->data.position.r, &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); update_region_info_ui(context);
break; break;
case GLFW_KEY_L: 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; context->hex.regions[data->selected_region]->data.position.r -= 1;
add_transfer( add_transfer(
&context->hex.regions[data->selected_region]->data.position.r, &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); update_region_info_ui(context);
break; break;
case GLFW_KEY_O: 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; context->hex.regions[data->selected_region]->data.y += 1;
add_transfer( add_transfer(
&context->hex.regions[data->selected_region]->data.y, &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); update_region_info_ui(context);
break; break;
case GLFW_KEY_U: 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; context->hex.regions[data->selected_region]->data.y -= 1;
add_transfer( add_transfer(
&context->hex.regions[data->selected_region]->data.y, &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; break;
case GLFW_KEY_Y: case GLFW_KEY_Y:
region = context->hex.regions[context->hex.data.clicked_region]; if(data->clicked_region < MAX_LOADED_REGIONS && data->clicked_vertex != 0) {
if(region != NULL && context->hex.data.clicked_vertex != 0) { region = context->hex.regions[data->clicked_region];
float height = region->data.hexes[context->hex.data.clicked_hex].height[context->hex.data.clicked_vertex-1] + 0.1; float height = region->data.hexes[data->clicked_hex].height[data->clicked_vertex-1] + 0.1;
if(~mods & GLFW_MOD_CONTROL) { if(~mods & GLFW_MOD_CONTROL) {
uint32_t n_vertex[2], n_hex[2]; 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; HexCoord world, region_center;
region_qr(region->data.position, &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_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; uint32_t n0, n1;
first_matching_region(n_region[0], region->data.y, &n0, &context->hex); 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(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); 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); update_hex_info_ui(context);
} }
break; break;
case GLFW_KEY_H: case GLFW_KEY_H:
region = context->hex.regions[context->hex.data.clicked_region]; if(data->clicked_region < MAX_LOADED_REGIONS && data->clicked_vertex != 0) {
if(region != NULL && context->hex.data.clicked_vertex != 0) { region = context->hex.regions[data->clicked_region];
float height = region->data.hexes[context->hex.data.clicked_hex].height[context->hex.data.clicked_vertex-1] - 0.1; float height = region->data.hexes[data->clicked_hex].height[data->clicked_vertex-1] - 0.1;
if(~mods & GLFW_MOD_CONTROL) { if(~mods & GLFW_MOD_CONTROL) {
uint32_t n_vertex[2], n_hex[2]; 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; HexCoord world, region_center;
region_qr(region->data.position, &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_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; uint32_t n0, n1;
first_matching_region(n_region[0], region->data.y, &n0, &context->hex); 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(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); 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); update_hex_info_ui(context);
} }
break; break;
case GLFW_KEY_E: case GLFW_KEY_E:
region = context->hex.regions[context->hex.data.clicked_region]; if(data->clicked_region < MAX_LOADED_REGIONS) {
if(region != NULL) { region = context->hex.regions[data->clicked_region];
uint32_t n_vertex[2], n_hex[2]; uint32_t n_vertex[2], n_hex[2];
HexCoord n_region[2]; HexCoord n_region[2];
HexCoord world, region_center; 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); 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_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; uint32_t n0, n1;
first_matching_region(n_region[0], region->data.y, &n0, &context->hex); 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(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); 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); update_hex_info_ui(context);
} }
break; break;
@ -1262,18 +1265,6 @@ bool editor_key_callback(ClientContext* context, int key, int action, int mods)
return false; 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) { void editor_startup(ClientContext* context) {
region_info_ui(context); region_info_ui(context);
hex_info_ui(context); hex_info_ui(context);
@ -1284,7 +1275,9 @@ 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_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(button == GLFW_MOUSE_BUTTON_MIDDLE) {
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
@ -289,8 +288,6 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
break; break;
} }
} }
} else {
update_hex_hover(context->ui.cursor, &context->hex, &context->render);
} }
} }
} }

@ -705,9 +705,7 @@ VkResult create_hex_context(
VkResult result; VkResult result;
VK_RESULT(create_hex_pipeline(gpu, &context->graphics)); VK_RESULT(create_hex_pipeline(gpu, &context->graphics));
#ifdef DRAW_HEX_RAYS
VK_RESULT(create_ray_pipeline(gpu, &context->ray_pipeline)); VK_RESULT(create_ray_pipeline(gpu, &context->ray_pipeline));
#endif
VK_RESULT(create_hex_highlight_pipeline(gpu, &context->highlight_pipeline)); VK_RESULT(create_hex_highlight_pipeline(gpu, &context->highlight_pipeline));
VK_RESULT(create_point_pipeline(gpu, &context->point_pipeline)); VK_RESULT(create_point_pipeline(gpu, &context->point_pipeline));
@ -727,7 +725,48 @@ VkResult create_hex_context(
&context->context[i], &context->context[i],
&context->context_memory[i])); &context->context_memory[i]));
context->address[i] = buffer_address(gpu->device, context->context[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( VK_RESULT(add_transfers(
&context->data, &context->data,
context->context, context->context,
@ -735,6 +774,37 @@ VkResult create_hex_context(
sizeof(GPUHexContext), sizeof(GPUHexContext),
gpu)); 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; 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); 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) { void hex_qr(uint32_t hex, HexCoord* world) {
float radius = 0; float radius = 0;
float ring = 0; float ring = 0;