Hex world coordinate calculation

main
noah metz 2024-11-02 22:02:32 -06:00
parent bcbb21bbfe
commit 0685c2ad3b
6 changed files with 102 additions and 79 deletions

@ -3,13 +3,13 @@
#include "gpu.h"
#define REGION_SIZE 6
#define REGION_SIZE 7
#define REGION_HEX_COUNT (3*REGION_SIZE*(REGION_SIZE-1)+1)
#define MAX_LOADED_REGIONS 100
#define MAX_LOADED_REGIONS 11*11
typedef struct GPUHexStruct {
float height[6];
uint32_t color[6];
uint32_t color[7];
} GPUHex;
typedef struct GPUHexRegionStruct {
@ -31,6 +31,8 @@ typedef struct HexRegionStruct {
typedef struct GPUHexContextStruct {
mat4 proj;
mat4 view;
vec2 camera;
vec2 forward;
VkDeviceAddress regions[MAX_LOADED_REGIONS];
} GPUHexContext;

@ -28,12 +28,21 @@ const uint indices[] = {
};
const vec4 starts[] = {
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),
vec4( 0, 0, z, 0), // 0, -1
vec4(-x, 0, z/2, 0), // -1, 0
vec4(-x, 0, -z/2, 0), // -1, +1
vec4( 0, 0, -z, 0), // 0, +1
vec4( x, 0, -z/2, 0), // +1, 0
vec4( x, 0, z/2, 0), // +1, -1
};
const vec2 start_coords[] = {
vec2(0, -1),
vec2(-1, 0),
vec2(-1, 1),
vec2(0, 1),
vec2(1, 0),
vec2(1, -1),
};
const vec4 direction[] = {
@ -45,36 +54,39 @@ const vec4 direction[] = {
vec4(-x, 0, z/2, 0),
};
const vec2 direction_coords[] = {
vec2(-1, 1),
vec2(0, 1),
vec2(1, 0),
vec2(1, -1),
vec2(0, -1),
vec2(-1, 0),
};
layout(location=0) out vec4 color;
vec4 int2color(uint color_int) {
float r = float((color_int >> 24) & 0xFF)/255.0;
float g = float((color_int >> 16) & 0xFF)/255.0;
float b = float((color_int >> 8) & 0xFF)/255.0;
float a = float((color_int >> 0) & 0xFF)/255.0;
return vec4(r, g, b, a);
float r = float((color_int >> 24) & 0xFF);
float g = float((color_int >> 16) & 0xFF);
float b = float((color_int >> 8) & 0xFF);
float a = float((color_int >> 0) & 0xFF);
return vec4(r, g, b, a)/255.0;
}
const uint region_size = 6;
const uint region_size = 7;
const float region_width = x*(2*region_size-1);
const float region_height = z*(2*region_size-1);
const uint region_hex_count = 3*region_size*(region_size-1)+1;
void main() {
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];
uint hex_index = gl_InstanceIndex - ((gl_InstanceIndex/region_hex_count)*region_hex_count);
Region region = pc.context.regions[gl_InstanceIndex/region_hex_count];
float q = region.q;
float r = region.r;
vec2 region_qr = vec2(region.q, 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);
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;
uint radius = 0;
uint ring = 0;
@ -87,7 +99,7 @@ void main() {
hex = ring - (radius*side);
}
vec4 position = vertices[indices[gl_VertexIndex]] + (starts[side]*radius) + (direction[side]*hex) + region_offset;
vec4 position = vertices[indices[gl_VertexIndex]] + (starts[side]*radius) + (direction[side]*hex) + region_pos;
if(gl_VertexIndex % 3 == 0) {
position.y = (region.hexes[hex_index].heights[0] +
region.hexes[hex_index].heights[1] +
@ -95,17 +107,32 @@ void main() {
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[hex_index].heights[indices[gl_VertexIndex]-1];
color = int2color(region.hexes[hex_index].colors[indices[gl_VertexIndex]-1]);
}
color = int2color(region.hexes[hex_index].colors[indices[gl_VertexIndex]]);
vec2 hex_qr = start_coords[side]*radius + direction_coords[side]*hex;
/*
vec4 hex_pos = vec4(0, 0, 0, 1);
hex_pos.x = x*hex_qr.x;
hex_pos.z = -z*hex_qr.y - z*hex_qr.x/2;
vec4 world_pos = vec4(0, 0, 0, 1);
world_pos.x = hex_pos.x + region_pos.x;
world_pos.z = hex_pos.z + region_pos.z;
vec2 world_qr = vec2(0, 0);
world_qr.x = world_pos.x/x;
world_qr.y = -world_pos.z/z - world_pos.x/(2*x);
*/
vec2 world_qr;
world_qr.x = (x*hex_qr.x + (region_qr.x+region_qr.y/2)*region_width - region_qr.y*x/2)/x;
world_qr.y = -(-z*hex_qr.y - z*hex_qr.x/2 + 0.75*region_qr.y*region_height + 0.25*region_qr.y*z + 0.5*region_qr.x*z)/z - (x*hex_qr.x + (region_qr.x+region_qr.y/2)*region_width - region_qr.y*x/2)/(2*x);
color = vec4(world_qr/region_size, 0.0, 1.0);
gl_Position = pc.context.proj * pc.context.view * position;
}

@ -1,6 +1,6 @@
struct Hex {
float heights[6];
uint colors[6];
uint colors[7];
};
layout(std430, buffer_reference) readonly buffer Region {
@ -12,6 +12,8 @@ layout(std430, buffer_reference) readonly buffer Region {
layout(std430, buffer_reference) readonly buffer HexContext {
mat4 proj;
mat4 view;
vec2 camera;
vec2 forward;
Region regions[];
};

@ -1,4 +1,5 @@
#include "draw.h"
#include "hex.h"
#include "vulkan/vulkan_core.h"
void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context, double time, uint32_t frame) {
@ -30,7 +31,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*100, 0, 0);
vkCmdDraw(command_buffer, 18, REGION_HEX_COUNT*MAX_LOADED_REGIONS, 0, 0);
}
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) {

@ -1,6 +1,7 @@
#include "hex.h"
#include "gpu.h"
#include "vulkan/vulkan_core.h"
#include <math.h>
VkResult create_hex_context(
RenderContext* gpu,
@ -123,10 +124,6 @@ VkResult create_hex_context(
.lineWidth = 1.0f,
.cullMode = VK_CULL_MODE_BACK_BIT,
.frontFace = VK_FRONT_FACE_CLOCKWISE,
.depthBiasEnable = VK_FALSE,
.depthBiasConstantFactor = 0.0f,
.depthBiasClamp = 0.0f,
.depthBiasSlopeFactor = 0.0f,
};
VkPipelineColorBlendAttachmentState blend_attachments = {
@ -197,7 +194,7 @@ VkResult create_hex_context(
VK_RESULT(vkCreateGraphicsPipelines(gpu->device, VK_NULL_HANDLE, 1, &graphics_pipeline_info, NULL, &context->graphics.pipeline));
glm_perspective(30.0, (float)gpu->swapchain_extent.width/(float)gpu->swapchain_extent.height, 0.01, 99.9, context->data.proj);
glm_perspective(-M_PI*1/8, (float)gpu->swapchain_extent.width/(float)gpu->swapchain_extent.height, 0.01, 1000, context->data.proj);
glm_mat4_identity(context->data.view);
VK_RESULT(create_storage_buffer(
gpu->allocator,

@ -122,7 +122,7 @@ VkResult main_thread(ClientContext* context) {
4*sizeof(uint32_t),
&context->render));
HexRegion* regions[19];
HexRegion* regions[MAX_LOADED_REGIONS];
uint32_t colors[] = {
0xFF0000FF,
0x00FF00FF,
@ -145,37 +145,21 @@ VkResult main_thread(ClientContext* context) {
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);
for(uint32_t r = 0; r < sizeof(regions)/sizeof(HexRegion*); r++) {
uint32_t region = 0;
for(int32_t q = -5; q < 5; q++) {
for(int32_t r = -5; r < 5; r++) {
VK_RESULT(create_hex_region(q, r, &regions[region], &context->hex, &context->render));
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;
}
temp_hexes[i].color[6] = colors[r % (sizeof(colors)/sizeof(uint32_t))];
}
VK_RESULT(add_transfer(temp_hexes, regions[region]->region, offsetof(GPUHexRegion, hexes), sizeof(GPUHex)*REGION_HEX_COUNT, 0, &context->render));
region++;
}
VK_RESULT(add_transfer(temp_hexes, regions[r]->region, offsetof(GPUHexRegion, hexes), sizeof(GPUHex)*REGION_HEX_COUNT, 0, &context->render));
}
@ -186,7 +170,7 @@ VkResult main_thread(ClientContext* context) {
context->position[2] = 0;
context->rotation[0] = 3*M_PI/2;
context->rotation[1] = 0;
context->rotation[1] = M_PI/4;
context->cur_spin[0] = 0;
context->cur_spin[1] = 0;
@ -194,7 +178,7 @@ VkResult main_thread(ClientContext* context) {
context->key_spin[1] = 0;
context->cur_spin[0] = 0;
context->cur_spin[1] = 0;
context->distance = 10;
context->distance = 50;
context->zoom = 0;
context->camera_mode = false;
context->key_spin_speed = 1.0;
@ -206,7 +190,7 @@ VkResult main_thread(ClientContext* context) {
GPUString* mapped_string = context->ui.containers[0].layers[0].strings_buffer;
char str[21];
double last_frame_time = glfwGetTime();
double last_frame_time = 0;
while(glfwWindowShouldClose(context->window) == 0) {
double frame_time = glfwGetTime();
double delta_time = (frame_time - last_frame_time);
@ -221,7 +205,8 @@ VkResult main_thread(ClientContext* context) {
if(context->key_spin[0] != 0 || context->key_spin[1] != 0 ||
context->zoom != 0 ||
context->cur_spin[0] != 0 || context->cur_spin[1] != 0) {
context->cur_spin[0] != 0 || context->cur_spin[1] != 0 ||
last_frame_time == 0) {
context->rotation[0] += (float)context->key_spin[0]*delta_time*context->key_spin_speed;
context->rotation[0] += (float)context->cur_spin[0]*delta_time*context->cur_spin_speed;
@ -244,12 +229,21 @@ VkResult main_thread(ClientContext* context) {
context->distance = 1;
}
vec3 camera;
vec3 camera = {};
camera[0] = context->position[0] + context->distance*cos(context->rotation[1])*cos(context->rotation[0]);
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]);
vec2 hex_pos = {};
vec2 hex_forward = {};
hex_pos[0] = camera[0];
hex_pos[1] = camera[2] - camera[0]/2;
glm_lookat(camera, context->position, up, context->hex.data.view);
add_transfer(&context->hex.data, context->hex.context, 0, 2*sizeof(mat4), context->render.current_frame, &context->render);
add_transfer(hex_pos, context->hex.context, offsetof(GPUHexContext, camera), sizeof(vec2), context->render.current_frame, &context->render);
add_transfer(hex_forward, context->hex.context, offsetof(GPUHexContext, forward), sizeof(vec2), context->render.current_frame, &context->render);
}
if(context->clicked_container != 0) {