update UBOs
This commit is contained in:
@@ -14,12 +14,9 @@ layout(location = 0) out vec2 tex_coords;
|
|||||||
|
|
||||||
layout(push_constant) uniform PushConstants {
|
layout(push_constant) uniform PushConstants {
|
||||||
mat4 model;
|
mat4 model;
|
||||||
mat4 view;
|
|
||||||
mat4 projection;
|
|
||||||
float time;
|
|
||||||
} push;
|
} push;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = push.projection * push.view * push.model * vec4(position, 1.0);
|
gl_Position = ubo.projection * ubo.view * push.model * vec4(position, 1.0);
|
||||||
tex_coords = uv;
|
tex_coords = uv;
|
||||||
}
|
}
|
||||||
29
src/main.rs
29
src/main.rs
@@ -2,7 +2,8 @@ use winit::{Event};
|
|||||||
use cgmath::{Matrix4, Rad, Vector3, Deg, Quaternion, Rotation3, One, Rotation};
|
use cgmath::{Matrix4, Rad, Vector3, Deg, Quaternion, Rotation3, One, Rotation};
|
||||||
|
|
||||||
mod vulkan;
|
mod vulkan;
|
||||||
use crate::vulkan::{Game, LinePoint, GameObject, VulkanRenderer, RenderLoopResult, MeshHandle, GameObjectHandle};
|
use crate::vulkan::{Game, LinePoint, GameObject, VulkanRenderer, RenderResult, MeshHandle, GameObjectHandle};
|
||||||
|
use crate::vulkan::vs::ty::UniformBufferObject;
|
||||||
|
|
||||||
mod input;
|
mod input;
|
||||||
use crate::input::{InputState};
|
use crate::input::{InputState};
|
||||||
@@ -41,12 +42,9 @@ impl TestGame {
|
|||||||
println!("Game loaded!");
|
println!("Game loaded!");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(self: &mut Self, renderer: &mut VulkanRenderer) {
|
fn update(self: &mut Self, renderer: &mut VulkanRenderer) -> UniformBufferObject {
|
||||||
self.input.frame_start();
|
self.input.frame_start();
|
||||||
|
let time = (renderer.game_data.start_time.elapsed().unwrap().as_micros() as f64 / 1000000.0) as f32;
|
||||||
let new_time = (renderer.game_data.start_time.elapsed().unwrap().as_micros() as f64 / 1000000.0) as f32;
|
|
||||||
// let frame_time = new_time - renderer.game_data.uniform_buffers.iter().map(|ubo| ubo.time).max_by(|a,b| if a > b {Ordering::Greater} else {Ordering::Less} ).unwrap();
|
|
||||||
// renderer.uniform_buffers.iter_mut().for_each(|ubo| ubo.time = new_time);
|
|
||||||
|
|
||||||
// User interaction
|
// User interaction
|
||||||
if self.input.button_just_released("quit") {
|
if self.input.button_just_released("quit") {
|
||||||
@@ -85,14 +83,16 @@ impl TestGame {
|
|||||||
|
|
||||||
proj.y.y *= -1.0;
|
proj.y.y *= -1.0;
|
||||||
|
|
||||||
renderer.game_data.push_constants.view = view.into();
|
|
||||||
renderer.game_data.push_constants.projection = proj.into();
|
|
||||||
// renderer.uniform_buffers.iter_mut().for_each(|ubo| ubo.view = view.into());
|
|
||||||
// renderer.uniform_buffers.iter_mut().for_each(|ubo| ubo.projection = proj.into());
|
|
||||||
renderer.game_data.line_push_constants.view = view.into();
|
renderer.game_data.line_push_constants.view = view.into();
|
||||||
renderer.game_data.line_push_constants.projection = proj.into();
|
renderer.game_data.line_push_constants.projection = proj.into();
|
||||||
|
|
||||||
self.input.frame_end();
|
self.input.frame_end();
|
||||||
|
|
||||||
|
UniformBufferObject {
|
||||||
|
view: view.into(),
|
||||||
|
projection: proj.into(),
|
||||||
|
time,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,12 +123,13 @@ fn main() {
|
|||||||
game.game_start(&mut renderer);
|
game.game_start(&mut renderer);
|
||||||
|
|
||||||
let mut continue_rendering = true;
|
let mut continue_rendering = true;
|
||||||
|
let mut ubo = game.update(&mut renderer);
|
||||||
|
|
||||||
while continue_rendering {
|
while continue_rendering {
|
||||||
match renderer.render_loop(&mut game) {
|
match renderer.render_loop(&mut game, ubo) {
|
||||||
RenderLoopResult::Ok => game.update(&mut renderer),
|
RenderResult::Ok => ubo = game.update(&mut renderer),
|
||||||
RenderLoopResult::Reload => println!("Render loop reloaded..."),
|
RenderResult::Reload => println!("Render loop reloaded..."),
|
||||||
RenderLoopResult::Quit => continue_rendering = false,
|
RenderResult::Quit => continue_rendering = false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,6 @@ use shaderc;
|
|||||||
use vs::ty::PushConstants;
|
use vs::ty::PushConstants;
|
||||||
use line_vs::ty::LinePushConstants;
|
use line_vs::ty::LinePushConstants;
|
||||||
use crate::mesh::{CPUMesh};
|
use crate::mesh::{CPUMesh};
|
||||||
use crate::vulkan::RenderLoopResult::Quit;
|
|
||||||
|
|
||||||
use image::{ImageFormat, ConvertBuffer, ImageBuffer, Rgb, Rgba};
|
use image::{ImageFormat, ConvertBuffer, ImageBuffer, Rgb, Rgba};
|
||||||
|
|
||||||
@@ -113,7 +112,8 @@ pub struct VulkanRenderer {
|
|||||||
pub descriptor_sets: Vec<FixedGraphicsDescriptorSet>,
|
pub descriptor_sets: Vec<FixedGraphicsDescriptorSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum RenderLoopResult {
|
pub enum RenderResult {
|
||||||
|
/// Contains buffer index and swapchain future
|
||||||
Ok,
|
Ok,
|
||||||
Reload,
|
Reload,
|
||||||
Quit,
|
Quit,
|
||||||
@@ -123,10 +123,7 @@ impl VulkanRenderer {
|
|||||||
pub fn init(line_vertices: Vec<LinePoint>, enable_validation_layers: bool) -> VulkanRenderer {
|
pub fn init(line_vertices: Vec<LinePoint>, enable_validation_layers: bool) -> VulkanRenderer {
|
||||||
let mut data = GameData {
|
let mut data = GameData {
|
||||||
push_constants: PushConstants {
|
push_constants: PushConstants {
|
||||||
time: 0.0,
|
|
||||||
model: Matrix4::identity().into(),
|
model: Matrix4::identity().into(),
|
||||||
view: Matrix4::identity().into(),
|
|
||||||
projection: Matrix4::identity().into(),
|
|
||||||
},
|
},
|
||||||
line_push_constants: LinePushConstants {
|
line_push_constants: LinePushConstants {
|
||||||
model: Matrix4::identity().into(),
|
model: Matrix4::identity().into(),
|
||||||
@@ -334,35 +331,32 @@ impl VulkanRenderer {
|
|||||||
recreate_swapchain: false, debug_callback, previous_frame_end }
|
recreate_swapchain: false, debug_callback, previous_frame_end }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_command_buffers(self: &mut Self) -> Vec<Arc<AutoCommandBuffer>> {
|
fn create_command_buffer(self: &mut Self, fb_index: usize, ubo: vs::ty::UniformBufferObject) -> Arc<AutoCommandBuffer> {
|
||||||
let mut buffers = Vec::new();
|
let mut cbb = AutoCommandBufferBuilder::primary_simultaneous_use(self.device.clone(), self.queue.family()).unwrap()
|
||||||
for fb_index in 0..self.framebuffers.len() {
|
.update_buffer(self.uniform_buffers[fb_index].clone(), ubo).unwrap()
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary_simultaneous_use(self.device.clone(), self.queue.family()).unwrap()
|
.begin_render_pass(self.framebuffers[fb_index].clone(), false, vec![ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap();
|
||||||
.update_buffer(self.uniform_buffers[fb_index].clone(), vs::ty::UniformBufferObject { view: Matrix4::identity().into(), projection: Matrix4::identity().into(), time: 0.0 }).unwrap()
|
|
||||||
.begin_render_pass(self.framebuffers[fb_index].clone(), false, vec![ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap();
|
|
||||||
|
|
||||||
for i in 0..self.game_data.game_objects.len() {
|
for i in 0..self.game_data.game_objects.len() {
|
||||||
let game_object = &self.game_data.game_objects[i];
|
let game_object = &self.game_data.game_objects[i];
|
||||||
let mesh = &self.game_data.meshes[game_object.mesh_index];
|
let mesh = &self.game_data.meshes[game_object.mesh_index];
|
||||||
self.game_data.push_constants.model = game_object.model_matrix.into();
|
self.game_data.push_constants.model = game_object.model_matrix.into();
|
||||||
cbb = cbb.draw_indexed(
|
cbb = cbb.draw_indexed(
|
||||||
self.pipeline.clone(),
|
self.pipeline.clone(),
|
||||||
&self.dynamic_state,
|
&self.dynamic_state,
|
||||||
vec![mesh.vertex_buffer.clone()],
|
vec![mesh.vertex_buffer.clone()],
|
||||||
mesh.index_buffer.clone(),
|
mesh.index_buffer.clone(),
|
||||||
self.descriptor_sets[fb_index].clone(),
|
self.descriptor_sets[fb_index].clone(),
|
||||||
self.game_data.push_constants.clone()).unwrap()
|
self.game_data.push_constants.clone()).unwrap()
|
||||||
}
|
|
||||||
|
|
||||||
cbb = cbb.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap()
|
|
||||||
.end_render_pass().unwrap();
|
|
||||||
|
|
||||||
buffers.push(Arc::new(cbb.build().unwrap()));
|
|
||||||
}
|
}
|
||||||
buffers
|
|
||||||
|
cbb = cbb.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap()
|
||||||
|
.end_render_pass().unwrap();
|
||||||
|
|
||||||
|
Arc::new(cbb.build().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_loop(self: &mut Self, game: &mut dyn Game) -> RenderLoopResult {
|
/// Returns false if rendering should stop
|
||||||
|
pub fn render_loop(self: &mut Self, game: &mut dyn Game, new_ubo: vs::ty::UniformBufferObject) -> RenderResult {
|
||||||
// It is important to call this function from time to time, otherwise resources will keep
|
// It is important to call this function from time to time, otherwise resources will keep
|
||||||
// accumulating and you will eventually reach an out of memory error.
|
// accumulating and you will eventually reach an out of memory error.
|
||||||
// Calling this function polls various fences in order to determine what the GPU has
|
// Calling this function polls various fences in order to determine what the GPU has
|
||||||
@@ -384,7 +378,7 @@ impl VulkanRenderer {
|
|||||||
// Simply restarting the loop is the easiest way to fix this issue.
|
// Simply restarting the loop is the easiest way to fix this issue.
|
||||||
Err(SwapchainCreationError::UnsupportedDimensions) => {
|
Err(SwapchainCreationError::UnsupportedDimensions) => {
|
||||||
println!("Swapchain rejected: UnsupportedDimensions");
|
println!("Swapchain rejected: UnsupportedDimensions");
|
||||||
return RenderLoopResult::Reload;
|
return RenderResult::Reload;
|
||||||
}
|
}
|
||||||
Err(err) => panic!("{:?}", err),
|
Err(err) => panic!("{:?}", err),
|
||||||
};
|
};
|
||||||
@@ -414,20 +408,20 @@ impl VulkanRenderer {
|
|||||||
//
|
//
|
||||||
// This function can block if no image is available. The parameter is an optional timeout
|
// This function can block if no image is available. The parameter is an optional timeout
|
||||||
// after which the function call will return an error.
|
// after which the function call will return an error.
|
||||||
let (image_num, acquire_future) = match swapchain::acquire_next_image(self.swapchain.clone(), None) {
|
let (fb_index, acquire_future) = match swapchain::acquire_next_image(self.swapchain.clone(), None) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(AcquireError::OutOfDate) => {
|
Err(AcquireError::OutOfDate) => {
|
||||||
self.recreate_swapchain = true;
|
self.recreate_swapchain = true;
|
||||||
return RenderLoopResult::Reload;
|
return RenderResult::Reload;
|
||||||
},
|
},
|
||||||
Err(err) => panic!("{:?}", err)
|
Err(err) => panic!("{:?}", err)
|
||||||
};
|
};
|
||||||
|
|
||||||
let command_buffer = self.create_command_buffers()[image_num].clone();
|
let command_buffer = self.create_command_buffer(fb_index, new_ubo).clone();
|
||||||
|
|
||||||
let future = self.previous_frame_end.take().unwrap().join(acquire_future)
|
let future = self.previous_frame_end.take().unwrap().join(acquire_future)
|
||||||
.then_execute(self.queue.clone(), command_buffer).unwrap()
|
.then_execute(self.queue.clone(), command_buffer).unwrap()
|
||||||
.then_swapchain_present(self.queue.clone(), self.swapchain.clone(), image_num)
|
.then_swapchain_present(self.queue.clone(), self.swapchain.clone(), fb_index)
|
||||||
.then_signal_fence_and_flush();
|
.then_signal_fence_and_flush();
|
||||||
|
|
||||||
match future {
|
match future {
|
||||||
@@ -463,9 +457,9 @@ impl VulkanRenderer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if resized { self.recreate_swapchain = true }
|
if resized { self.recreate_swapchain = true }
|
||||||
if self.game_data.shutdown || window_closed { return Quit; }
|
if self.game_data.shutdown || window_closed { return RenderResult::Quit; }
|
||||||
|
|
||||||
RenderLoopResult::Ok
|
RenderResult::Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upload_mesh(self: &mut Self, mesh: CPUMesh) -> usize {
|
pub fn upload_mesh(self: &mut Self, mesh: CPUMesh) -> usize {
|
||||||
|
|||||||
Reference in New Issue
Block a user