Draw all hex regions in one draw call

main
noah metz 2024-11-02 12:07:11 -06:00
parent 74cccfe065
commit bcbb21bbfe
6 changed files with 114 additions and 51 deletions

@ -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);

@ -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;
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;
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[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;

@ -4,8 +4,8 @@ struct Hex {
};
layout(std430, buffer_reference) readonly buffer Region {
uint q;
uint r;
int q;
int r;
Hex hexes[];
};

@ -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) {

@ -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;

@ -122,18 +122,63 @@ VkResult main_thread(ClientContext* context) {
4*sizeof(uint32_t),
&context->render));
HexRegion* region;
VK_RESULT(create_hex_region(0, 0, &region, &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, &regions[0], &context->hex, &context->render));
VK_RESULT(create_hex_region( 1, -1, &regions[1], &context->hex, &context->render));
VK_RESULT(create_hex_region( 1, 0, &regions[2], &context->hex, &context->render));
VK_RESULT(create_hex_region( 0, 1, &regions[3], &context->hex, &context->render));
VK_RESULT(create_hex_region(-1, 1, &regions[4], &context->hex, &context->render));
VK_RESULT(create_hex_region(-1, 0, &regions[5], &context->hex, &context->render));
VK_RESULT(create_hex_region( 0, -1, &regions[6], &context->hex, &context->render));
VK_RESULT(create_hex_region( 0, -2, &regions[7], &context->hex, &context->render));
VK_RESULT(create_hex_region( 1, -2, &regions[8], &context->hex, &context->render));
VK_RESULT(create_hex_region( 2, -2, &regions[9], &context->hex, &context->render));
VK_RESULT(create_hex_region( 2, -1, &regions[10], &context->hex, &context->render));
VK_RESULT(create_hex_region( 2, 0, &regions[11], &context->hex, &context->render));
VK_RESULT(create_hex_region( 1, 1, &regions[12], &context->hex, &context->render));
VK_RESULT(create_hex_region( 0, 2, &regions[13], &context->hex, &context->render));
VK_RESULT(create_hex_region(-1, 2, &regions[14], &context->hex, &context->render));
VK_RESULT(create_hex_region(-2, 2, &regions[15], &context->hex, &context->render));
VK_RESULT(create_hex_region(-2, 1, &regions[16], &context->hex, &context->render));
VK_RESULT(create_hex_region(-2, 0, &regions[17], &context->hex, &context->render));
VK_RESULT(create_hex_region(-1, -1, &regions[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) {