diff --git a/Cargo.lock b/Cargo.lock index 47ae214..e264b69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -961,18 +961,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", @@ -1181,6 +1181,7 @@ dependencies = [ "log", "png", "pretty_env_logger", + "serde", "thiserror", "tobj", "vulkanalia", diff --git a/Cargo.toml b/Cargo.toml index 277b5cc..4d2f700 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,5 @@ pretty_env_logger = "0.5" thiserror = "1" tobj = { version = "3", features = ["log"] } vulkanalia = { version = "=0.23.0", features = ["libloading", "provisional", "window"] } -winit = "0.29" \ No newline at end of file +winit = "0.29" +serde = { version = "1.0", features = ["derive"] } \ No newline at end of file diff --git a/shaders/geo.spv b/shaders/geo.spv index bae4fb5..1419149 100644 Binary files a/shaders/geo.spv and b/shaders/geo.spv differ diff --git a/shaders/shader.geom b/shaders/shader.geom index 3b3223e..ce74298 100644 --- a/shaders/shader.geom +++ b/shaders/shader.geom @@ -1,7 +1,7 @@ #version 450 layout(points) in; -layout(triangle_strip, max_vertices=24) out; +layout(triangle_strip, max_vertices=12) out; layout(binding = 0) uniform UniformBufferObject { mat4 model; @@ -16,137 +16,164 @@ layout(location = 1) in vec2 geoTexCoord[]; layout(location = 0) out vec3 fragColor; layout(location = 1) out vec2 fragTexCoord; +bool ignore_scalars = false; + void main () { mat4 geom_rotation = ubo.geom_rot; //back - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + vec4 normal_back = geom_rotation * vec4(0, 0, -1, 0); + float scalar_back = dot(normal_back, vec4(1, 0, 0, 0)); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + if (scalar_back <= 0 || ignore_scalars){ + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); - EndPrimitive(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } //front - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + vec4 normal_front = geom_rotation * vec4(0, 0, 1, 0); + float scalar_front = dot(normal_front, vec4(1, 0, 0, 0)); + if (scalar_front <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); - - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); - EndPrimitive(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } //up - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + vec4 normal_up = geom_rotation * vec4(0, 1, 0, 0); + float scalar_up = dot(normal_up, vec4(1, 0, 0, 0)); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + if (scalar_up <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); - EndPrimitive(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } //down - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + vec4 normal_down = geom_rotation * vec4(0, -1, 0, 0); + float scalar_down = dot(normal_down, vec4(1, 0, 0, 0)); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + if (scalar_down <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); - EndPrimitive(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } //left - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + vec4 normal_left = geom_rotation * vec4(-1, 0, 0, 0); + float scalar_left = dot(normal_left, vec4(1, 0, 0, 0)); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + if (scalar_left <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); - EndPrimitive(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } //right - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + vec4 normal_right = geom_rotation * vec4(1, 0, 0, 0); + float scalar_right = dot(normal_right, vec4(1, 0, 0, 0)); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + if (scalar_right <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); - gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0)); - fragColor = geoColor[0]; - fragTexCoord = geoTexCoord[0]; - EmitVertex(); - EndPrimitive(); + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e9c167b..251f9d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ use vulkanalia::prelude::v1_0::*; use vulkanalia::Version; use vulkanalia::bytecode::Bytecode; +use core::time; use std::collections::HashSet; use std::ffi::CStr; use std::os::raw::c_void; @@ -27,7 +28,7 @@ use vulkanalia::vk::ExtDebugUtilsExtension; use vulkanalia::vk::KhrSurfaceExtension; use vulkanalia::vk::KhrSwapchainExtension; -use cgmath::{vec2, vec3, SquareMatrix}; +use cgmath::{vec2, vec3, Matrix, SquareMatrix}; use std::mem::size_of; use std::ptr::copy_nonoverlapping as memcpy; @@ -50,7 +51,9 @@ const VALIDATION_ENABLED: bool = const VALIDATION_LAYER: vk::ExtensionName = vk::ExtensionName::from_bytes(b"VK_LAYER_KHRONOS_validation"); -const DEVICE_EXTENSIONS: &[vk::ExtensionName] = &[vk::KHR_SWAPCHAIN_EXTENSION.name]; +const DEVICE_EXTENSIONS: &[vk::ExtensionName] = &[ + vk::KHR_SWAPCHAIN_EXTENSION.name +]; const MAX_FRAMES_IN_FLIGHT: usize = 2; @@ -112,6 +115,15 @@ fn main() -> Result<()> { if event.logical_key == "w" { app.cur_pos += app.view_direction * 0.1; } + if event.logical_key == "s" { + app.cur_pos -= app.view_direction * 0.1; + } + if event.logical_key == "a" { + app.cur_pos -= app.view_direction.cross(vertex::Vec3::new(0.0, 0.0, 1.0)) * 0.1; + } + if event.logical_key == "d" { + app.cur_pos += app.view_direction.cross(vertex::Vec3::new(0.0, 0.0, 1.0)) * 0.1; + } }, _ => {} } @@ -152,11 +164,38 @@ impl App { vertex::Vertex::new(vec3(8.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), vec2(0.0, 0.0)) ); data.indices.push(0); + data.vertices.push( vertex::Vertex::new(vec3(-8.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0), vec2(0.0, 0.0)) ); data.indices.push(1); + data.vertices.push( + vertex::Vertex::new(vec3(0.0, 8.0, 0.0), vec3(1.0, 1.0, 0.0), vec2(0.0, 0.0)) + ); + data.indices.push(2); + + data.vertices.push( + vertex::Vertex::new(vec3(0.0, -8.0, 0.0), vec3(0.0, 1.0, 1.0), vec2(0.0, 0.0)) + ); + data.indices.push(3); + + let grid_size = 1000; + for x_index in -grid_size..grid_size { + for y_index in -grid_size..grid_size { + if !(((x_index as i32).abs() == 8 && y_index == 0) || (x_index == 0 && (y_index as i32).abs() == 8)){ + let index = data.indices.len(); + let vert = vertex::Vertex::new( + vec3(x_index as f32, y_index as f32, 0.0), + vec3(0.0, 1.0, 0.0), + vec2(0.0, 0.0) + ); + data.vertices.push(vert); + data.indices.push(index as u32); + } + } + } + let instance = create_instance(window, &entry, &mut data)?; data.surface = vk_window::create_surface(&instance, &window, &window)?; pick_physical_device(&instance, &mut data)?; @@ -200,6 +239,7 @@ impl App { /// Renders a frame for our Vulkan app. unsafe fn render(&mut self, window: &Window) -> Result<()> { + let start_time = Instant::now(); let in_flight_fence = self.data.in_flight_fences[self.frame]; self.device.wait_for_fences(&[in_flight_fence], true, u64::MAX)?; @@ -259,6 +299,7 @@ impl App { self.frame = (self.frame + 1) % MAX_FRAMES_IN_FLIGHT; + println!("{}", 1000000.0 / start_time.elapsed().as_micros() as f32); Ok(()) } @@ -362,7 +403,7 @@ impl App { let rot_mat = cgmath::Matrix3::from_angle_y(cgmath::Deg(-self.cam_angle_y)) * cgmath::Matrix3::from_angle_z(cgmath::Deg(self.cam_angle_x)); let rot_mat4 = cgmath::Matrix4::from_angle_y(cgmath::Deg(-self.cam_angle_y)) * cgmath::Matrix4::from_angle_z(cgmath::Deg(self.cam_angle_x)); - self.view_direction = rot_mat * vertex::Vec3::new(1.0, 0.0, 0.0); + self.view_direction = rot_mat.transpose() * vertex::Vec3::new(1.0, 0.0, 0.0); let model = cgmath::Matrix4::from_translation( cgmath::Point3::new(0.0, 0.0, 0.0) - self.cur_pos ); let view = buffer::Mat4::look_to_rh( @@ -385,7 +426,7 @@ impl App { cgmath::Deg(45.0), self.data.swapchain_extent.width as f32 / self.data.swapchain_extent.height as f32, 0.1, - 10.0, + 10000.0, ); let ubo = buffer::UniformBufferObject { model, geom_rot: rot_mat4, view, proj }; @@ -415,7 +456,7 @@ unsafe fn create_instance(window: &Window, entry: &Entry, data: &mut app_data::A .application_version(vk::make_version(1, 0, 0)) .engine_name(b"No Engine\0") .engine_version(vk::make_version(1, 0, 0)) - .api_version(vk::make_version(1, 0, 0)); + .api_version(vk::make_version(1, 1, 0)); // Validation layers @@ -562,6 +603,10 @@ unsafe fn check_physical_device_extensions( if DEVICE_EXTENSIONS.iter().all(|e| extensions.contains(e)) { Ok(()) } else { + let missing = DEVICE_EXTENSIONS.iter().filter(|e| !extensions.contains(e)).collect::>(); + for missing_extension in missing { + println!("Missing extension: {}", missing_extension); + } Err(anyhow!(errors::SuitabilityError("Missing required device extensions."))) } }