|  |  |  | @ -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; | 
		
	
	
		
			
				
					|  |  |  | 
 |