|
|
|
@ -1,6 +1,9 @@
|
|
|
|
|
#include "GLFW/glfw3.h"
|
|
|
|
|
#define CGLM_PRINT_PRECISION 10
|
|
|
|
|
#define CGLM_DEFINE_PRINTS 1
|
|
|
|
|
#include "cglm/cam.h"
|
|
|
|
|
#include "cglm/mat4.h"
|
|
|
|
|
#include "cglm/io.h"
|
|
|
|
|
#include "ui.h"
|
|
|
|
|
#include "gpu.h"
|
|
|
|
|
#include "draw.h"
|
|
|
|
@ -16,6 +19,11 @@
|
|
|
|
|
|
|
|
|
|
#define max(a, b) ((a > b) ? a : b)
|
|
|
|
|
|
|
|
|
|
typedef struct GPURayStruct {
|
|
|
|
|
vec4 a;
|
|
|
|
|
vec4 b;
|
|
|
|
|
} GPURay;
|
|
|
|
|
|
|
|
|
|
typedef struct ClientContextStruct {
|
|
|
|
|
GLFWwindow* window;
|
|
|
|
|
RenderContext* render;
|
|
|
|
@ -41,6 +49,14 @@ typedef struct ClientContextStruct {
|
|
|
|
|
float key_spin_speed;
|
|
|
|
|
float cur_spin_speed;
|
|
|
|
|
float zoom_speed;
|
|
|
|
|
|
|
|
|
|
mat4 inverse;
|
|
|
|
|
|
|
|
|
|
GraphicsPipeline ray_pipeline;
|
|
|
|
|
VkBuffer ray;
|
|
|
|
|
VkDeviceAddress ray_address;
|
|
|
|
|
VmaAllocation ray_memory;
|
|
|
|
|
|
|
|
|
|
} ClientContext;
|
|
|
|
|
|
|
|
|
|
void* network_thread(void* data) {
|
|
|
|
@ -53,9 +69,169 @@ void* network_thread(void* data) {
|
|
|
|
|
vec3 zero = {0, 0, 0};
|
|
|
|
|
vec3 up = {0, 1, 0};
|
|
|
|
|
|
|
|
|
|
VkResult create_ray_pipeline(RenderContext* gpu, GraphicsPipeline* pipeline) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file("shader/ray.vert.spv", gpu->device);
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file("shader/ray.frag.spv", gpu->device);
|
|
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo stages[] = {
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
.module = vert_shader,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
.module = frag_shader,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPushConstantRange push = {
|
|
|
|
|
.size = 2*sizeof(VkDeviceAddress),
|
|
|
|
|
.offset = 0,
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
|
|
|
.pPushConstantRanges = &push,
|
|
|
|
|
.pushConstantRangeCount = 1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VK_RESULT(vkCreatePipelineLayout(gpu->device, &layout_info, NULL, &pipeline->layout));
|
|
|
|
|
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo vertex_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
|
|
|
|
.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
|
|
|
|
|
.primitiveRestartEnable = VK_FALSE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkViewport viewport = {
|
|
|
|
|
.x = 0.0f,
|
|
|
|
|
.y = 0.0f,
|
|
|
|
|
.width = (float)(100),
|
|
|
|
|
.height = (float)(100),
|
|
|
|
|
.minDepth = 0.0f,
|
|
|
|
|
.maxDepth = 1.0f,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkRect2D scissor = {
|
|
|
|
|
.offset = {
|
|
|
|
|
.x = 0,
|
|
|
|
|
.y = 0,
|
|
|
|
|
},
|
|
|
|
|
.extent = {
|
|
|
|
|
.width = 100,
|
|
|
|
|
.height = 100,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineViewportStateCreateInfo viewport_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
|
|
|
|
.viewportCount = 1,
|
|
|
|
|
.pViewports = &viewport,
|
|
|
|
|
.scissorCount = 1,
|
|
|
|
|
.pScissors = &scissor,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineRasterizationStateCreateInfo raster_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
|
|
|
|
.depthClampEnable = VK_FALSE,
|
|
|
|
|
.rasterizerDiscardEnable = VK_FALSE,
|
|
|
|
|
.polygonMode = VK_POLYGON_MODE_FILL,
|
|
|
|
|
.lineWidth = 1.0f,
|
|
|
|
|
.cullMode = VK_CULL_MODE_BACK_BIT,
|
|
|
|
|
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineColorBlendAttachmentState blend_attachments = {
|
|
|
|
|
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
|
|
|
|
.blendEnable = VK_TRUE,
|
|
|
|
|
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
|
|
|
|
|
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
|
|
|
|
.colorBlendOp = VK_BLEND_OP_ADD,
|
|
|
|
|
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
|
|
|
|
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
|
|
|
|
.alphaBlendOp = VK_BLEND_OP_ADD,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineColorBlendStateCreateInfo blend_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
|
|
|
|
.logicOpEnable = VK_FALSE,
|
|
|
|
|
.logicOp = VK_LOGIC_OP_COPY,
|
|
|
|
|
.attachmentCount = 1,
|
|
|
|
|
.pAttachments = &blend_attachments,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDynamicState dynamic_states[] = {
|
|
|
|
|
VK_DYNAMIC_STATE_VIEWPORT,
|
|
|
|
|
VK_DYNAMIC_STATE_SCISSOR,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineDynamicStateCreateInfo dynamic_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
|
|
|
|
.dynamicStateCount = sizeof(dynamic_states)/sizeof(VkDynamicState),
|
|
|
|
|
.pDynamicStates = dynamic_states,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineMultisampleStateCreateInfo multisample_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
|
|
|
|
.sampleShadingEnable = VK_FALSE,
|
|
|
|
|
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
.minSampleShading = 1.0f,
|
|
|
|
|
.pSampleMask = 0,
|
|
|
|
|
.alphaToCoverageEnable = VK_FALSE,
|
|
|
|
|
.alphaToOneEnable = VK_FALSE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineDepthStencilStateCreateInfo depth_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
|
|
|
|
.depthTestEnable = VK_TRUE,
|
|
|
|
|
.depthWriteEnable = VK_TRUE,
|
|
|
|
|
.depthCompareOp = VK_COMPARE_OP_LESS,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkGraphicsPipelineCreateInfo pipeline_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
|
|
|
|
.layout = pipeline->layout,
|
|
|
|
|
.stageCount = sizeof(stages)/sizeof(VkPipelineShaderStageCreateInfo),
|
|
|
|
|
.pStages = stages,
|
|
|
|
|
.pVertexInputState = &vertex_info,
|
|
|
|
|
.pInputAssemblyState = &input_info,
|
|
|
|
|
.pViewportState = &viewport_info,
|
|
|
|
|
.pRasterizationState = &raster_info,
|
|
|
|
|
.pColorBlendState = &blend_info,
|
|
|
|
|
.pDynamicState = &dynamic_info,
|
|
|
|
|
.pMultisampleState = &multisample_info,
|
|
|
|
|
.pDepthStencilState = &depth_info,
|
|
|
|
|
.renderPass = gpu->render_pass,
|
|
|
|
|
.subpass = 0,
|
|
|
|
|
.basePipelineHandle = VK_NULL_HANDLE,
|
|
|
|
|
.basePipelineIndex = -1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return vkCreateGraphicsPipelines(gpu->device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &pipeline->pipeline);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult main_thread(ClientContext* context) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
VK_RESULT(create_ray_pipeline(context->render, &context->ray_pipeline));
|
|
|
|
|
|
|
|
|
|
VK_RESULT(create_storage_buffer(
|
|
|
|
|
context->render->allocator,
|
|
|
|
|
0,
|
|
|
|
|
sizeof(GPURay),
|
|
|
|
|
&context->ray,
|
|
|
|
|
&context->ray_memory));
|
|
|
|
|
context->ray_address = buffer_address(context->render->device, context->ray);
|
|
|
|
|
|
|
|
|
|
GPUString strings[] = {
|
|
|
|
|
{
|
|
|
|
@ -96,8 +272,8 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
uint32_t region = 0;
|
|
|
|
|
for(int32_t q = -10; q < 10; q++) {
|
|
|
|
|
for(int32_t r = -10; r < 10; r++) {
|
|
|
|
|
for(int32_t q = 0; q < 1; q++) {
|
|
|
|
|
for(int32_t r = 0; r < 1; r++) {
|
|
|
|
|
VK_RESULT(create_hex_region(q, r, ®ions[region], context->hex, context->render));
|
|
|
|
|
for(uint32_t i = 0; i < REGION_HEX_COUNT; i++) {
|
|
|
|
|
for(uint32_t h = 0; h < 6; h++) {
|
|
|
|
@ -159,10 +335,10 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
if(context->render->framebuffer_recreated == true) {
|
|
|
|
|
context->render->framebuffer_recreated = false;
|
|
|
|
|
glm_perspective(
|
|
|
|
|
-M_PI*1/8,
|
|
|
|
|
PERSPECTIVE_FOVY,
|
|
|
|
|
(float)context->render->swapchain_extent.width/(float)context->render->swapchain_extent.height,
|
|
|
|
|
0.01,
|
|
|
|
|
1000,
|
|
|
|
|
PERSPECTIVE_NEARZ,
|
|
|
|
|
PERSPECTIVE_FARZ,
|
|
|
|
|
context->hex->data.proj);
|
|
|
|
|
VK_RESULT(add_transfer(
|
|
|
|
|
&context->hex->data.proj,
|
|
|
|
@ -208,6 +384,11 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
hex_forward[1] = 0;
|
|
|
|
|
|
|
|
|
|
glm_lookat(camera, context->position, up, context->hex->data.view);
|
|
|
|
|
|
|
|
|
|
mat4 regular;
|
|
|
|
|
glm_mat4_mul(context->hex->data.proj, context->hex->data.view, regular);
|
|
|
|
|
glm_mat4_inv(regular, context->inverse);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
@ -233,7 +414,7 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
VkResult result = draw_frame(context->render, context->ui, context->hex, frame_time);
|
|
|
|
|
VkResult result = draw_frame(context->render, context->ui, context->hex, context->ray_pipeline, context->ray_address, frame_time);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result));
|
|
|
|
|
glfwDestroyWindow(context->window);
|
|
|
|
@ -314,6 +495,25 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
|
|
|
|
break;
|
|
|
|
|
case GLFW_MOUSE_BUTTON_LEFT:
|
|
|
|
|
if(action == GLFW_PRESS) {
|
|
|
|
|
vec4 start = {
|
|
|
|
|
cursor[0]*context->render->window_scale[0]*2/context->render->swapchain_extent.width - 1,
|
|
|
|
|
cursor[1]*context->render->window_scale[1]*2/context->render->swapchain_extent.height - 1,
|
|
|
|
|
0,
|
|
|
|
|
1.0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
vec4 end = {
|
|
|
|
|
PERSPECTIVE_FARZ*(cursor[0]*context->render->window_scale[0]*2/context->render->swapchain_extent.width - 1),
|
|
|
|
|
PERSPECTIVE_FARZ*(cursor[1]*context->render->window_scale[1]*2/context->render->swapchain_extent.height - 1),
|
|
|
|
|
PERSPECTIVE_FARZ,
|
|
|
|
|
PERSPECTIVE_FARZ,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
vec4 rays[2] = {};
|
|
|
|
|
glm_mat4_mulv(context->inverse, start, rays[0]);
|
|
|
|
|
glm_mat4_mulv(context->inverse, end, rays[1]);
|
|
|
|
|
add_transfer(rays, context->ray, 0, 2*sizeof(vec4), context->render->current_frame, context->render);
|
|
|
|
|
|
|
|
|
|
for(int32_t c = context->ui->max_containers - 1; c >= 0; c--) {
|
|
|
|
|
if(context->ui->containers[c].id == 0x00000000) {
|
|
|
|
|
continue;
|
|
|
|
|