|
|
|
@ -19,11 +19,6 @@
|
|
|
|
|
|
|
|
|
|
#define max(a, b) ((a > b) ? a : b)
|
|
|
|
|
|
|
|
|
|
typedef struct GPURayStruct {
|
|
|
|
|
vec4 a;
|
|
|
|
|
vec4 b;
|
|
|
|
|
} GPURay;
|
|
|
|
|
|
|
|
|
|
typedef struct ClientContextStruct {
|
|
|
|
|
GLFWwindow* window;
|
|
|
|
|
RenderContext* render;
|
|
|
|
@ -34,7 +29,7 @@ typedef struct ClientContextStruct {
|
|
|
|
|
uint32_t clicked_element;
|
|
|
|
|
int32_t clicked_hex[2];
|
|
|
|
|
|
|
|
|
|
vec2 cursor;
|
|
|
|
|
double cursor[2];
|
|
|
|
|
|
|
|
|
|
vec3 position;
|
|
|
|
|
|
|
|
|
@ -51,12 +46,8 @@ typedef struct ClientContextStruct {
|
|
|
|
|
float zoom_speed;
|
|
|
|
|
|
|
|
|
|
mat4 inverse;
|
|
|
|
|
|
|
|
|
|
GraphicsPipeline ray_pipeline;
|
|
|
|
|
VkBuffer ray;
|
|
|
|
|
VkDeviceAddress ray_address;
|
|
|
|
|
VmaAllocation ray_memory;
|
|
|
|
|
|
|
|
|
|
vec4 cursor_ray[2];
|
|
|
|
|
vec4 click_ray[2];
|
|
|
|
|
} ClientContext;
|
|
|
|
|
|
|
|
|
|
void* network_thread(void* data) {
|
|
|
|
@ -69,170 +60,9 @@ 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[] = {
|
|
|
|
|
{
|
|
|
|
|
.pos = {0, 32},
|
|
|
|
@ -272,8 +102,8 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
uint32_t region = 0;
|
|
|
|
|
for(int32_t q = 0; q < 1; q++) {
|
|
|
|
|
for(int32_t r = 0; r < 1; r++) {
|
|
|
|
|
for(int32_t q = -10; q < 10; q++) {
|
|
|
|
|
for(int32_t r = -10; r < 10; 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++) {
|
|
|
|
@ -414,7 +244,7 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
VkResult result = draw_frame(context->render, context->ui, context->hex, context->ray_pipeline, context->ray_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);
|
|
|
|
@ -475,6 +305,25 @@ bool contains(double* point, GPUContainer* container, GPUDrawable* rect) {
|
|
|
|
|
(point[1] >= container->offset[1] && point[1] <= container->offset[1] + container->size[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cursor_to_world_ray(ClientContext* context, double cursor[2], vec4 start, vec4 end) {
|
|
|
|
|
vec4 transformed_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 transformed_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,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
glm_mat4_mulv(context->inverse, transformed_start, start);
|
|
|
|
|
glm_mat4_mulv(context->inverse, transformed_end, end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
|
|
|
|
|
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
|
|
|
|
|
|
|
|
|
@ -495,24 +344,7 @@ 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);
|
|
|
|
|
cursor_to_world_ray(context, cursor, context->click_ray[0], context->click_ray[1]);
|
|
|
|
|
|
|
|
|
|
for(int32_t c = context->ui->max_containers - 1; c >= 0; c--) {
|
|
|
|
|
if(context->ui->containers[c].id == 0x00000000) {
|
|
|
|
@ -551,10 +383,10 @@ void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) {
|
|
|
|
|
if(context->camera_mode == true) {
|
|
|
|
|
context->cur_spin[0] = (xpos - context->cursor[0])/context->render->swapchain_extent.width*-100;
|
|
|
|
|
context->cur_spin[1] = (ypos - context->cursor[1])/context->render->swapchain_extent.height*100;
|
|
|
|
|
|
|
|
|
|
context->cursor[0] = xpos;
|
|
|
|
|
context->cursor[1] = ypos;
|
|
|
|
|
}
|
|
|
|
|
context->cursor[0] = xpos;
|
|
|
|
|
context->cursor[1] = ypos;
|
|
|
|
|
cursor_to_world_ray(context, context->cursor, context->cursor_ray[0], context->cursor_ray[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|