Compare commits

...

4 Commits

Author SHA1 Message Date
itycodes 6f04e54627 Skybox rendering
4 months ago
itycodes a5bbd536ca Fix mistakes in movement code
4 months ago
Avery d7615e5658
New movement controller
4 months ago
Avery a50b95de09
Fixed movement controller, nix flake
4 months ago

@ -0,0 +1,61 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1743315132,
"narHash": "sha256-6hl6L/tRnwubHcA4pfUUtk542wn2Om+D4UnDhlDW9BE=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "52faf482a3889b7619003c0daec593a1912fddc1",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

@ -0,0 +1,33 @@
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = {
self,
nixpkgs,
flake-utils,
} @ inputs:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {
inherit system;
};
lib = nixpkgs.lib;
in {
devShells.default = pkgs.mkShell {
VULKAN_SDK = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d";
# LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${pkgs.SDL2}/lib/";
LD_LIBRARY_PATH = lib.makeLibraryPath (with pkgs; [SDL2 vulkan-loader]);
buildInputs = with pkgs; [
SDL2
SDL2.dev
vulkan-headers
vulkan-loader
vulkan-validation-layers # maybe?
# glm and whatnot …
];
};
});
}

Binary file not shown.

@ -1,4 +1,7 @@
#version 450
// vim: ft=c
//
layout(binding = 1) uniform samplerCube combined_image;
layout(location = 0) out vec4 outColor;
@ -10,7 +13,8 @@ layout(push_constant, std430) uniform pc {
};
void main() {
outColor = vec4(data.rgb*(1.0+dot(normal.xyz, normalize(vec3(-0.7, -0.5, -0.1))))/2.0, 1.0);
outColor = texture(combined_image, vec3(pos_pre));
// outColor = vec4(data.rgb*(1.0+dot(normal.xyz, normalize(vec3(-0.7, -0.5, -0.1))))/2.0, 1.0);
//if(pos_post.z <= 0.0) {
// outColor = vec4(1.0);
//}

Binary file not shown.

Binary file not shown.

@ -1,8 +1,13 @@
#version 450
// vim: ft=c
struct PosNorm {
vec4 pos;
vec4 norm;
};
layout(std430, set = 0, binding = 0) buffer positions_buffer {
mat2x4 posnrm[];
PosNorm posnrm[];
} pos;
layout(push_constant, std430) uniform pc {
@ -20,16 +25,22 @@ const float TAU = PI*2.0;
void main() {
// assign outs
normal = pos.posnrm[gl_VertexIndex][1];
pos_pre = pos.posnrm[gl_VertexIndex][0];
normal = pos.posnrm[gl_VertexIndex].norm;
pos_pre = pos.posnrm[gl_VertexIndex].pos;
// define constants
const float zFar = 100.0;
const float zNear = 0.1;
// assign the transformee
gl_Position = pos.posnrm[gl_VertexIndex][0];
gl_Position = pos.posnrm[gl_VertexIndex].pos;
mat4 fix_coordinates = mat4(
-1.0, 0.0, 0.0, 0.0,
0.0, -1.0, 0.0, 0.0,
0.0, 0.0, -1.0, 0.0,
0.0, 0.0, 0.0, 1.0
);
mat4 view_orig = mat4(
1.0, 0.0, 0.0, cam_orig.x,
0.0, 1.0, 0.0, cam_orig.y,
@ -73,9 +84,14 @@ void main() {
0.0, 0.0, 0.0, 1.0
);
// vulkan has inverted screen coordinates
// but we want regular mesh coordinates
// gl_Position.xyz *= -1.0
gl_Position *= fix_coordinates;
// apply view's origin transformation
//gl_Position.xyz += cam_orig.xyz;
gl_Position *= view_orig;
// gl_Position *= view_orig;
// apply view's xz rotation
//mat2 xz_rot;
@ -107,4 +123,5 @@ void main() {
// z normalization
//gl_Position.z /= zFar;
gl_Position *= project_normal;
}

@ -1,4 +1,3 @@
#![feature(inherent_str_constructors)]
#![allow(unused_variables, unused_mut)]
use ash::Device;
@ -6,9 +5,15 @@ use ash::Entry;
use ash::Instance;
use ash::khr::{surface, swapchain};
use ash::vk;
use ash::vk::ImageCreateFlags;
use sdl2::mouse::MouseUtil;
use std::cmp;
use std::ffi::CStr;
use std::ffi::CString;
use std::thread;
use std::time::Duration;
use std::time::Instant;
use raw_window_handle::HasDisplayHandle;
use raw_window_handle::HasWindowHandle;
@ -20,28 +25,131 @@ use sdl2::video::Window;
const APP_NAME: &str = "MineClone";
const MOV_STEP: f32 = 0.05;
const ROT_MOUSE_SCALE: f32 = 0.001;
const MAX_WIDTH: u32 = 3440;
const MAX_HEIGHT: u32 = 1440;
const MESH_SIZE: u64 = 36 * 2 * 4 * 4;
#[rustfmt::skip]
const POSITIONS: [f32; 36 * 2 * 4] = [
// BOTTOM
-0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 1.0, 0.0, 0.0, -0.5, 0.5, 2.0,
1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 1.0,
0.0, 0.0, -0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // TOP
0.5, -0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5,
-0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.5, -0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.5, -0.5, 1.0,
1.0, 0.0, -1.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, // FRONT
-0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, 0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, -0.5, 0.5,
1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, 0.5, 1.0, 1.0,
0.0, 0.0, -1.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, // BACK
0.5, 0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, -0.5, -0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, -0.5, 0.5,
2.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5, -0.5, 2.0, 1.0, 0.0,
0.0, 1.0, 0.0, -0.5, -0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, // LEFT
-0.5, -0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 2.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5,
-0.5, 2.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 2.0,
1.0, -1.0, 0.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, // RIGHT
0.5, 0.5, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, -0.5, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, -0.5,
2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 1.0,
0.0, 0.0, 0.0, 0.5, -0.5, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0,
-0.5, 0.5, -0.5, 1.0,
0.0, 1.0, 0.0, 0.0,
0.5, 0.5, 0.5, 1.0,
0.0, 1.0, 0.0, 0.0,
-0.5, 0.5, 0.5, 1.0,
0.0, 1.0, 0.0, 0.0,
0.5, 0.5, -0.5, 1.0,
0.0, 1.0, 0.0, 0.0,
0.5, 0.5, 0.5, 1.0,
0.0, 1.0, 0.0, 0.0,
-0.5, 0.5, -0.5, 1.0,
0.0, 1.0, 0.0, 0.0,
// TOP
0.5, -0.5, 0.5, 1.0,
0.0, -1.0, 0.0, 0.0,
-0.5, -0.5, -0.5, 1.0,
0.0, -1.0, 0.0, 0.0,
-0.5, -0.5, 0.5, 1.0,
0.0, -1.0, 0.0, 0.0,
0.5, -0.5, 0.5, 1.0,
0.0, -1.0, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0,
0.0, -1.0, 0.0, 0.0,
-0.5, -0.5, -0.5, 1.0,
0.0, -1.0, 0.0, 0.0,
// FRONT
-0.5, -0.5, -0.5, 1.0,
0.0, 0.0, -1.0, 0.0,
0.5, 0.5, -0.5, 1.0,
0.0, 0.0, -1.0, 0.0,
-0.5, 0.5, -0.5, 1.0,
0.0, 0.0, -1.0, 0.0,
0.5, -0.5, -0.5, 1.0,
0.0, 0.0, -1.0, 0.0,
0.5, 0.5, -0.5, 1.0,
0.0, 0.0, -1.0, 0.0,
-0.5, -0.5, -0.5, 1.0,
0.0, 0.0, -1.0, 0.0,
// BACK
0.5, 0.5, 0.5, 1.0,
0.0, 0.0, 1.0, 0.0,
-0.5, -0.5, 0.5, 1.0,
0.0, 0.0, 1.0, 0.0,
-0.5, 0.5, 0.5, 1.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0,
0.0, 0.0, 1.0, 0.0,
0.5, -0.5, 0.5, 1.0,
0.0, 0.0, 1.0, 0.0,
-0.5, -0.5, 0.5, 1.0,
0.0, 0.0, 1.0, 0.0,
// LEFT
-0.5, -0.5, -0.5, 1.0,
-1.0, 0.0, 0.0, 0.0,
-0.5, 0.5, 0.5, 1.0,
-1.0, 0.0, 0.0, 0.0,
-0.5, -0.5, 0.5, 1.0,
-1.0, 0.0, 0.0, 0.0,
-0.5, 0.5, -0.5, 1.0,
-1.0, 0.0, 0.0, 0.0,
-0.5, 0.5, 0.5, 1.0,
-1.0, 0.0, 0.0, 0.0,
-0.5, -0.5, -0.5, 1.0,
-1.0, 0.0, 0.0, 0.0,
// RIGHT
0.5, 0.5, 0.5, 1.0,
1.0, 0.0, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0,
1.0, 0.0, 0.0, 0.0,
0.5, -0.5, 0.5, 1.0,
1.0, 0.0, 0.0, 0.0,
0.5, 0.5, 0.5, 1.0,
1.0, 0.0, 0.0, 0.0,
0.5, 0.5, -0.5, 1.0,
1.0, 0.0, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0,
1.0, 0.0, 0.0, 0.0,
];
fn create_instance(window: &Window, entry: &Entry) -> Instance {
@ -94,7 +202,7 @@ fn find_pdev_dgpu(instance: &Instance) -> vk::PhysicalDevice {
// Fix.
println!(
"Found discrete GPU: {}",
str::from_utf8(std::mem::transmute(props.device_name.as_slice())).unwrap()
std::str::from_utf8(std::mem::transmute(props.device_name.as_slice())).unwrap()
);
return pdevs.remove(i);
}
@ -327,7 +435,12 @@ fn setup_desc_layout(dev: &Device) -> vk::DescriptorSetLayout {
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
.descriptor_count(1)
.stage_flags(vk::ShaderStageFlags::VERTEX);
let layouts = [storage_binding];
let image_binding = vk::DescriptorSetLayoutBinding::default()
.binding(1)
.descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
.descriptor_count(1)
.stage_flags(vk::ShaderStageFlags::FRAGMENT);
let layouts = [storage_binding, image_binding];
let layout_info = vk::DescriptorSetLayoutCreateInfo::default().bindings(&layouts);
let layout = unsafe {
@ -441,11 +554,11 @@ fn setup_shader_stage(
let vert_stage = vk::PipelineShaderStageCreateInfo::default()
.stage(vk::ShaderStageFlags::VERTEX)
.module(vert_shader)
.name(CStr::from_bytes_with_nul(b"main\0").unwrap());
.name(c"main");
let frag_stage = vk::PipelineShaderStageCreateInfo::default()
.stage(vk::ShaderStageFlags::FRAGMENT)
.module(frag_shader)
.name(CStr::from_bytes_with_nul(b"main\0").unwrap());
.name(c"main");
[vert_stage, frag_stage]
}
@ -462,7 +575,7 @@ fn setup_pipeline(
.topology(vk::PrimitiveTopology::TRIANGLE_LIST);
let rasterization = vk::PipelineRasterizationStateCreateInfo::default()
.polygon_mode(vk::PolygonMode::FILL)
.cull_mode(vk::CullModeFlags::BACK)
.cull_mode(vk::CullModeFlags::NONE)
.front_face(vk::FrontFace::CLOCKWISE)
.line_width(1.0);
let multisample = vk::PipelineMultisampleStateCreateInfo::default()
@ -568,8 +681,8 @@ fn setup_swapchain(
.image_format(format.format)
.image_color_space(format.color_space)
.image_extent(vk::Extent2D {
width: std::cmp::max(caps.current_extent.width, width),
height: std::cmp::max(caps.current_extent.height, height),
width: cmp::min(cmp::max(caps.current_extent.width, width), MAX_WIDTH),
height: cmp::min(cmp::max(caps.current_extent.height, height), MAX_HEIGHT),
})
.image_array_layers(1)
.image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT)
@ -589,10 +702,14 @@ fn setup_swapchain(
}
fn setup_desc_pool(dev: &Device) -> vk::DescriptorPool {
let pool_size = vk::DescriptorPoolSize::default()
let pool_size_storage = vk::DescriptorPoolSize::default()
.ty(vk::DescriptorType::STORAGE_BUFFER)
.descriptor_count(1);
let pool_sizes = [pool_size];
let pool_size_image = vk::DescriptorPoolSize::default()
.ty(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
.descriptor_count(1);
let pool_sizes = [pool_size_storage, pool_size_image];
let pool_info = vk::DescriptorPoolCreateInfo::default()
.max_sets(1)
.pool_sizes(&pool_sizes);
@ -706,7 +823,13 @@ fn make_desc_sets(dev: &Device, desc_pool: &vk::DescriptorPool) -> Vec<vk::Descr
sets
}
fn write_desc_sets(dev: &Device, desc_sets: &Vec<vk::DescriptorSet>, mesh_buf: &vk::Buffer) {
fn write_desc_sets(
dev: &Device,
desc_sets: &Vec<vk::DescriptorSet>,
mesh_buf: &vk::Buffer,
image_view: vk::ImageView,
skybox_sampler: vk::Sampler
) {
let buf_info = vk::DescriptorBufferInfo::default()
.buffer(*mesh_buf)
.offset(0)
@ -718,8 +841,21 @@ fn write_desc_sets(dev: &Device, desc_sets: &Vec<vk::DescriptorSet>, mesh_buf: &
.dst_array_element(0)
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
.buffer_info(&buf_infos);
let img_info = vk::DescriptorImageInfo::default()
.image_layout(vk::ImageLayout::GENERAL)
.image_view(image_view)
.sampler(skybox_sampler);
let img_infos = &[img_info];
let img_desc = vk::WriteDescriptorSet::default()
.dst_set(desc_sets[0])
.dst_binding(1)
.dst_array_element(0)
.descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
.image_info(img_infos);
unsafe {
dev.update_descriptor_sets(&[buf_desc], &[]);
dev.update_descriptor_sets(&[buf_desc, img_desc], &[]);
}
}
@ -782,6 +918,8 @@ fn record_commands(
pipe: &vk::Pipeline,
desc_sets: &Vec<vk::DescriptorSet>,
camera: &Camera,
skybox_buffer: &vk::Buffer,
skybox_image: &vk::Image,
) {
let clear_vals = [
vk::ClearValue {
@ -808,6 +946,30 @@ fn record_commands(
.clear_values(&clear_vals);
unsafe {
let regions = (0..6)
.map(|i| {
vk::BufferImageCopy::default()
.buffer_offset(3 * 2048 * 2048 * i)
.buffer_row_length(0)
.buffer_image_height(0)
.image_offset(vk::Offset3D::default())
.image_extent(vk::Extent3D::default().width(2048).height(2048).depth(1))
.image_subresource(
vk::ImageSubresourceLayers::default()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0)
.layer_count(1)
.base_array_layer(i as u32),
)
})
.collect::<Vec<_>>();
dev.cmd_copy_buffer_to_image(
*cmd_buf,
*skybox_buffer,
*skybox_image,
vk::ImageLayout::GENERAL,
&regions,
);
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(
@ -874,6 +1036,9 @@ fn record_commands(
48,
base_color.as_ref(),
);
dev.cmd_draw(*cmd_buf, 36, 1, 0, 0);
dev.cmd_end_render_pass(*cmd_buf);
}
@ -953,65 +1118,56 @@ struct Camera {
rotation: Vector3,
}
fn handle_key(keycode: Keycode, camera: &mut Camera) {
let mov_scale = 0.05;
let rot_scale = 0.05;
fn handle_cont_key(keycode: Keycode, camera: &mut Camera, mouse: &MouseUtil) {
match keycode {
Keycode::W => {
camera.origin.x -= -camera.rotation.y.sin() * mov_scale;
camera.origin.z -= camera.rotation.y.cos() * mov_scale;
camera.origin.x -= -camera.rotation.y.sin() * MOV_STEP;
camera.origin.z -= camera.rotation.y.cos() * MOV_STEP;
}
Keycode::S => {
camera.origin.x += -camera.rotation.y.sin() * mov_scale;
camera.origin.z += camera.rotation.y.cos() * mov_scale;
camera.origin.x += -camera.rotation.y.sin() * MOV_STEP;
camera.origin.z += camera.rotation.y.cos() * MOV_STEP;
}
Keycode::A => {
camera.origin.x += camera.rotation.y.cos() * mov_scale;
camera.origin.z += camera.rotation.y.sin() * mov_scale;
camera.origin.x += camera.rotation.y.cos() * MOV_STEP;
camera.origin.z += camera.rotation.y.sin() * MOV_STEP;
}
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;
camera.origin.z -= camera.rotation.y.sin() * MOV_STEP;
camera.origin.x -= camera.rotation.y.cos() * MOV_STEP;
}
Keycode::Space => {
camera.origin.y += mov_scale;
camera.origin.y += MOV_STEP;
}
Keycode::LShift => {
camera.origin.y -= mov_scale;
camera.origin.y -= MOV_STEP;
}
_ => {}
}
}
fn decode_rif(raw: &[u8]) -> &[u8] {
&raw[17..]
}
fn main() {
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let mouse = sdl_context.mouse();
let mut width = 1024;
let mut height = 768;
let max_width = 3440;
let max_height = 1440;
let window = video_subsystem
let mut window = video_subsystem
.window(APP_NAME, width, height)
.vulkan()
.resizable()
.build()
.unwrap();
// We start in relative move
mouse.set_relative_mouse_mode(true);
let entry = Entry::linked();
let instance = create_instance(&window, &entry);
@ -1043,7 +1199,11 @@ fn main() {
let mesh_mem = mem_alloc(&dev, host_visible_inx, MESH_SIZE);
// Max viewport size is 3440x1440
let depth_mem = mem_alloc(&dev, host_invisible_inx, max_width * max_height * 8);
let depth_mem = mem_alloc(
&dev,
host_invisible_inx,
(MAX_WIDTH * MAX_HEIGHT * 8) as u64,
);
let mut depth_img = make_depth_img(
&dev,
@ -1066,6 +1226,75 @@ fn main() {
std::ptr::copy(POSITIONS.as_ptr(), mesh_mem as *mut f32, POSITIONS.len());
}
let (skybox_image, skybox_image_view, skybox_sampler) = {
let qf_idxs = [rcs_queue_inx];
let create_info = vk::ImageCreateInfo::default()
.flags(ImageCreateFlags::CUBE_COMPATIBLE)
.image_type(vk::ImageType::TYPE_2D)
.format(vk::Format::R8G8B8_UNORM)
.extent(vk::Extent3D::default().width(2048).height(2048).depth(1))
.mip_levels(1)
.array_layers(6)
.samples(vk::SampleCountFlags::TYPE_1)
.tiling(vk::ImageTiling::OPTIMAL)
.usage(vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::SAMPLED)
.sharing_mode(vk::SharingMode::EXCLUSIVE)
.initial_layout(vk::ImageLayout::UNDEFINED)
.queue_family_indices(&qf_idxs);
let image =
unsafe { dev.create_image(&create_info, None) }.expect("Failed to create image");
let skybox_mem_size: vk::MemoryRequirements = unsafe {dev.get_image_memory_requirements(image)};
let skybox_dev_mem = mem_alloc(&dev, host_invisible_inx, skybox_mem_size.size);
unsafe {
dev.bind_image_memory(image, skybox_dev_mem, 0).expect("Failed to bind image memory");
}
let create_info = vk::ImageViewCreateInfo::default()
.image(image)
.view_type(vk::ImageViewType::CUBE)
.format(vk::Format::R8G8B8_UNORM)
.components(vk::ComponentMapping::default())
.subresource_range(
vk::ImageSubresourceRange::default()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.base_mip_level(0)
.level_count(1)
.base_array_layer(0)
.layer_count(6),
);
let image_view = unsafe { dev.create_image_view(&create_info, None) }
.expect("Failed to create image view");
let create_info = vk::SamplerCreateInfo::default()
.mag_filter(vk::Filter::LINEAR)
.min_filter(vk::Filter::LINEAR)
.mipmap_mode(vk::SamplerMipmapMode::LINEAR)
.address_mode_u(vk::SamplerAddressMode::CLAMP_TO_EDGE)
.address_mode_v(vk::SamplerAddressMode::CLAMP_TO_EDGE)
.address_mode_w(vk::SamplerAddressMode::CLAMP_TO_EDGE)
.max_anisotropy(1.0)
.max_lod(1.0)
.border_color(vk::BorderColor::FLOAT_OPAQUE_WHITE);
let sampler =
unsafe { dev.create_sampler(&create_info, None) }.expect("Failed to create sampler");
(image, image_view, sampler)
};
let skybox_mem = mem_alloc(&dev, host_visible_inx, 3 * 2048 * 2048 * 6);
let skybox_buf = alloc_buf(
&dev,
&skybox_mem,
3 * 2048 * 2048 * 6,
vk::BufferUsageFlags::TRANSFER_SRC,
);
let skybox_ptr = buf_to_ptr(&dev, &skybox_mem, &skybox_buf);
let img = std::fs::read("resources/skybox.rif").unwrap();
let data = decode_rif(&img);
unsafe {
std::ptr::copy(data.as_ptr(), skybox_ptr as *mut u8, data.len());
}
let vert_shader_bin = std::fs::read("shaders/vert.spv").unwrap();
let frag_shader_bin = std::fs::read("shaders/frag.spv").unwrap();
@ -1124,7 +1353,7 @@ fn main() {
let desc_sets = make_desc_sets(&dev, &desc_pool);
write_desc_sets(&dev, &desc_sets, &mesh_buf);
write_desc_sets(&dev, &desc_sets, &mesh_buf, skybox_image_view, skybox_sampler);
let sem_avail = make_sem(&dev);
let sem_finish = make_sem(&dev);
@ -1146,6 +1375,7 @@ fn main() {
let mut running = true;
while running {
let now = Instant::now();
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. } => running = false,
@ -1156,10 +1386,11 @@ fn main() {
width = w as u32;
height = h as u32;
unsafe {
dev.device_wait_idle().expect("Failed to wait for device idle");
dev.device_wait_idle()
.expect("Failed to wait for device idle");
swapchain_loader.destroy_swapchain(swapchain, None);
}
(swapchain, extents) = setup_swapchain(
(swapchain, _) = setup_swapchain(
&pdev,
&dev,
&surface,
@ -1183,13 +1414,37 @@ fn main() {
framebufs =
make_framebufs(&dev, &swap_views, &depth_view, &pass, width, height);
}
// We do this key here and not in `handle_cont_key()` because we don't want key
// repeat, just a single press
Event::KeyDown {
keycode: Some(keycode),
keycode: Some(Keycode::ESCAPE),
repeat: false,
..
} => handle_key(keycode, &mut camera),
} => {
mouse.set_relative_mouse_mode(!mouse.relative_mouse_mode());
}
Event::MouseMotion {
window_id,
xrel,
yrel,
..
} if mouse.relative_mouse_mode() => {
// We only wanna do movement if the mouse is in relative mode (ie. its pinned to
// the center of the window and hidden)
camera.rotation.y -= xrel as f32 * ROT_MOUSE_SCALE;
camera.rotation.x -= yrel as f32 * ROT_MOUSE_SCALE;
mouse.warp_mouse_in_window(&window, width as i32 / 2, height as i32 / 2);
}
_ => {}
}
}
event_pump
.keyboard_state()
.pressed_scancodes()
.filter_map(Keycode::from_scancode)
.for_each(|k| handle_cont_key(k, &mut camera, &mouse));
wait_for_fence(&dev, &fence_flight);
reset_fence(&dev, &fence_flight);
@ -1214,6 +1469,8 @@ fn main() {
&pipe,
&desc_sets,
&camera,
&skybox_buf,
&skybox_image,
);
end_cmd_buf(&dev, &cmd_buf);
@ -1227,5 +1484,9 @@ fn main() {
);
queue_present(&swapchain_loader, &queue, &swapchain, img_inx, &sem_finish);
let elapsed = now.elapsed();
let delay = (1_000_000u128 / 60).saturating_sub(elapsed.as_micros());
thread::sleep(Duration::from_micros(delay as u64));
}
}

Loading…
Cancel
Save