|
|
|
@ -41,6 +41,166 @@ int hex_indices[] = {
|
|
|
|
|
0, 1, 6,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult create_point_pipeline(
|
|
|
|
|
RenderContext* gpu,
|
|
|
|
|
GraphicsPipeline* pipeline) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file("shader/point.vert.spv", gpu->device);
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file("shader/point.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 = sizeof(HexPushConstant),
|
|
|
|
|
.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_POINT_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 graphics_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,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VK_RESULT(vkCreateGraphicsPipelines(
|
|
|
|
|
gpu->device,
|
|
|
|
|
VK_NULL_HANDLE,
|
|
|
|
|
1, &graphics_pipeline_info,
|
|
|
|
|
NULL,
|
|
|
|
|
&pipeline->pipeline));
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_ray_pipeline(
|
|
|
|
|
RenderContext* gpu,
|
|
|
|
|
GraphicsPipeline* pipeline) {
|
|
|
|
@ -531,6 +691,7 @@ VkResult create_hex_context(
|
|
|
|
|
VK_RESULT(create_ray_pipeline(gpu, &context->ray_pipeline));
|
|
|
|
|
#endif
|
|
|
|
|
VK_RESULT(create_hex_highlight_pipeline(gpu, &context->highlight_pipeline));
|
|
|
|
|
VK_RESULT(create_point_pipeline(gpu, &context->point_pipeline));
|
|
|
|
|
|
|
|
|
|
memset(&context->data, 0, sizeof(GPUHexContext));
|
|
|
|
|
glm_perspective(
|
|
|
|
@ -636,6 +797,7 @@ VkResult allocate_hex_region(
|
|
|
|
|
|
|
|
|
|
bool ray_hex_intersect(
|
|
|
|
|
float* distance,
|
|
|
|
|
uint32_t* vertex,
|
|
|
|
|
vec3 start,
|
|
|
|
|
vec3 dir,
|
|
|
|
|
vec3 region_offset,
|
|
|
|
@ -685,39 +847,41 @@ bool ray_hex_intersect(
|
|
|
|
|
glm_vec3_add(vertices[vertex], hex_offset, vertices[vertex]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*distance = INFINITY;
|
|
|
|
|
bool intersect = false;
|
|
|
|
|
|
|
|
|
|
vec3 t;
|
|
|
|
|
glm_vec3_sub(start, vertices[0], t);
|
|
|
|
|
|
|
|
|
|
for(uint32_t triangle = 0; triangle < 6; triangle++) {
|
|
|
|
|
vec3 vert[3];
|
|
|
|
|
for(int v_i = 0; v_i < 3; v_i++) {
|
|
|
|
|
vert[v_i][0] = vertices[hex_indices[triangle*3+v_i]][0];
|
|
|
|
|
vert[v_i][1] = vertices[hex_indices[triangle*3+v_i]][1];
|
|
|
|
|
vert[v_i][2] = vertices[hex_indices[triangle*3+v_i]][2];
|
|
|
|
|
vec3 vert[2];
|
|
|
|
|
for(int v_i = 0; v_i < 2; v_i++) {
|
|
|
|
|
vert[v_i][0] = vertices[hex_indices[triangle*3+v_i + 1]][0];
|
|
|
|
|
vert[v_i][1] = vertices[hex_indices[triangle*3+v_i + 1]][1];
|
|
|
|
|
vert[v_i][2] = vertices[hex_indices[triangle*3+v_i + 1]][2];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vec3 v0v1;
|
|
|
|
|
glm_vec3_sub(vert[1], vert[0], v0v1);
|
|
|
|
|
glm_vec3_sub(vert[0], vertices[0], v0v1);
|
|
|
|
|
vec3 v0v2;
|
|
|
|
|
glm_vec3_sub(vert[2], vert[0], v0v2);
|
|
|
|
|
glm_vec3_sub(vert[1], vertices[0], v0v2);
|
|
|
|
|
vec3 pvec;
|
|
|
|
|
glm_vec3_cross(dir, v0v2, pvec);
|
|
|
|
|
float det = glm_vec3_dot(v0v1, pvec);
|
|
|
|
|
|
|
|
|
|
float det_inv = 1/det;
|
|
|
|
|
|
|
|
|
|
vec3 t;
|
|
|
|
|
glm_vec3_sub(start, vert[0], t);
|
|
|
|
|
float u = glm_vec3_dot(t, pvec) * det_inv;
|
|
|
|
|
float u = glm_vec3_dot(t, pvec) / det;
|
|
|
|
|
if(u < 0 || u > 1) continue;
|
|
|
|
|
|
|
|
|
|
vec3 q;
|
|
|
|
|
glm_vec3_cross(t, v0v1, q);
|
|
|
|
|
float v = glm_vec3_dot(dir, q) * det_inv;
|
|
|
|
|
float v = glm_vec3_dot(dir, q) / det;
|
|
|
|
|
if(v < 0 || (u+v) > 1) continue;
|
|
|
|
|
|
|
|
|
|
intersect = true;
|
|
|
|
|
*distance = min(*distance, glm_vec3_dot(v0v2, q) * det_inv);
|
|
|
|
|
float intersect_distance = glm_vec3_dot(v0v2, q) / det;
|
|
|
|
|
if(intersect_distance < *distance) {
|
|
|
|
|
*distance = intersect_distance;
|
|
|
|
|
*vertex = (u > v) ? ((triangle+1) % 6)+1 : triangle+1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return intersect;
|
|
|
|
@ -725,26 +889,27 @@ bool ray_hex_intersect(
|
|
|
|
|
|
|
|
|
|
bool ray_region_intersect(
|
|
|
|
|
float* distance,
|
|
|
|
|
uint32_t* vertex,
|
|
|
|
|
uint32_t* hid,
|
|
|
|
|
vec3 start,
|
|
|
|
|
vec3 dir,
|
|
|
|
|
HexRegion* region) {
|
|
|
|
|
bool intersect = false;
|
|
|
|
|
float temp_distance;
|
|
|
|
|
*distance = INFINITY;
|
|
|
|
|
|
|
|
|
|
float intersect_distance = INFINITY;
|
|
|
|
|
uint32_t intersection_vertex = 0;
|
|
|
|
|
vec3 region_offset = {
|
|
|
|
|
((float)region->data.q + (float)region->data.r/2)*REGION_WIDTH - region->data.r*HEX_X/2,
|
|
|
|
|
0,
|
|
|
|
|
0.75*region->data.r*REGION_HEIGHT + 0.25*region->data.r*HEX_Z + 0.5*region->data.q*HEX_Z,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for(uint32_t temp_hid = 0; temp_hid < REGION_HEX_COUNT; temp_hid++) {
|
|
|
|
|
if(ray_hex_intersect(&temp_distance, start, dir, region_offset, temp_hid, region)) {
|
|
|
|
|
if(temp_distance < *distance) {
|
|
|
|
|
for(uint32_t intersect_hid = 0; intersect_hid < REGION_HEX_COUNT; intersect_hid++) {
|
|
|
|
|
if(ray_hex_intersect(&intersect_distance, &intersection_vertex, start, dir, region_offset, intersect_hid, region)) {
|
|
|
|
|
if(intersect_distance < *distance) {
|
|
|
|
|
intersect = true;
|
|
|
|
|
*hid = temp_hid;
|
|
|
|
|
*distance = temp_distance;
|
|
|
|
|
*hid = intersect_hid;
|
|
|
|
|
*distance = intersect_distance;
|
|
|
|
|
*vertex = intersection_vertex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -754,6 +919,7 @@ bool ray_region_intersect(
|
|
|
|
|
|
|
|
|
|
bool ray_world_intersect(
|
|
|
|
|
float* distance,
|
|
|
|
|
uint32_t* vertex,
|
|
|
|
|
uint32_t* rid,
|
|
|
|
|
uint32_t* hid,
|
|
|
|
|
vec4 ray_start,
|
|
|
|
@ -777,24 +943,27 @@ bool ray_world_intersect(
|
|
|
|
|
glm_vec3_divs(dir, mdir, dir);
|
|
|
|
|
|
|
|
|
|
bool intersect = false;
|
|
|
|
|
float temp_distance;
|
|
|
|
|
uint32_t temp_hid;
|
|
|
|
|
float intersect_distance = INFINITY;
|
|
|
|
|
uint32_t intersection_vertex = 0;
|
|
|
|
|
uint32_t intersect_hid;
|
|
|
|
|
|
|
|
|
|
*distance = INFINITY;
|
|
|
|
|
|
|
|
|
|
for(uint32_t temp_rid = 0; temp_rid < MAX_LOADED_REGIONS; temp_rid++) {
|
|
|
|
|
HexRegion* region = context->regions[temp_rid];
|
|
|
|
|
for(uint32_t intersect_rid = 0; intersect_rid < MAX_LOADED_REGIONS; intersect_rid++) {
|
|
|
|
|
HexRegion* region = context->regions[intersect_rid];
|
|
|
|
|
if(region == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
} else if(region->data.map != context->data.current_map) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(ray_region_intersect(&temp_distance, &temp_hid, start, dir, region)) {
|
|
|
|
|
if(temp_distance < *distance) {
|
|
|
|
|
if(ray_region_intersect(&intersect_distance, &intersection_vertex, &intersect_hid, start, dir, region)) {
|
|
|
|
|
if(intersect_distance < *distance) {
|
|
|
|
|
intersect = true;
|
|
|
|
|
*hid = temp_hid;
|
|
|
|
|
*rid = temp_rid;
|
|
|
|
|
*distance = temp_distance;
|
|
|
|
|
*hid = intersect_hid;
|
|
|
|
|
*rid = intersect_rid;
|
|
|
|
|
*vertex = intersection_vertex;
|
|
|
|
|
*distance = intersect_distance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -884,6 +1053,7 @@ VkResult update_hex_hover(
|
|
|
|
|
float distance;
|
|
|
|
|
if(ray_world_intersect(
|
|
|
|
|
&distance,
|
|
|
|
|
&hex->data.hovered_vertex,
|
|
|
|
|
&hex->data.hovered_region,
|
|
|
|
|
&hex->data.hovered_hex,
|
|
|
|
|
hex->data.hover_start,
|
|
|
|
@ -893,7 +1063,7 @@ VkResult update_hex_hover(
|
|
|
|
|
&hex->data.hovered_region,
|
|
|
|
|
hex->context,
|
|
|
|
|
offsetof(GPUHexContext, hovered_region),
|
|
|
|
|
sizeof(uint32_t)*2,
|
|
|
|
|
sizeof(uint32_t)*3,
|
|
|
|
|
gpu);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -923,6 +1093,7 @@ VkResult update_hex_click(
|
|
|
|
|
|
|
|
|
|
if(ray_world_intersect(
|
|
|
|
|
&distance,
|
|
|
|
|
&hex->data.clicked_vertex,
|
|
|
|
|
&hex->data.clicked_region,
|
|
|
|
|
&hex->data.clicked_hex,
|
|
|
|
|
hex->data.click_start,
|
|
|
|
@ -932,7 +1103,7 @@ VkResult update_hex_click(
|
|
|
|
|
&hex->data.clicked_region,
|
|
|
|
|
hex->context,
|
|
|
|
|
offsetof(GPUHexContext, clicked_region),
|
|
|
|
|
sizeof(uint32_t)*2,
|
|
|
|
|
sizeof(uint32_t)*3,
|
|
|
|
|
gpu));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|