diff --git a/shaders/text.frag b/shaders/text.frag index 3050a76..fbc98ab 100644 --- a/shaders/text.frag +++ b/shaders/text.frag @@ -5,7 +5,7 @@ layout(push_constant) uniform PushConstants { mat4 model; } push; -layout(binding = 0) uniform ObjectUniformData { +layout(binding = 0, set = 0) uniform ObjectUniformData { mat4 view; mat4 projection; mat4 ortho_projection; @@ -15,7 +15,7 @@ layout(binding = 0) uniform ObjectUniformData { vec3 camera_position; } ubo; -layout(binding = 1) uniform sampler2D diffuse_tex; +layout(binding = 1, set = 0) uniform sampler2D diffuse_tex; layout(location = 0) in vec2 tex_coords; diff --git a/shaders/text.vert b/shaders/text.vert index 0858bf9..99a9784 100644 --- a/shaders/text.vert +++ b/shaders/text.vert @@ -5,7 +5,7 @@ layout(push_constant) uniform PushConstants { mat4 model; } push; -layout(binding = 0) uniform ObjectUniformData { +layout(binding = 0, set = 0) uniform ObjectUniformData { mat4 view; mat4 projection; mat4 ortho_projection; diff --git a/shaders/triangle.frag b/shaders/triangle.frag index 1a717f9..6ba975f 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -6,7 +6,7 @@ layout(push_constant) uniform PushConstants { bool is_selected; } push; -layout(binding = 0) uniform ObjectUniformData { +layout(binding = 0, set = 0) uniform ObjectUniformData { mat4 view; mat4 projection; mat4 ortho_projection; @@ -16,7 +16,7 @@ layout(binding = 0) uniform ObjectUniformData { vec3 camera_position; } ubo; -layout(binding = 1) uniform sampler2D diffuse_tex; +layout(binding = 1, set = 0) uniform sampler2D diffuse_tex; layout(binding = 2) uniform sampler2D normal_tex; layout(location = 0) in vec2 tex_coords; diff --git a/shaders/triangle.vert b/shaders/triangle.vert index 999ae1e..f7183ef 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -6,7 +6,7 @@ layout(push_constant) uniform PushConstants { bool is_selected; } push; -layout(binding = 0) uniform ObjectUniformData { +layout(binding = 0, set = 0) uniform ObjectUniformData { mat4 view; mat4 projection; mat4 ortho_projection; diff --git a/src/game/entities.rs b/src/game/entities.rs index 177b8eb..b289c42 100644 --- a/src/game/entities.rs +++ b/src/game/entities.rs @@ -1,6 +1,6 @@ use cgmath::{Vector4, vec4}; -use crate::{input::InputState, text::{create_text_object, update_text}, vulkan::{MeshHandle, PERF_COUNTER_SIZE, VulkanRenderer, gameobject::{GameObject, GameObjectHandle, Updatable}, mesh::{CPUMesh, CPUVertexList}}}; +use crate::{input::InputState, text::{create_text_object, update_text}, vulkan::{MeshHandle, PERF_COUNTER_SIZE, TextVertex, VulkanRenderer, gameobject::{GameObject, GameObjectHandle, Updatable}, mesh::{CPUMesh, CPUVertexList}}}; use super::{GameState, TestGame}; @@ -9,9 +9,9 @@ pub struct FpsCounter { } impl FpsCounter { - pub fn new(game: &mut TestGame, renderer: &mut VulkanRenderer) -> Box { + pub fn new(game: &mut TestGame, renderer: &mut VulkanRenderer) -> FpsCounter { let text_mesh = create_text_object(&mut game.game_state.brush, renderer, "", 30.); - Box::new(FpsCounter { game_object: game.add_game_object(renderer, text_mesh) }) + FpsCounter { game_object: game.add_game_object(renderer, text_mesh) } } } @@ -38,8 +38,13 @@ pub struct UiQuad { impl UiQuad { pub fn new(game: &mut TestGame, renderer: &mut VulkanRenderer) -> UiQuad { - let quad_verts = vec![]; - let cpu_mesh = CPUMesh { vertices: CPUVertexList::Vertex3D(quad_verts), indices: vec![0, 1, 2, 1, 3, 2], local_texture_index: None, local_normal_map_index: None, name: None }; + let quad_verts = vec![ + TextVertex { position: [0., 0., 0.], uv: [0., 0.] }, + TextVertex { position: [0., 1., 0.], uv: [0., 1.] }, + TextVertex { position: [1., 0., 0.], uv: [1., 0.] }, + TextVertex { position: [1., 1., 0.], uv: [1., 1.] }, + ]; + let cpu_mesh = CPUMesh { vertices: CPUVertexList::VertexText(quad_verts), indices: vec![0, 1, 2, 1, 3, 2], local_texture_index: None, local_normal_map_index: None, name: None }; let mesh_index = renderer.upload_mesh(cpu_mesh, None); let mesh_handle = MeshHandle { index: mesh_index, @@ -54,6 +59,6 @@ impl UiQuad { impl Updatable for UiQuad { fn update(&mut self, delta_time: f32, input: &InputState, game_state: &mut GameState, game_objects: &mut Vec, renderer: &mut VulkanRenderer) { - todo!() + } } \ No newline at end of file diff --git a/src/game/mod.rs b/src/game/mod.rs index 06e38c7..00a1a74 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -6,7 +6,7 @@ use winit::event::Event; use level::{load_level, save_level}; use player::Player; -use crate::game::entities::FpsCounter; +use crate::game::entities::{FpsCounter, UiQuad}; use crate::text::create_brush; use crate::{config::LogConfig, vulkan}; use crate::input::InputState; @@ -149,7 +149,10 @@ impl TestGame { load_level("levels/test.lvl", self, renderer).unwrap(); let fps = FpsCounter::new(self, renderer); - self.components.push(fps); + self.components.push(Box::new(fps)); + + let test_quad = UiQuad::new(self, renderer); + self.components.push(Box::new(test_quad)); println!("Game loaded!"); } diff --git a/src/vulkan/gameobject.rs b/src/vulkan/gameobject.rs index dd001ea..728fe04 100644 --- a/src/vulkan/gameobject.rs +++ b/src/vulkan/gameobject.rs @@ -17,7 +17,7 @@ pub struct GameObject { pub rotation: Quaternion, pub scale: Vector3, pub children: Vec, - pub descriptor_sets: Vec>, + pub descriptor_sets: Vec>>, pub is_selected: bool, pub pipeline_index: usize, pub visible: bool, @@ -31,7 +31,7 @@ impl GameObject { } pub fn init_descriptor_sets(&mut self, renderer: &mut VulkanRenderer) { - self.descriptor_sets = renderer.pipelines[self.pipeline_index].create_descriptor_set(&self.textures, renderer); + self.descriptor_sets = renderer.pipelines[self.pipeline_index].create_descriptor_sets(&self.textures, renderer); } pub fn _set_position(&mut self, x: f32, y: f32, z: f32) { diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 6496b8d..2e5e77d 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -218,8 +218,8 @@ impl VulkanRenderer { let type_str = match (msg.severity.error, msg.severity.warning, msg.severity.information, msg.severity.verbose) { (true, _, _, _) => "!!", (_, true, _, _) => "!", - (_, _, _, true) => "i", - _ => " " + (_, _, true, _) => "i", + _ => "v" }; let layer_str = msg.layer_prefix; @@ -228,7 +228,7 @@ impl VulkanRenderer { }).ok(); } - // TODO: Just get the first physical device we find, it's fiiiine... + // TODO: Create device selector let physical = PhysicalDevice::enumerate(&instance).next().unwrap(); println!("Using device: {} (type: {:?})", physical.name(), physical.ty()); @@ -236,14 +236,11 @@ impl VulkanRenderer { let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap(); let window = surface.window(); - // TODO: Tutorial says we need more queues - // In a real-life application, we would probably use at least a graphics queue and a transfers - // queue to handle data transfers in parallel. In this example we only use one queue. + // Queue let queue_family = physical.queue_families().find(|&q| { q.supports_graphics() && surface.is_supported(q).unwrap_or(false) }).unwrap(); - // Queue let device_ext = DeviceExtensions { khr_swapchain: true, ..DeviceExtensions::none() }; let (device, mut queues) = Device::new(physical, physical.supported_features(), &device_ext, [(queue_family, 0.5)].iter().cloned()).unwrap(); diff --git a/src/vulkan/pipelines.rs b/src/vulkan/pipelines.rs index f7b8148..38ac76a 100644 --- a/src/vulkan/pipelines.rs +++ b/src/vulkan/pipelines.rs @@ -1,6 +1,6 @@ use std::{convert::TryInto, io::{self, ErrorKind, Read, Write}, path::PathBuf, sync::Arc}; -use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{DescriptorSet, descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::{shader::{ShaderModule}}}; +use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{DescriptorSet, descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet, pipeline_layout::PipelineLayoutDesc}, pipeline::{shader::{ShaderModule}}}; use vulkano::command_buffer::DynamicState; use vulkano::device::Device; use vulkano::framebuffer::RenderPassAbstract; @@ -22,7 +22,7 @@ type DS = Arc; pub trait Drawcall { fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState); - fn create_descriptor_set(self: &Self, textures: &Vec, renderer: &VulkanRenderer) -> Vec; + fn create_descriptor_sets(self: &Self, textures: &Vec, renderer: &VulkanRenderer) -> Vec>; fn recreate_pipeline(self: &mut Self, device: Arc, render_pass: RP); fn get_pipeline(self: &Self) -> &GP; } @@ -155,24 +155,23 @@ impl Drawcall for DefaultShader { } } - fn create_descriptor_set(self: &Self, textures: &Vec, renderer: &VulkanRenderer) -> Vec { - let descriptor_set_layout = self.get_pipeline().descriptor_set_layout(0).unwrap().clone(); + fn create_descriptor_sets(self: &Self, textures: &Vec, renderer: &VulkanRenderer) -> Vec> { + let descriptor_set_layout_0 = self.get_pipeline().descriptor_set_layout(0).unwrap().clone(); renderer.uniform_buffers.iter().map(|uniform_buffer| { - let descriptor_set: Arc<(dyn vulkano::descriptor::DescriptorSet + std::marker::Send + std::marker::Sync + 'static)>; - let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone()); + let descriptor_set_0: Arc<(dyn vulkano::descriptor::DescriptorSet + std::marker::Send + std::marker::Sync + 'static)>; debug_assert!(textures.len() == 2, "Expected diffuse and normal map for object shader!"); let diffuse = &renderer.game_data.textures[textures[0]]; let normal_map = &renderer.game_data.textures[textures[1]]; - descriptor_set = Arc::new(builder + descriptor_set_0 = Arc::new(PersistentDescriptorSet::start(descriptor_set_layout_0.clone()) .add_buffer(uniform_buffer.clone()).unwrap() .add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap() .add_sampled_image(normal_map.image.clone(), normal_map.sampler.clone()).unwrap() .build().unwrap()); - descriptor_set + vec![descriptor_set_0] }).collect() } @@ -240,7 +239,7 @@ impl Drawcall for LineShader { game_data.line_push_constants.clone()).unwrap(); } - fn create_descriptor_set(self: &Self, _textures: &Vec, _renderer: &VulkanRenderer) -> Vec { + fn create_descriptor_sets(self: &Self, _textures: &Vec, _renderer: &VulkanRenderer) -> Vec> { vec![] } @@ -318,6 +317,10 @@ impl TextShader { .build(device.clone()) .unwrap()); + println!("{:?}", gp.descriptor(0, 0).unwrap().ty); + println!("{:?}", gp.descriptor(0, 1).unwrap().ty); + println!("{:?}", gp.descriptor(0, 2).unwrap().ty); // TODO: Why does this exist? + gp } } @@ -340,24 +343,27 @@ impl Drawcall for TextShader { } } - fn create_descriptor_set(self: &Self, textures: &Vec, renderer: &VulkanRenderer) -> Vec { + fn create_descriptor_sets(self: &Self, textures: &Vec, renderer: &VulkanRenderer) -> Vec> { let descriptor_set_layout = self.get_pipeline().descriptor_set_layout(0).unwrap().clone(); renderer.uniform_buffers.iter().map(|uniform_buffer| { let descriptor_set: Arc<(dyn vulkano::descriptor::DescriptorSet + std::marker::Send + std::marker::Sync + 'static)>; let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone()); - debug_assert!(textures.len() == 1, "Expected only diffuse map for text shader!"); - let diffuse = &renderer.game_data.textures[textures[0]]; - println!("Using diffuse image with size {:?}", diffuse.image.dimensions()); + let diffuse_index = match textures.len() { + 0 => 0, + 1 => textures[0], + _ => panic!("Expected only diffuse map for text shader!"), + }; + let diffuse = &renderer.game_data.textures[diffuse_index]; descriptor_set = Arc::new(builder .add_buffer(uniform_buffer.clone()).unwrap() .add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap() - .add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap() + .add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap() // TODO: delet this .build().unwrap()); - descriptor_set + vec![descriptor_set] }).collect() }