Created HexContext, and initial hex region shader

main
noah metz 2024-11-01 15:46:27 -06:00
parent 07b0a46dfc
commit 5b1275ea83
7 changed files with 169 additions and 58 deletions

@ -3,12 +3,12 @@
#include "gpu.h"
#include "ui.h"
#include "hex.h"
VkResult draw_frame(
RenderContext* context,
UIContext* ui,
GraphicsPipeline* hex_graphics,
VkDeviceAddress world,
HexContext* hex,
double time);
#endif

@ -3,20 +3,59 @@
#include "gpu.h"
typedef struct GPUHexContextStruct {
mat4 proj;
mat4 view;
} GPUHexContext;
#define REGION_SIZE 6
#define REGION_HEX_COUNT 3*REGION_SIZE*(REGION_SIZE-1)+1
typedef struct HexPushConstantStruct {
VkDeviceAddress context;
double time;
} HexPushConstant;
VkResult create_hex_pipeline(
VkDevice device,
VkRenderPass render_pass,
GraphicsPipeline* graphics,
ComputePipeline* compute);
typedef struct GPUHexContextStruct {
mat4 proj;
mat4 view;
VkDeviceAddress regions;
} GPUHexContext;
typedef struct HexContextStruct {
VkDeviceAddress address;
VkBuffer context;
VmaAllocation context_memory;
GraphicsPipeline graphics;
ComputePipeline compute;
GPUHexContext data;
} HexContext;
typedef struct GPUHexStruct {
float height[6];
uint32_t color[6];
} GPUHex;
typedef struct GPUHexRegionStruct {
uint32_t x;
uint32_t y;
GPUHex hexes[REGION_HEX_COUNT];
} GPUHexRegion;
typedef struct HexRegionStruct {
uint32_t x;
uint32_t y;
VkDeviceAddress address;
VkBuffer region;
VmaAllocation region_memory;
} HexRegion;
VkResult create_hex_context(
RenderContext* gpu,
HexContext* context);
VkResult create_hex_region(
uint32_t x, uint32_t y,
HexRegion* region,
RenderContext* gpu);
#endif

@ -4,9 +4,11 @@
#include "hex_common.glsl"
#define PI 3.1415926535897932384626433832795
float w = 0.5;
const float w = 0.5;
const float x = 0.75;
const float z = sqrt(3.0)/4.0;
vec4 vertices[] = {
const vec4 vertices[] = {
vec4(0, 0, 0, 1),
vec4(w*cos(0*PI/3), 0, w*sin(0*PI/3), 1),
vec4(w*cos(1*PI/3), 0, w*sin(1*PI/3), 1),
@ -16,7 +18,7 @@ vec4 vertices[] = {
vec4(w*cos(5*PI/3), 0, w*sin(5*PI/3), 1),
};
uint indices[] = {
const uint indices[] = {
0, 2, 1,
0, 3, 2,
0, 4, 3,
@ -25,6 +27,38 @@ uint indices[] = {
0, 1, 6,
};
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),
};
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),
};
void main() {
gl_Position = pc.context.proj * pc.context.view * vertices[indices[gl_VertexIndex]];
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);
side = uint(floor(ring/(radius)));
hex = ring - (radius*side);
}
// Calculate position based on radius/ring/side/hex
vec4 position = vertices[indices[gl_VertexIndex]] + (starts[side]*radius) + (direction[side]*hex);
gl_Position = pc.context.proj * pc.context.view * position;
}

