diff --git a/Cargo.toml b/Cargo.toml index 20f7c40..29f6512 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,5 @@ shade_runner = "0.1.2" shaderc = "0.5.0" cgmath = "0.17" winit = "0.19" +image = "0.22.0" +tobj = "0.1.8" \ No newline at end of file diff --git a/shaders/triangle.frag b/shaders/triangle.frag index 447bbcd..6fe3cef 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -5,5 +5,5 @@ layout(location = 0) in vec3 pos; layout(location = 0) out vec4 f_color; void main() { - f_color = vec4(pos, 1.0); + f_color = vec4(.3, .1, .8, 1.0); } \ No newline at end of file diff --git a/shaders/triangle.vert b/shaders/triangle.vert index c6849e2..55fc202 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -1,10 +1,11 @@ #version 450 +#extension GL_ARB_separate_shader_objects : enable layout(location = 0) in vec3 position; layout(location = 0) out vec3 pos; -layout(push_constant) uniform push_constants { +layout(push_constant) uniform PushConstants { float time; mat4 model; mat4 view; @@ -12,6 +13,6 @@ layout(push_constant) uniform push_constants { } push; void main() { - gl_Position = push.projection * push.view * push.model * vec4(position + vec3(sin(push.time / 10.), 0., 0.), 1.0); + gl_Position = push.projection * push.view * push.model * vec4(position, 1.0); pos = gl_Position.xyz; } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index b344805..c281468 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,10 @@ use crate::vulkan::{Vertex, GameData}; use winit::{Event, WindowEvent, ElementState}; use std::time::SystemTime; use std::iter::FromIterator; -use cgmath::{Matrix4, SquareMatrix, Rad, Point3, Vector3}; +use cgmath::{Matrix4, SquareMatrix, Rad, Point3, Vector3, Deg}; mod vulkan; +use vulkan::vs::ty::PushConstants; const PRINT_KEYBOARD_INPUT: bool = false; @@ -40,29 +41,40 @@ impl GameData<'_> { fn update_push_constants(self: &mut Self) { self.push_constants.time = self.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0; - self.push_constants.model = Matrix4::identity(); - self.push_constants.view = Matrix4::look_at(Point3::new(f32::sin(self.push_constants.time), 0.0, f32::cos(self.push_constants.time)), Point3::new(0.0, 0.0, 0.0), Vector3::new(0.0, 1.0, 0.0)); - self.push_constants.projection = cgmath::perspective(Rad(std::f32::consts::FRAC_PI_2), self.aspect_ratio, 0.01, 100.0); + + let model = Matrix4::from_angle_z(Rad::from(Deg(self.push_constants.time * 100.0))); + + let view = Matrix4::look_at( + Point3::new(2.0, 2.0, 2.0), + Point3::new(0.0, 0.0, 0.0), + Vector3::new(0.0, 0.0, 1.0) + ); + + let mut proj = cgmath::perspective( + Rad::from(Deg(45.0)), + self.aspect_ratio, + 0.1, + 10.0 + ); + + proj.y.y *= -1.0; + + self.push_constants.model = model.into(); + self.push_constants.view = view.into(); + self.push_constants.projection = proj.into(); } } -#[derive(Debug, Clone, Copy)] -pub struct PushConstants { - pub time: f32, - pub model: Matrix4, - pub view: Matrix4, - pub projection: Matrix4, -} - fn main() { - let mut whatever = String::new(); - std::io::stdin().read_line(&mut whatever).unwrap(); +// let mut whatever = String::new(); +// std::io::stdin().read_line(&mut whatever).unwrap(); let mut pc = PushConstants { time: 0.0, - model: Matrix4::identity(), - view: Matrix4::identity(), - projection: Matrix4::identity() + _dummy0: [0; 12], + model: Matrix4::identity().into(), + view: Matrix4::identity().into(), + projection: Matrix4::identity().into(), }; let data = GameData { diff --git a/src/vulkan.rs b/src/vulkan.rs index 0d99ae5..b60392c 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -298,11 +298,11 @@ pub fn init(mut game: GameData) { Err(err) => panic!("{:?}", err) }; + game.update_push_constants(); + // Specify the color to clear the framebuffer with i.e. blue let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into(), 1f32.into()); - game.update_push_constants(); - // In order to draw, we have to build a *command buffer*. The command buffer object holds // the list of commands that are going to be executed. // @@ -409,6 +409,20 @@ fn window_size_dependent_setup(device: Arc, images: &[Arc>() } +pub mod vs { + vulkano_shaders::shader!{ + ty: "vertex", + path: "shaders/triangle.vert" + } +} + +pub mod fs { + vulkano_shaders::shader! { + ty: "fragment", + path: "shaders/triangle.frag" + } +} + fn create_pipeline(device: Arc, sub_pass: Subpass>, vertex_shader_path: &str, fragment_shader_path: &str, is_line: bool) -> Option, Box, Arc>>> { if let Some((shader, shader_data)) = read_shader(vertex_shader_path, fragment_shader_path) { let vertex_shader_entry; @@ -445,20 +459,13 @@ fn create_pipeline(device: Arc, sub_pass: Subpass .build(device.clone()) .unwrap()); } else { - // Before we draw we have to create what is called a pipeline. This is similar to an OpenGL - // program, but much more specific. pipeline = Arc::new(GraphicsPipeline::start() .vertex_input_single_buffer::() - // A Vulkan shader can in theory contain multiple entry points, so we have to specify - // which one. The `main` word of `main_entry_point` actually corresponds to the name of - // the entry point. .vertex_shader(vertex_shader_entry.clone(), ()) .triangle_list() - // Use a resizable viewport set to draw over the entire window .viewports_dynamic_scissors_irrelevant(1) + .depth_stencil_simple_depth() .fragment_shader(fragment_shader_entry.clone(), ()) - // We have to indicate which subpass of which render pass this pipeline is going to be used - // in. The pipeline will only be usable from this particular subpass. .render_pass(sub_pass.clone()) .build(device.clone()) .unwrap());