|
|
|
@ -13,6 +13,8 @@ use std::ffi::CString;
|
|
|
|
|
use raw_window_handle::HasDisplayHandle;
|
|
|
|
|
use raw_window_handle::HasWindowHandle;
|
|
|
|
|
|
|
|
|
|
use sdl2::event::Event;
|
|
|
|
|
use sdl2::keyboard::Keycode;
|
|
|
|
|
use sdl2::video::Window;
|
|
|
|
|
|
|
|
|
|
const APP_NAME: &str = "MineClone";
|
|
|
|
@ -411,10 +413,10 @@ fn setup_pipe_layout(dev: &Device) -> vk::PipelineLayout {
|
|
|
|
|
vk::PushConstantRange::default()
|
|
|
|
|
.stage_flags(vk::ShaderStageFlags::VERTEX)
|
|
|
|
|
.offset(0)
|
|
|
|
|
.size(32), // vec4 camera_orig, camera_rot
|
|
|
|
|
.size(48), // vec4 camera_orig, camera_rot
|
|
|
|
|
vk::PushConstantRange::default()
|
|
|
|
|
.stage_flags(vk::ShaderStageFlags::FRAGMENT)
|
|
|
|
|
.offset(32)
|
|
|
|
|
.offset(48)
|
|
|
|
|
.size(16), // vec4 base_color
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
@ -450,9 +452,9 @@ fn setup_pipeline(
|
|
|
|
|
dev: &Device,
|
|
|
|
|
vert_shader: &vk::ShaderModule,
|
|
|
|
|
frag_shader: &vk::ShaderModule,
|
|
|
|
|
pass: &vk::RenderPass,
|
|
|
|
|
pipe_layout: &vk::PipelineLayout,
|
|
|
|
|
) -> vk::Pipeline {
|
|
|
|
|
let pipe_layout = setup_pipe_layout(&dev);
|
|
|
|
|
let pass = setup_render_pass(&dev);
|
|
|
|
|
let shader_stages = setup_shader_stage(&dev, *vert_shader, *frag_shader);
|
|
|
|
|
let vert_input = vk::PipelineVertexInputStateCreateInfo::default();
|
|
|
|
|
let input_assembly = vk::PipelineInputAssemblyStateCreateInfo::default()
|
|
|
|
@ -508,9 +510,9 @@ fn setup_pipeline(
|
|
|
|
|
.multisample_state(&multisample)
|
|
|
|
|
.depth_stencil_state(&depth_stencil)
|
|
|
|
|
.color_blend_state(&color_blend)
|
|
|
|
|
.layout(pipe_layout)
|
|
|
|
|
.layout(*pipe_layout)
|
|
|
|
|
.dynamic_state(&dynamic)
|
|
|
|
|
.render_pass(pass)
|
|
|
|
|
.render_pass(*pass)
|
|
|
|
|
.subpass(0);
|
|
|
|
|
|
|
|
|
|
let pipe = unsafe {
|
|
|
|
@ -633,6 +635,355 @@ fn make_swap_views(
|
|
|
|
|
views
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn make_depth_view(dev: &Device, depth_img: &vk::Image, format: vk::Format) -> vk::ImageView {
|
|
|
|
|
let view_info = vk::ImageViewCreateInfo::default()
|
|
|
|
|
.image(*depth_img)
|
|
|
|
|
.view_type(vk::ImageViewType::TYPE_2D)
|
|
|
|
|
.format(format)
|
|
|
|
|
.components(vk::ComponentMapping::default())
|
|
|
|
|
.subresource_range(
|
|
|
|
|
vk::ImageSubresourceRange::default()
|
|
|
|
|
.aspect_mask(vk::ImageAspectFlags::DEPTH)
|
|
|
|
|
.base_mip_level(0)
|
|
|
|
|
.level_count(1)
|
|
|
|
|
.base_array_layer(0)
|
|
|
|
|
.layer_count(1),
|
|
|
|
|
);
|
|
|
|
|
let view = unsafe {
|
|
|
|
|
dev.create_image_view(&view_info, None)
|
|
|
|
|
.expect("Failed to create image view")
|
|
|
|
|
};
|
|
|
|
|
view
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn make_framebufs(
|
|
|
|
|
dev: &Device,
|
|
|
|
|
swap_views: &Vec<vk::ImageView>,
|
|
|
|
|
depth_view: &vk::ImageView,
|
|
|
|
|
pass: &vk::RenderPass,
|
|
|
|
|
width: u32,
|
|
|
|
|
height: u32,
|
|
|
|
|
) -> Vec<vk::Framebuffer> {
|
|
|
|
|
let mut framebufs = Vec::new();
|
|
|
|
|
for view in swap_views.iter() {
|
|
|
|
|
let attachments = [*view, *depth_view];
|
|
|
|
|
let framebuf_info = vk::FramebufferCreateInfo::default()
|
|
|
|
|
.render_pass(*pass)
|
|
|
|
|
.attachments(attachments.as_ref())
|
|
|
|
|
.width(width)
|
|
|
|
|
.height(height)
|
|
|
|
|
.layers(1);
|
|
|
|
|
let framebuf = unsafe {
|
|
|
|
|
dev.create_framebuffer(&framebuf_info, None)
|
|
|
|
|
.expect("Failed to create framebuffer")
|
|
|
|
|
};
|
|
|
|
|
framebufs.push(framebuf);
|
|
|
|
|
}
|
|
|
|
|
framebufs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn make_desc_sets(dev: &Device, desc_pool: &vk::DescriptorPool) -> Vec<vk::DescriptorSet> {
|
|
|
|
|
let layout = setup_desc_layout(&dev);
|
|
|
|
|
let layouts = [layout];
|
|
|
|
|
let alloc_info = vk::DescriptorSetAllocateInfo::default()
|
|
|
|
|
.descriptor_pool(*desc_pool)
|
|
|
|
|
.set_layouts(&layouts);
|
|
|
|
|
let sets = unsafe {
|
|
|
|
|
dev.allocate_descriptor_sets(&alloc_info)
|
|
|
|
|
.expect("Failed to allocate descriptor sets")
|
|
|
|
|
};
|
|
|
|
|
sets
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn write_desc_sets(dev: &Device, desc_sets: &Vec<vk::DescriptorSet>, mesh_buf: &vk::Buffer) {
|
|
|
|
|
let buf_info = vk::DescriptorBufferInfo::default()
|
|
|
|
|
.buffer(*mesh_buf)
|
|
|
|
|
.offset(0)
|
|
|
|
|
.range(vk::WHOLE_SIZE);
|
|
|
|
|
let buf_infos = [buf_info];
|
|
|
|
|
let buf_desc = vk::WriteDescriptorSet::default()
|
|
|
|
|
.dst_set(desc_sets[0])
|
|
|
|
|
.dst_binding(0)
|
|
|
|
|
.dst_array_element(0)
|
|
|
|
|
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
|
|
|
|
|
.buffer_info(&buf_infos);
|
|
|
|
|
unsafe {
|
|
|
|
|
dev.update_descriptor_sets(&[buf_desc], &[]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn make_sem(dev: &Device) -> vk::Semaphore {
|
|
|
|
|
let sem_info = vk::SemaphoreCreateInfo::default();
|
|
|
|
|
let sem = unsafe {
|
|
|
|
|
dev.create_semaphore(&sem_info, None)
|
|
|
|
|
.expect("Failed to create semaphore")
|
|
|
|
|
};
|
|
|
|
|
sem
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn make_fence(dev: &Device) -> vk::Fence {
|
|
|
|
|
let fence_info = vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED);
|
|
|
|
|
let fence = unsafe {
|
|
|
|
|
dev.create_fence(&fence_info, None)
|
|
|
|
|
.expect("Failed to create fence")
|
|
|
|
|
};
|
|
|
|
|
fence
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn wait_for_fence(dev: &Device, fence: &vk::Fence) {
|
|
|
|
|
unsafe {
|
|
|
|
|
let fence = [*fence];
|
|
|
|
|
dev.wait_for_fences(&fence, true, u64::MAX)
|
|
|
|
|
.expect("Failed to wait for fence");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn reset_fence(dev: &Device, fence: &vk::Fence) {
|
|
|
|
|
unsafe {
|
|
|
|
|
let fence = [*fence];
|
|
|
|
|
dev.reset_fences(&fence).expect("Failed to reset fence");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn ack_next_img(
|
|
|
|
|
dev: &Device,
|
|
|
|
|
swapchain_loader: &swapchain::Device,
|
|
|
|
|
swapchain: &vk::SwapchainKHR,
|
|
|
|
|
sem_avail: &vk::Semaphore,
|
|
|
|
|
fence: &vk::Fence,
|
|
|
|
|
) -> u32 {
|
|
|
|
|
unsafe {
|
|
|
|
|
let (img_inx, _) = swapchain_loader
|
|
|
|
|
.acquire_next_image(*swapchain, u64::MAX, *sem_avail, vk::Fence::null())
|
|
|
|
|
.expect("Failed to acquire next image");
|
|
|
|
|
img_inx
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn record_commands(
|
|
|
|
|
dev: &Device,
|
|
|
|
|
cmd_buf: &vk::CommandBuffer,
|
|
|
|
|
framebuf: &vk::Framebuffer,
|
|
|
|
|
pass: &vk::RenderPass,
|
|
|
|
|
layout: &vk::PipelineLayout,
|
|
|
|
|
width: u32,
|
|
|
|
|
height: u32,
|
|
|
|
|
pipe: &vk::Pipeline,
|
|
|
|
|
desc_sets: &Vec<vk::DescriptorSet>,
|
|
|
|
|
camera: &Camera,
|
|
|
|
|
) {
|
|
|
|
|
let clear_vals = [
|
|
|
|
|
vk::ClearValue {
|
|
|
|
|
color: vk::ClearColorValue {
|
|
|
|
|
float32: [0.0, 0.0, 0.0, 1.0],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
vk::ClearValue {
|
|
|
|
|
depth_stencil: vk::ClearDepthStencilValue {
|
|
|
|
|
depth: 1.0,
|
|
|
|
|
stencil: 0,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
let render_pass_info = vk::RenderPassBeginInfo::default()
|
|
|
|
|
.render_pass(*pass)
|
|
|
|
|
.framebuffer(*framebuf)
|
|
|
|
|
.render_area(
|
|
|
|
|
vk::Rect2D::default()
|
|
|
|
|
.offset(vk::Offset2D::default())
|
|
|
|
|
.extent(vk::Extent2D { width, height }),
|
|
|
|
|
)
|
|
|
|
|
.clear_values(&clear_vals);
|
|
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
dev.cmd_begin_render_pass(*cmd_buf, &render_pass_info, vk::SubpassContents::INLINE);
|
|
|
|
|
dev.cmd_bind_pipeline(*cmd_buf, vk::PipelineBindPoint::GRAPHICS, *pipe);
|
|
|
|
|
dev.cmd_bind_descriptor_sets(
|
|
|
|
|
*cmd_buf,
|
|
|
|
|
vk::PipelineBindPoint::GRAPHICS,
|
|
|
|
|
*layout,
|
|
|
|
|
0,
|
|
|
|
|
desc_sets.as_ref(),
|
|
|
|
|
&[],
|
|
|
|
|
);
|
|
|
|
|
dev.cmd_set_viewport_with_count(
|
|
|
|
|
*cmd_buf,
|
|
|
|
|
&[vk::Viewport::default()
|
|
|
|
|
.width(width as f32)
|
|
|
|
|
.height(height as f32)],
|
|
|
|
|
);
|
|
|
|
|
dev.cmd_set_scissor_with_count(
|
|
|
|
|
*cmd_buf,
|
|
|
|
|
&[vk::Rect2D::default().extent(vk::Extent2D { width, height })],
|
|
|
|
|
);
|
|
|
|
|
let cam_data: Vec<u8> = (Vec::<f32>::from([
|
|
|
|
|
camera.origin.x,
|
|
|
|
|
camera.origin.y,
|
|
|
|
|
camera.origin.z,
|
|
|
|
|
0.0,
|
|
|
|
|
camera.rotation.x,
|
|
|
|
|
camera.rotation.y,
|
|
|
|
|
camera.rotation.z,
|
|
|
|
|
]))
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|f| f.to_ne_bytes())
|
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
|
.into_flattened();
|
|
|
|
|
|
|
|
|
|
let screen_res: Vec<u8> = (Vec::<u32>::from([width, height]))
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|f| f.to_ne_bytes())
|
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
|
.into_flattened();
|
|
|
|
|
let base_color: Vec<u8> = (Vec::<f32>::from([0.0, 1.0, 1.0, 1.0]))
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|f| f.to_ne_bytes())
|
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
|
.into_flattened();
|
|
|
|
|
|
|
|
|
|
dev.cmd_push_constants(
|
|
|
|
|
*cmd_buf,
|
|
|
|
|
*layout,
|
|
|
|
|
vk::ShaderStageFlags::VERTEX,
|
|
|
|
|
0,
|
|
|
|
|
cam_data.as_ref(),
|
|
|
|
|
);
|
|
|
|
|
dev.cmd_push_constants(
|
|
|
|
|
*cmd_buf,
|
|
|
|
|
*layout,
|
|
|
|
|
vk::ShaderStageFlags::VERTEX,
|
|
|
|
|
32,
|
|
|
|
|
screen_res.as_ref(),
|
|
|
|
|
);
|
|
|
|
|
dev.cmd_push_constants(
|
|
|
|
|
*cmd_buf,
|
|
|
|
|
*layout,
|
|
|
|
|
vk::ShaderStageFlags::FRAGMENT,
|
|
|
|
|
48,
|
|
|
|
|
base_color.as_ref(),
|
|
|
|
|
);
|
|
|
|
|
dev.cmd_draw(*cmd_buf, 36, 1, 0, 0);
|
|
|
|
|
dev.cmd_end_render_pass(*cmd_buf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn start_cmd_buf(dev: &Device, cmd_buf: &vk::CommandBuffer) {
|
|
|
|
|
unsafe {
|
|
|
|
|
dev.reset_command_buffer(*cmd_buf, vk::CommandBufferResetFlags::empty())
|
|
|
|
|
.expect("Failed to reset command buffer");
|
|
|
|
|
let begin_info =
|
|
|
|
|
vk::CommandBufferBeginInfo::default().flags(vk::CommandBufferUsageFlags::empty());
|
|
|
|
|
dev.begin_command_buffer(*cmd_buf, &begin_info)
|
|
|
|
|
.expect("Failed to begin command buffer");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn end_cmd_buf(dev: &Device, cmd_buf: &vk::CommandBuffer) {
|
|
|
|
|
unsafe {
|
|
|
|
|
dev.end_command_buffer(*cmd_buf)
|
|
|
|
|
.expect("Failed to end command buffer");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn submit_queue(
|
|
|
|
|
dev: &Device,
|
|
|
|
|
queue: &vk::Queue,
|
|
|
|
|
cmd_buf: &vk::CommandBuffer,
|
|
|
|
|
sem_avail: &vk::Semaphore,
|
|
|
|
|
sem_finish: &vk::Semaphore,
|
|
|
|
|
fence: &vk::Fence,
|
|
|
|
|
) {
|
|
|
|
|
let cmd_bufs = [*cmd_buf];
|
|
|
|
|
let wait_sems = [*sem_avail];
|
|
|
|
|
let signal_sems = [*sem_finish];
|
|
|
|
|
let submit_info = vk::SubmitInfo::default()
|
|
|
|
|
.command_buffers(&cmd_bufs)
|
|
|
|
|
.wait_semaphores(&wait_sems)
|
|
|
|
|
.wait_dst_stage_mask(&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT])
|
|
|
|
|
.signal_semaphores(&signal_sems);
|
|
|
|
|
unsafe {
|
|
|
|
|
dev.queue_submit(*queue, &[submit_info], *fence)
|
|
|
|
|
.expect("Failed to submit queue");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn queue_present(
|
|
|
|
|
swapchain_loader: &swapchain::Device,
|
|
|
|
|
queue: &vk::Queue,
|
|
|
|
|
swapchain: &vk::SwapchainKHR,
|
|
|
|
|
img_inx: u32,
|
|
|
|
|
sem_finish: &vk::Semaphore,
|
|
|
|
|
) {
|
|
|
|
|
let swapchains = [*swapchain];
|
|
|
|
|
let img_inxs = [img_inx];
|
|
|
|
|
let wait_sems = [*sem_finish];
|
|
|
|
|
let present_info = vk::PresentInfoKHR::default()
|
|
|
|
|
.swapchains(&swapchains)
|
|
|
|
|
.image_indices(&img_inxs)
|
|
|
|
|
.wait_semaphores(&wait_sems);
|
|
|
|
|
unsafe {
|
|
|
|
|
swapchain_loader
|
|
|
|
|
.queue_present(*queue, &present_info)
|
|
|
|
|
.expect("Failed to present queue");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct Vector3 {
|
|
|
|
|
x: f32,
|
|
|
|
|
y: f32,
|
|
|
|
|
z: f32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct Camera {
|
|
|
|
|
origin: Vector3,
|
|
|
|
|
rotation: Vector3,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn handle_key(keycode: Keycode, camera: &mut Camera) {
|
|
|
|
|
let mov_scale = 0.01;
|
|
|
|
|
let rot_scale = 0.01;
|
|
|
|
|
match keycode {
|
|
|
|
|
Keycode::W => {
|
|
|
|
|
camera.origin.x -= -camera.rotation.y.sin() * mov_scale;
|
|
|
|
|
camera.origin.z -= camera.rotation.y.cos() * mov_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::S => {
|
|
|
|
|
camera.origin.x += -camera.rotation.y.sin() * mov_scale;
|
|
|
|
|
camera.origin.z += camera.rotation.y.cos() * mov_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::A => {
|
|
|
|
|
camera.origin.x += camera.rotation.y.cos() * mov_scale;
|
|
|
|
|
camera.origin.z += camera.rotation.y.sin() * mov_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::D => {
|
|
|
|
|
camera.origin.z -= camera.rotation.y.sin() * mov_scale;
|
|
|
|
|
camera.origin.x -= camera.rotation.y.cos() * mov_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::R => {
|
|
|
|
|
camera.rotation.x += rot_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::F => {
|
|
|
|
|
camera.rotation.x -= rot_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::Q => {
|
|
|
|
|
camera.rotation.y += rot_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::E => {
|
|
|
|
|
camera.rotation.y -= rot_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::Space => {
|
|
|
|
|
camera.origin.y += mov_scale;
|
|
|
|
|
}
|
|
|
|
|
Keycode::LShift => {
|
|
|
|
|
camera.origin.y -= mov_scale;
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let sdl_context = sdl2::init().unwrap();
|
|
|
|
|
let video_subsystem = sdl_context.video().unwrap();
|
|
|
|
@ -659,7 +1010,12 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
let rcs_queue_inx = find_rcs_queue_inx(&instance, &pdev).expect("No RCS queue found");
|
|
|
|
|
|
|
|
|
|
let dev = make_dev(&instance, &pdev, rcs_queue_inx, vec![c"VK_KHR_swapchain", c"VK_EXT_extended_dynamic_state3"]);
|
|
|
|
|
let dev = make_dev(
|
|
|
|
|
&instance,
|
|
|
|
|
&pdev,
|
|
|
|
|
rcs_queue_inx,
|
|
|
|
|
vec![c"VK_KHR_swapchain", c"VK_EXT_extended_dynamic_state3"],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let queue = unsafe { dev.get_device_queue(rcs_queue_inx, 0) };
|
|
|
|
|
|
|
|
|
@ -725,7 +1081,10 @@ fn main() {
|
|
|
|
|
.expect("Failed to create fragment shader module")
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let pipe = setup_pipeline(&dev, &vert_shader, &frag_shader);
|
|
|
|
|
let pass = setup_render_pass(&dev);
|
|
|
|
|
|
|
|
|
|
let pipe_layout = setup_pipe_layout(&dev);
|
|
|
|
|
let pipe = setup_pipeline(&dev, &vert_shader, &frag_shader, &pass, &pipe_layout);
|
|
|
|
|
|
|
|
|
|
let surface_loader = surface::Instance::new(&entry, &instance);
|
|
|
|
|
let swapchain_loader = swapchain::Device::new(&instance, &dev);
|
|
|
|
@ -744,4 +1103,81 @@ fn main() {
|
|
|
|
|
let swap_images = make_swap_images(&dev, &swapchain, &swapchain_loader);
|
|
|
|
|
|
|
|
|
|
let swap_views = make_swap_views(&dev, &swap_images, vk::Format::B8G8R8A8_UNORM);
|
|
|
|
|
|
|
|
|
|
let depth_view = make_depth_view(&dev, &depth_img, vk::Format::D32_SFLOAT);
|
|
|
|
|
|
|
|
|
|
let framebufs = make_framebufs(&dev, &swap_views, &depth_view, &pass, width, height);
|
|
|
|
|
|
|
|
|
|
let desc_sets = make_desc_sets(&dev, &desc_pool);
|
|
|
|
|
|
|
|
|
|
write_desc_sets(&dev, &desc_sets, &mesh_buf);
|
|
|
|
|
|
|
|
|
|
let sem_avail = make_sem(&dev);
|
|
|
|
|
let sem_finish = make_sem(&dev);
|
|
|
|
|
let fence_flight = make_fence(&dev);
|
|
|
|
|
|
|
|
|
|
let mut event_pump = sdl_context.event_pump().expect("Failed to get event pump");
|
|
|
|
|
let mut camera = Camera {
|
|
|
|
|
origin: Vector3 {
|
|
|
|
|
x: 0.0,
|
|
|
|
|
y: 0.0,
|
|
|
|
|
z: 0.0,
|
|
|
|
|
},
|
|
|
|
|
rotation: Vector3 {
|
|
|
|
|
x: 0.0,
|
|
|
|
|
y: 0.0,
|
|
|
|
|
z: 0.0,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut running = true;
|
|
|
|
|
while running {
|
|
|
|
|
for event in event_pump.poll_iter() {
|
|
|
|
|
match event {
|
|
|
|
|
Event::Quit { .. } => running = false,
|
|
|
|
|
Event::KeyDown {
|
|
|
|
|
keycode: Some(keycode),
|
|
|
|
|
..
|
|
|
|
|
} => handle_key(keycode, &mut camera),
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wait_for_fence(&dev, &fence_flight);
|
|
|
|
|
reset_fence(&dev, &fence_flight);
|
|
|
|
|
|
|
|
|
|
let img_inx = ack_next_img(
|
|
|
|
|
&dev,
|
|
|
|
|
&swapchain_loader,
|
|
|
|
|
&swapchain,
|
|
|
|
|
&sem_avail,
|
|
|
|
|
&fence_flight,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
start_cmd_buf(&dev, &cmd_buf);
|
|
|
|
|
|
|
|
|
|
record_commands(
|
|
|
|
|
&dev,
|
|
|
|
|
&cmd_buf,
|
|
|
|
|
&framebufs[img_inx as usize],
|
|
|
|
|
&pass,
|
|
|
|
|
&pipe_layout,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
&pipe,
|
|
|
|
|
&desc_sets,
|
|
|
|
|
&camera,
|
|
|
|
|
);
|
|
|
|
|
end_cmd_buf(&dev, &cmd_buf);
|
|
|
|
|
|
|
|
|
|
submit_queue(
|
|
|
|
|
&dev,
|
|
|
|
|
&queue,
|
|
|
|
|
&cmd_buf,
|
|
|
|
|
&sem_avail,
|
|
|
|
|
&sem_finish,
|
|
|
|
|
&fence_flight,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
queue_present(&swapchain_loader, &queue, &swapchain, img_inx, &sem_finish);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|