@ -1,6 +1,26 @@
struct Hex {
float heights[6];
uint colors[6];
};
layout(std430, buffer_reference) readonly buffer HexList {
Hex h[];
};
struct Region {
uint x;
uint y;
HexList hexes;
};
layout(std430, buffer_reference) readonly buffer RegionList {
Region r[];
};
layout(std430, buffer_reference) readonly buffer HexContext {
mat4 proj;
mat4 view;
RegionList regions;
};
layout(std430, push_constant) uniform PushConstant {

@ -1,6 +1,4 @@
#include "draw.h"
#include "gpu.h"
#include "hex.h"
#include "vulkan/vulkan_core.h"
void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context, double time, uint32_t frame) {
@ -24,14 +22,14 @@ void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context, doubl
}
}
void record_hex_draw(VkCommandBuffer command_buffer, GraphicsPipeline* graphics, VkDeviceAddress context, double time) {
void record_hex_draw(VkCommandBuffer command_buffer, HexContext* hex, double time, uint32_t frame) {
HexPushConstant push = {
.context = context,
.context = hex->address,
.time = time,
};
vkCmdPushConstants(command_buffer, graphics->layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(HexPushConstant), &push);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics->pipeline);
vkCmdDraw(command_buffer, 18, 1, 0, 0);
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);
}
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) {
@ -65,8 +63,7 @@ void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t f
VkResult draw_frame(
RenderContext* context,
UIContext* ui,
GraphicsPipeline* hex_graphics,
VkDeviceAddress hex_context,
HexContext* hex,
double time) {
VkResult result;
@ -186,7 +183,7 @@ VkResult draw_frame(
};
vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
record_hex_draw(command_buffer, hex_graphics, hex_context, time);
record_hex_draw(command_buffer, hex, time, context->current_frame);
vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE);
record_ui_draw(command_buffer, ui, time, context->current_frame);
vkCmdEndRenderPass(command_buffer);

@ -2,16 +2,14 @@
#include "gpu.h"
#include "vulkan/vulkan_core.h"
VkResult create_hex_pipeline(
VkDevice device,
VkRenderPass render_pass,
GraphicsPipeline* graphics,
ComputePipeline* compute) {
VkResult create_hex_context(
RenderContext* gpu,
HexContext* context) {
VkResult result;
// Compute Pipeline
VkShaderModule compute_shader = load_shader_file("shader/hex.comp.spv", device);
VkShaderModule compute_shader = load_shader_file("shader/hex.comp.spv", gpu->device);
if(compute_shader == VK_NULL_HANDLE) {
return VK_ERROR_UNKNOWN;
}
@ -35,20 +33,20 @@ VkResult create_hex_pipeline(
.pushConstantRangeCount = 1,
};
VK_RESULT(vkCreatePipelineLayout(device, &compute_layout_info, NULL, &compute->layout));
VK_RESULT(vkCreatePipelineLayout(gpu->device, &compute_layout_info, NULL, &context->compute.layout));
VkComputePipelineCreateInfo compute_pipeline_info = {
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.stage = compute_shader_stage,
.layout = compute->layout,
.layout = context->compute.layout,
};
VK_RESULT(vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &compute_pipeline_info, NULL, &compute->pipeline));
VK_RESULT(vkCreateComputePipelines(gpu->device, VK_NULL_HANDLE, 1, &compute_pipeline_info, NULL, &context->compute.pipeline));
// Graphics Pipeline
VkShaderModule vert_shader = load_shader_file("shader/hex.vert.spv", device);
VkShaderModule frag_shader = load_shader_file("shader/hex.frag.spv", device);
VkShaderModule vert_shader = load_shader_file("shader/hex.vert.spv", gpu->device);
VkShaderModule frag_shader = load_shader_file("shader/hex.frag.spv", gpu->device);
VkPipelineShaderStageCreateInfo graphics_stages[] = {
{
@ -77,7 +75,7 @@ VkResult create_hex_pipeline(
.pushConstantRangeCount = 1,
};
VK_RESULT(vkCreatePipelineLayout(device, &graphics_layout_info, NULL, &graphics->layout));
VK_RESULT(vkCreatePipelineLayout(gpu->device, &graphics_layout_info, NULL, &context->graphics.layout));
VkPipelineVertexInputStateCreateInfo vertex_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
@ -180,7 +178,7 @@ VkResult create_hex_pipeline(
VkGraphicsPipelineCreateInfo graphics_pipeline_info = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.layout = graphics->layout,
.layout = context->graphics.layout,
.stageCount = sizeof(graphics_stages)/sizeof(VkPipelineShaderStageCreateInfo),
.pStages = graphics_stages,
.pVertexInputState = &vertex_info,
@ -191,13 +189,42 @@ VkResult create_hex_pipeline(
.pDynamicState = &dynamic_info,
.pMultisampleState = &multisample_info,
.pDepthStencilState = &depth_info,
.renderPass = render_pass,
.renderPass = gpu->render_pass,
.subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = -1,
};
VK_RESULT(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphics_pipeline_info, NULL, &graphics->pipeline));
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_mat4_identity(context->data.view);
VK_RESULT(create_storage_buffer(
gpu->allocator,
0,
sizeof(GPUHexContext),
&context->context,
&context->context_memory));
context->address = buffer_address(gpu->device, context->context);
VK_RESULT(add_transfer(&context->data, context->context, 0, sizeof(GPUHexContext), gpu->current_frame, gpu));
return VK_SUCCESS;
}
VkResult create_hex_region(uint32_t x, uint32_t y, HexRegion* region, RenderContext* gpu) {
VkResult result;
region->x = x;
region->y = y;
VK_RESULT(create_storage_buffer(
gpu->allocator,
0,
sizeof(GPUHexRegion),
&region->region,
&region->region_memory));
VK_RESULT(add_transfer(&region->x, region->region, offsetof(GPUHexRegion, x), sizeof(uint32_t)*2, 0, gpu));
region->address = buffer_address(gpu->device, region->region);
return VK_SUCCESS;
}

@ -17,6 +17,7 @@ typedef struct ClientContextStruct {
GLFWwindow* window;
RenderContext render;
UIContext ui;
HexContext hex;
uint32_t clicked_container;
uint32_t clicked_element;
@ -51,9 +52,6 @@ vec3 up = {0, 1, 0};
VkResult main_thread(ClientContext* context) {
VkResult result;
GraphicsPipeline graphics;
ComputePipeline compute;
VK_RESULT(create_hex_pipeline(context->render.device, context->render.render_pass, &graphics, &compute));
GPUString strings[] = {
{
@ -124,17 +122,13 @@ VkResult main_thread(ClientContext* context) {
4*sizeof(uint32_t),
&context->render));
VkBuffer hex_context;
VmaAllocation hex_context_memory;
GPUHexContext hex;
VK_RESULT(create_storage_buffer(context->render.allocator, 0, sizeof(GPUHexContext), &hex_context, &hex_context_memory));
VkDeviceAddress hex_context_address = buffer_address(context->render.device, hex_context);
glm_perspective(30.0, (float)context->render.swapchain_extent.width/(float)context->render.swapchain_extent.height, 0.01, 99.9, hex.proj);
HexRegion region;
VK_RESULT(create_hex_region(0, 0, &region, &context->render));
context->position[0] = 0;
context->position[1] = 0;
context->position[2] = 0;
context->rotation[0] = 0;
context->rotation[0] = 3*M_PI/2;
context->rotation[1] = 0;
context->cur_spin[0] = 0;
context->cur_spin[1] = 0;
@ -143,7 +137,7 @@ VkResult main_thread(ClientContext* context) {
context->key_spin[1] = 0;
context->cur_spin[0] = 0;
context->cur_spin[1] = 0;
context->distance = 1;
context->distance = 10;
context->zoom = 0;
context->camera_mode = false;
context->key_spin_speed = 1.0;
@ -154,7 +148,6 @@ VkResult main_thread(ClientContext* context) {
uint32_t* mapped_codes = context->ui.containers[0].layers[0].codes_buffer;
GPUString* mapped_string = context->ui.containers[0].layers[0].strings_buffer;
char str[21];
//
double last_frame_time = glfwGetTime();
while(glfwWindowShouldClose(context->window) == 0) {
@ -183,8 +176,8 @@ VkResult main_thread(ClientContext* context) {
context->rotation[1] += (float)context->key_spin[1]*delta_time*context->key_spin_speed;
context->rotation[1] += (float)context->cur_spin[1]*delta_time*context->cur_spin_speed;
if(context->rotation[1] > M_PI/2) {
context->rotation[1] = M_PI/2;
if(context->rotation[1] > (M_PI/2 - 0.1)) {
context->rotation[1] = (M_PI/2 - 0.1);
} else if(context->rotation[1] < 0) {
context->rotation[1] = 0;
}
@ -198,9 +191,9 @@ VkResult main_thread(ClientContext* context) {
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]);
glm_lookat(camera, context->position, up, hex.view);
add_transfer(&hex, hex_context, 0, sizeof(GPUHexContext), (context->render.current_frame + 1) % MAX_FRAMES_IN_FLIGHT, &context->render);
glm_lookat(camera, context->position, up, context->hex.data.view);
add_transfer(&context->hex.data, context->hex.context, 0, sizeof(GPUHexContext), 0, &context->render);
add_transfer(&context->hex.data, context->hex.context, 0, sizeof(GPUHexContext), 1, &context->render);
}
if(context->clicked_container != 0) {
@ -223,7 +216,7 @@ VkResult main_thread(ClientContext* context) {
}
//
VkResult result = draw_frame(&context->render, &context->ui, &graphics, hex_context_address, frame_time);
VkResult result = draw_frame(&context->render, &context->ui, &context->hex, frame_time);
if(result != VK_SUCCESS) {
fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result));
glfwDestroyWindow(context->window);
@ -365,6 +358,7 @@ int main() {
// TODO: make # of fonts/textures/containers scaling, recreate GPU buffers as necessary
VK_RESULT(create_ui_context(10, 10, 10, &context.render, &context.ui));
VK_RESULT(create_hex_context(&context.render, &context.hex));
pthread_t network_thread_handle;