From bcbb21bbfe24ad0dc9fe5380cb1c5564c88e164e Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Sat, 2 Nov 2024 12:07:11 -0600 Subject: [PATCH] Draw all hex regions in one draw call --- client/include/hex.h | 10 ++--- client/shader/hex.vert | 84 +++++++++++++++++++++-------------- client/shader/hex_common.glsl | 4 +- client/src/draw.c | 2 +- client/src/hex.c | 2 +- client/src/main.c | 63 ++++++++++++++++++++++---- 6 files changed, 114 insertions(+), 51 deletions(-) diff --git a/client/include/hex.h b/client/include/hex.h index a455854..971f688 100644 --- a/client/include/hex.h +++ b/client/include/hex.h @@ -13,15 +13,15 @@ typedef struct GPUHexStruct { } GPUHex; typedef struct GPUHexRegionStruct { - uint32_t q; - uint32_t r; + int32_t q; + int32_t r; GPUHex hexes[REGION_HEX_COUNT]; } GPUHexRegion; typedef struct HexRegionStruct { - uint32_t q; - uint32_t r; + int32_t q; + int32_t r; VkDeviceAddress address; VkBuffer region; @@ -58,7 +58,7 @@ VkResult create_hex_context( HexContext* context); VkResult create_hex_region( - uint32_t q, uint32_t s, + int32_t q, int32_t r, HexRegion** region, HexContext* hex, RenderContext* gpu); diff --git a/client/shader/hex.vert b/client/shader/hex.vert index 62d323a..d2389a5 100644 --- a/client/shader/hex.vert +++ b/client/shader/hex.vert @@ -6,7 +6,7 @@ #define PI 3.1415926535897932384626433832795 const float w = 0.5; const float x = 0.75; -const float z = sqrt(3.0)/4.0; +const float z = sqrt(3.0)/2.0; const vec4 vertices[] = { vec4(0, 0, 0, 1), @@ -28,21 +28,21 @@ const uint indices[] = { }; const vec4 starts[] = { - vec4( 0, 0, 2*z, 0), - vec4(-x, 0, z, 0), - vec4(-x, 0, -z, 0), - vec4( 0, 0, -2*z, 0), - vec4( x, 0, -z, 0), - vec4( x, 0, z, 0), + vec4( 0, 0, z, 0), + vec4(-x, 0, z/2, 0), + vec4(-x, 0, -z/2, 0), + vec4( 0, 0, -z, 0), + vec4( x, 0, -z/2, 0), + vec4( x, 0, z/2, 0), }; const vec4 direction[] = { - vec4(-x, 0, -z, 0), - vec4( 0, 0, -2*z, 0), - vec4( x, 0, -z, 0), - vec4( x, 0, z, 0), - vec4( 0, 0, 2*z, 0), - vec4(-x, 0, z, 0), + vec4(-x, 0, -z/2, 0), + vec4( 0, 0, -z, 0), + vec4( x, 0, -z/2, 0), + vec4( x, 0, z/2, 0), + vec4( 0, 0, z, 0), + vec4(-x, 0, z/2, 0), }; layout(location=0) out vec4 color; @@ -55,38 +55,56 @@ vec4 int2color(uint color_int) { return vec4(r, g, b, a); } +const uint region_size = 6; +const uint region_hex_count = 3*region_size*(region_size-1)+1; + void main() { - Region region = pc.context.regions[pc.region]; + uint region_index = uint(floor(gl_InstanceIndex/region_hex_count)); + uint hex_index = gl_InstanceIndex - (region_index*region_hex_count); + Region region = pc.context.regions[region_index]; + + float q = region.q; + float r = region.r; + + float z_off = 0; + if(r != 0) { + z_off = r/2; + } + float x_off = 0; + if((q+r) != 0) { + x_off = (q+r)/2; + } + vec4 region_offset = vec4(x*(x_off + 2*(r+(-q-r)/2)*(region_size-0.5)), 0, z*(z_off + 2*(-q-r)*(region_size-1.75)), 0); uint radius = 0; uint ring = 0; uint side = 0; uint hex = 0; - if(gl_InstanceIndex != 0) { - radius = uint(floor(0.5 + sqrt(12*gl_InstanceIndex-3)/6)); - ring = gl_InstanceIndex - (3*radius*radius - 3*radius + 1); + if(hex_index != 0) { + radius = uint(floor(0.5 + sqrt(12*hex_index-3)/6)); + ring = hex_index - (3*radius*radius - 3*radius + 1); side = uint(floor(ring/(radius))); hex = ring - (radius*side); } - - vec4 position = vertices[indices[gl_VertexIndex]] + (starts[side]*radius) + (direction[side]*hex); + + vec4 position = vertices[indices[gl_VertexIndex]] + (starts[side]*radius) + (direction[side]*hex) + region_offset; if(gl_VertexIndex % 3 == 0) { - position.y = (region.hexes[gl_InstanceIndex].heights[0] + - region.hexes[gl_InstanceIndex].heights[1] + - region.hexes[gl_InstanceIndex].heights[2] + - region.hexes[gl_InstanceIndex].heights[3] + - region.hexes[gl_InstanceIndex].heights[4] + - region.hexes[gl_InstanceIndex].heights[5])/6; + 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; - color = (int2color(region.hexes[gl_InstanceIndex].colors[0]) + - int2color(region.hexes[gl_InstanceIndex].colors[1]) + - int2color(region.hexes[gl_InstanceIndex].colors[2]) + - int2color(region.hexes[gl_InstanceIndex].colors[3]) + - int2color(region.hexes[gl_InstanceIndex].colors[4]) + - int2color(region.hexes[gl_InstanceIndex].colors[5]))/6; + color = (int2color(region.hexes[hex_index].colors[0]) + + int2color(region.hexes[hex_index].colors[1]) + + int2color(region.hexes[hex_index].colors[2]) + + int2color(region.hexes[hex_index].colors[3]) + + int2color(region.hexes[hex_index].colors[4]) + + int2color(region.hexes[hex_index].colors[5]))/6; } else { - position.y = region.hexes[gl_InstanceIndex].heights[indices[gl_VertexIndex]-1]; - color = int2color(region.hexes[gl_InstanceIndex].colors[indices[gl_VertexIndex]-1]); + position.y = region.hexes[hex_index].heights[indices[gl_VertexIndex]-1]; + color = int2color(region.hexes[hex_index].colors[indices[gl_VertexIndex]-1]); } gl_Position = pc.context.proj * pc.context.view * position; diff --git a/client/shader/hex_common.glsl b/client/shader/hex_common.glsl index 7688fdc..3caecc5 100644 --- a/client/shader/hex_common.glsl +++ b/client/shader/hex_common.glsl @@ -4,8 +4,8 @@ struct Hex { }; layout(std430, buffer_reference) readonly buffer Region { - uint q; - uint r; + int q; + int r; Hex hexes[]; }; diff --git a/client/src/draw.c b/client/src/draw.c index 8eb99ce..2b6be25 100644 --- a/client/src/draw.c +++ b/client/src/draw.c @@ -30,7 +30,7 @@ void record_hex_draw(VkCommandBuffer command_buffer, HexContext* hex, double tim }; vkCmdPushConstants(command_buffer, hex->graphics.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(HexPushConstant), &push); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, hex->graphics.pipeline); - vkCmdDraw(command_buffer, 18, REGION_HEX_COUNT, 0, 0); + vkCmdDraw(command_buffer, 18, REGION_HEX_COUNT*100, 0, 0); } void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) { diff --git a/client/src/hex.c b/client/src/hex.c index e44a57c..55df9c9 100644 --- a/client/src/hex.c +++ b/client/src/hex.c @@ -211,7 +211,7 @@ VkResult create_hex_context( return VK_SUCCESS; } -VkResult create_hex_region(uint32_t q, uint32_t r, HexRegion** region, HexContext* hex, RenderContext* gpu) { +VkResult create_hex_region(int32_t q, int32_t r, HexRegion** region, HexContext* hex, RenderContext* gpu) { VkResult result; uint32_t i = 0; diff --git a/client/src/main.c b/client/src/main.c index 55ad519..7ed1dd2 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -122,18 +122,63 @@ VkResult main_thread(ClientContext* context) { 4*sizeof(uint32_t), &context->render)); - HexRegion* region; - VK_RESULT(create_hex_region(0, 0, ®ion, &context->hex, &context->render)); + HexRegion* regions[19]; + uint32_t colors[] = { + 0xFF0000FF, + 0x00FF00FF, + 0x00FF00FF, + 0x00FF00FF, + 0x00FF00FF, + 0x00FF00FF, + 0x00FF00FF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + 0x0000FFFF, + }; + + VK_RESULT(create_hex_region( 0, 0, ®ions[0], &context->hex, &context->render)); + + VK_RESULT(create_hex_region( 1, -1, ®ions[1], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 1, 0, ®ions[2], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 0, 1, ®ions[3], &context->hex, &context->render)); + VK_RESULT(create_hex_region(-1, 1, ®ions[4], &context->hex, &context->render)); + VK_RESULT(create_hex_region(-1, 0, ®ions[5], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 0, -1, ®ions[6], &context->hex, &context->render)); + + VK_RESULT(create_hex_region( 0, -2, ®ions[7], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 1, -2, ®ions[8], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 2, -2, ®ions[9], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 2, -1, ®ions[10], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 2, 0, ®ions[11], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 1, 1, ®ions[12], &context->hex, &context->render)); + VK_RESULT(create_hex_region( 0, 2, ®ions[13], &context->hex, &context->render)); + VK_RESULT(create_hex_region(-1, 2, ®ions[14], &context->hex, &context->render)); + VK_RESULT(create_hex_region(-2, 2, ®ions[15], &context->hex, &context->render)); + VK_RESULT(create_hex_region(-2, 1, ®ions[16], &context->hex, &context->render)); + VK_RESULT(create_hex_region(-2, 0, ®ions[17], &context->hex, &context->render)); + VK_RESULT(create_hex_region(-1, -1, ®ions[18], &context->hex, &context->render)); GPUHex* temp_hexes = malloc(sizeof(GPUHex)*REGION_HEX_COUNT); - uint32_t colors[] = {0xFF0000FF, 0x00FF00FF, 0x0000FFFF}; - for(uint32_t i = 0; i < REGION_HEX_COUNT; i++) { - for(uint32_t h = 0; h < 6; h++) { - temp_hexes[i].color[h] = colors[i%3]; - temp_hexes[i].height[h] = 0; + for(uint32_t r = 0; r < sizeof(regions)/sizeof(HexRegion*); r++) { + for(uint32_t i = 0; i < REGION_HEX_COUNT; i++) { + for(uint32_t h = 0; h < 6; h++) { + temp_hexes[i].color[h] = colors[r % (sizeof(colors)/sizeof(uint32_t))]; + temp_hexes[i].height[h] = 0; + } } + VK_RESULT(add_transfer(temp_hexes, regions[r]->region, offsetof(GPUHexRegion, hexes), sizeof(GPUHex)*REGION_HEX_COUNT, 0, &context->render)); } - VK_RESULT(add_transfer(temp_hexes, region->region, offsetof(GPUHexRegion, hexes), sizeof(GPUHex)*REGION_HEX_COUNT, 0, &context->render)); + + free(temp_hexes); context->position[0] = 0; @@ -204,7 +249,7 @@ VkResult main_thread(ClientContext* context) { camera[1] = context->position[1] + context->distance*sin(context->rotation[1]); camera[2] = context->position[2] + context->distance*cos(context->rotation[1])*sin(context->rotation[0]); glm_lookat(camera, context->position, up, context->hex.data.view); - add_transfer(&context->hex.data, context->hex.context, 0, 2*sizeof(mat4), 0, &context->render); + add_transfer(&context->hex.data, context->hex.context, 0, 2*sizeof(mat4), context->render.current_frame, &context->render); } if(context->clicked_container != 0) {