diff --git a/shaders/compile.bat b/shaders/compile.bat index a8d7348..39e1fb0 100644 --- a/shaders/compile.bat +++ b/shaders/compile.bat @@ -1,2 +1,3 @@ C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/shader.vert -o shaders/vert.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/shader.frag -o shaders/frag.spv \ No newline at end of file +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/shader.frag -o shaders/frag.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/shader.geom -o shaders/geo.spv \ No newline at end of file diff --git a/shaders/frag.spv b/shaders/frag.spv index 9495412..1ebe140 100644 Binary files a/shaders/frag.spv and b/shaders/frag.spv differ diff --git a/shaders/geo.spv b/shaders/geo.spv new file mode 100644 index 0000000..bae4fb5 Binary files /dev/null and b/shaders/geo.spv differ diff --git a/shaders/shader.frag b/shaders/shader.frag index 87187fa..f53c648 100644 --- a/shaders/shader.frag +++ b/shaders/shader.frag @@ -7,5 +7,5 @@ layout(location = 0) out vec4 outColor; layout(binding = 1) uniform sampler2D texSampler; void main() { - outColor = texture(texSampler, fragTexCoord); + outColor = vec4(fragColor, 1); //texture(texSampler, fragTexCoord); } \ No newline at end of file diff --git a/shaders/shader.geom b/shaders/shader.geom new file mode 100644 index 0000000..3b3223e --- /dev/null +++ b/shaders/shader.geom @@ -0,0 +1,152 @@ +#version 450 + +layout(points) in; +layout(triangle_strip, max_vertices=24) out; + +layout(binding = 0) uniform UniformBufferObject { + mat4 model; + mat4 geom_rot; + mat4 view; + mat4 proj; +} ubo; + +layout(location = 0) in vec3 geoColor[]; +layout(location = 1) in vec2 geoTexCoord[]; + +layout(location = 0) out vec3 fragColor; +layout(location = 1) out vec2 fragTexCoord; + +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(); + + 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(); + + //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(); + + 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(); + + //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(); + + 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(); + + //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(); + + 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(); + + //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(); + + 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(); + + //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(); + + 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(); +} \ No newline at end of file diff --git a/shaders/shader.vert b/shaders/shader.vert index 4cda1bf..76bf4e0 100644 --- a/shaders/shader.vert +++ b/shaders/shader.vert @@ -2,6 +2,7 @@ layout(binding = 0) uniform UniformBufferObject { mat4 model; + mat4 geom_rot; mat4 view; mat4 proj; } ubo; @@ -11,11 +12,11 @@ layout(location = 0) in vec3 inPosition; layout(location = 1) in vec3 inColor; layout(location = 2) in vec2 inTexCoord; -layout(location = 0) out vec3 fragColor; -layout(location = 1) out vec2 fragTexCoord; +layout(location = 0) out vec3 geoColor; +layout(location = 1) out vec2 geoTexCoord; void main() { - gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0); - fragColor = inColor; - fragTexCoord = inTexCoord; + gl_Position = ubo.geom_rot * ubo.model * vec4(inPosition, 1.0); + geoColor = inColor; + geoTexCoord = inTexCoord; } \ No newline at end of file diff --git a/shaders/vert.spv b/shaders/vert.spv index 99280dc..308206e 100644 Binary files a/shaders/vert.spv and b/shaders/vert.spv differ diff --git a/src/buffer.rs b/src/buffer.rs index 051cea8..8f94ec2 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -176,6 +176,7 @@ pub unsafe fn create_index_buffer( #[derive(Copy, Clone, Debug)] pub struct UniformBufferObject { pub model: Mat4, + pub geom_rot: Mat4, pub view: Mat4, pub proj: Mat4, } @@ -188,7 +189,7 @@ pub unsafe fn create_descriptor_set_layout( .binding(0) .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER) .descriptor_count(1) - .stage_flags(vk::ShaderStageFlags::VERTEX); + .stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY); let sampler_binding = vk::DescriptorSetLayoutBinding::builder() .binding(1) diff --git a/src/main.rs b/src/main.rs index 3bb81d6..e9c167b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ use anyhow::{anyhow, Result}; use log::*; -use winit::dpi::LogicalSize; +use winit::dpi::{LogicalSize, LogicalPosition, PhysicalPosition}; use winit::event::{Event, WindowEvent}; use winit::event_loop::EventLoop; use winit::window::{Window, WindowBuilder}; @@ -27,7 +27,7 @@ use vulkanalia::vk::ExtDebugUtilsExtension; use vulkanalia::vk::KhrSurfaceExtension; use vulkanalia::vk::KhrSwapchainExtension; -use cgmath::vec3; +use cgmath::{vec2, vec3, SquareMatrix}; use std::mem::size_of; use std::ptr::copy_nonoverlapping as memcpy; @@ -64,6 +64,7 @@ fn main() -> Result<()> { .with_title("Vulkan Tutorial (Rust)") .with_inner_size(LogicalSize::new(1024, 768)) .build(&event_loop)?; + //window.set_cursor_visible(false); // App @@ -88,7 +89,30 @@ fn main() -> Result<()> { app.minimized = false; app.resized = true; } - } + }, + WindowEvent::CursorMoved { device_id, position } => { + let log_pos: LogicalPosition = position.to_logical(window.scale_factor()); + if app.last_pos.x != -1.0 { + app.cam_angle_x += ((log_pos.x - (window.inner_size().width as f32 / 2.0)) / (window.inner_size().width as f32)) * 180.0; + app.cam_angle_y += ((log_pos.y - (window.inner_size().height as f32 / 2.0)) / (window.inner_size().height as f32)) * 180.0; + + if app.cam_angle_x >= 360.0 { + app.cam_angle_x -= 360.0; + } + if app.cam_angle_x <= -360.0 { + app.cam_angle_x += 360.0; + } + app.cam_angle_y = app.cam_angle_y.max(-90.0).min(90.0); + } + + window.set_cursor_position(LogicalPosition::new(window.inner_size().width / 2, window.inner_size().height / 2)).expect("Cannot set Cursor!"); + app.last_pos = LogicalPosition::new(window.inner_size().width as f32 / 2 as f32, window.inner_size().height as f32 / 2 as f32); + }, + WindowEvent::KeyboardInput { device_id, event, is_synthetic } => { + if event.logical_key == "w" { + app.cur_pos += app.view_direction * 0.1; + } + }, _ => {} } _ => {} @@ -109,6 +133,11 @@ struct App { resized: bool, minimized: bool, start: Instant, + cam_angle_x: f32, + cam_angle_y: f32, + last_pos: LogicalPosition, + view_direction: vertex::Vec3, + cur_pos: cgmath::Point3, } impl App { @@ -117,7 +146,17 @@ impl App { let loader = LibloadingLoader::new(LIBRARY)?; let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?; let mut data = app_data::AppData::default(); - load_model::load_model(&mut data)?; + + //load_model::load_model(&mut data)?; + data.vertices.push( + 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); + let instance = create_instance(window, &entry, &mut data)?; data.surface = vk_window::create_surface(&instance, &window, &window)?; pick_physical_device(&instance, &mut data)?; @@ -151,7 +190,12 @@ impl App { create_sync_objects(&device, &mut data)?; - Ok(Self { entry, instance, data, device, frame: 0 , resized: false, minimized: false, start: Instant::now()}) + Ok(Self { entry, instance, data, device, frame: 0 , resized: false, minimized: false, start: Instant::now(), + cam_angle_x: 0.0, cam_angle_y: 0.0, + last_pos: LogicalPosition::new(-1 as f32, -1 as f32), + view_direction: vertex::Vec3::new(0.0, 0.0, 0.0), + cur_pos: cgmath::point3(0.0, 0.0, 0.0), + }) } /// Renders a frame for our Vulkan app. @@ -308,19 +352,25 @@ impl App { } - unsafe fn update_uniform_buffer(&self, image_index: usize) -> Result<()> { + unsafe fn update_uniform_buffer(&mut self, image_index: usize) -> Result<()> { let time = self.start.elapsed().as_secs_f32(); - let model = buffer::Mat4::from_axis_angle( - vec3(0.0, 0.0, 1.0), + /*let model = buffer::Mat4::from_axis_angle( + vec3(0.0, 1.0, 0.0), cgmath::Deg(90.0) * 0.0 //time - ); + );*/ - let view = buffer::Mat4::look_at_rh( - cgmath::point3(2.0, 2.0, 2.0), + 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); + 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( cgmath::point3(0.0, 0.0, 0.0), - vec3(0.0, 0.0, 1.0), + vertex::Vec3::new(1.0, 0.0, 0.0), + vertex::Vec3::new(0.0, 0.0, 1.0) ); + let correction = buffer::Mat4::new( //column major order, matrix looks transposed 1.0, 0.0, 0.0, 0.0, @@ -338,7 +388,7 @@ impl App { 10.0, ); - let ubo = buffer::UniformBufferObject { model, view, proj }; + let ubo = buffer::UniformBufferObject { model, geom_rot: rot_mat4, view, proj }; let memory = self.device.map_memory( self.data.uniform_buffers_memory[image_index], @@ -546,7 +596,8 @@ unsafe fn create_logical_device( }; let features = vk::PhysicalDeviceFeatures::builder() - .sampler_anisotropy(true); + .sampler_anisotropy(true) + .geometry_shader(true); let indices = queue_family_indices::QueueFamilyIndices::get(instance, data, data.physical_device)?; @@ -580,9 +631,11 @@ unsafe fn create_logical_device( unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Result<()> { let vert = include_bytes!("../shaders/vert.spv"); + let geo = include_bytes!("../shaders/geo.spv"); let frag = include_bytes!("../shaders/frag.spv"); let vert_shader_module = create_shader_module(device, &vert[..])?; + let geo_shader_module = create_shader_module(device, &geo[..])?; let frag_shader_module = create_shader_module(device, &frag[..])?; let vert_stage = vk::PipelineShaderStageCreateInfo::builder() @@ -590,6 +643,11 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu .module(vert_shader_module) .name(b"main\0"); + let geo_stage = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::GEOMETRY) + .module(geo_shader_module) + .name(b"main\0"); + let frag_stage = vk::PipelineShaderStageCreateInfo::builder() .stage(vk::ShaderStageFlags::FRAGMENT) .module(frag_shader_module) @@ -602,7 +660,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu .vertex_attribute_descriptions(&attribute_descriptions); let input_assembly_state = vk::PipelineInputAssemblyStateCreateInfo::builder() - .topology(vk::PrimitiveTopology::TRIANGLE_LIST) + .topology(vk::PrimitiveTopology::POINT_LIST) .primitive_restart_enable(false); let viewport = vk::Viewport::builder() @@ -668,7 +726,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu data.pipeline_layout = device.create_pipeline_layout(&layout_info, None)?; - let stages = &[vert_stage, frag_stage]; + let stages = &[vert_stage, geo_stage, frag_stage]; let info = vk::GraphicsPipelineCreateInfo::builder() .stages(stages) .vertex_input_state(&vertex_input_state) @@ -686,6 +744,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu vk::PipelineCache::null(), &[info], None)?.0[0]; device.destroy_shader_module(vert_shader_module, None); + device.destroy_shader_module(geo_shader_module, None); device.destroy_shader_module(frag_shader_module, None); Ok(()) diff --git a/src/vertex.rs b/src/vertex.rs index 8038561..78c8465 100644 --- a/src/vertex.rs +++ b/src/vertex.rs @@ -5,8 +5,8 @@ use std::mem::size_of; use cgmath; -type Vec2 = cgmath::Vector2; -type Vec3 = cgmath::Vector3; +pub type Vec2 = cgmath::Vector2; +pub type Vec3 = cgmath::Vector3; #[repr(C)] #[derive(Copy, Clone, Debug)]