camera: fix camera movement
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 8m11s
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 8m11s
This commit is contained in:
parent
f835941432
commit
998aa68da1
10 changed files with 83 additions and 103 deletions
|
@ -1,5 +1,12 @@
|
||||||
# Project
|
# Project
|
||||||
|
|
||||||
|
Run renderdoc on wayland:
|
||||||
|
|
||||||
|
```console
|
||||||
|
WAYLAND_DISPLAY= QT_QPA_PLATFORM=xcb qrenderdoc
|
||||||
|
```
|
||||||
|
> Not supported yet https://github.com/baldurk/renderdoc/issues/853
|
||||||
|
|
||||||
## Usefull links
|
## Usefull links
|
||||||
|
|
||||||
- https://vulkan-tutorial.com/fr/Introduction
|
- https://vulkan-tutorial.com/fr/Introduction
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
libxkbcommon
|
libxkbcommon
|
||||||
wayland
|
wayland
|
||||||
libGL
|
libGL
|
||||||
|
|
||||||
# Xorg
|
# Xorg
|
||||||
xorg.libX11
|
xorg.libX11
|
||||||
xorg.libXcursor
|
xorg.libXcursor
|
||||||
|
@ -64,7 +65,7 @@
|
||||||
++ packages;
|
++ packages;
|
||||||
|
|
||||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
||||||
VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d:${pkgs.renderdoc}/share/vulkan/implicit_layer.d";
|
VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d";
|
||||||
RUST_LOG = "debug,rust_vulkan_test=trace";
|
RUST_LOG = "debug,rust_vulkan_test=trace";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
|
|
@ -65,6 +65,7 @@ impl ApplicationHandler for App {
|
||||||
renderer.swapchain_format(),
|
renderer.swapchain_format(),
|
||||||
GuiConfig {
|
GuiConfig {
|
||||||
is_overlay: true,
|
is_overlay: true,
|
||||||
|
allow_srgb_render_target: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -132,7 +133,9 @@ impl ApplicationHandler for App {
|
||||||
self.scene_manager.load_scene_if_not_loaded(&scene_context);
|
self.scene_manager.load_scene_if_not_loaded(&scene_context);
|
||||||
|
|
||||||
if let Some(scene) = self.scene_manager.current_scene_mut() {
|
if let Some(scene) = self.scene_manager.current_scene_mut() {
|
||||||
scene.update(&scene_context);
|
if let Err(e) = scene.update(&scene_context) {
|
||||||
|
log::error!("Error updating scene: {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
let acquire_future = renderer.acquire(None, |_| {}).unwrap();
|
let acquire_future = renderer.acquire(None, |_| {}).unwrap();
|
||||||
let acquire_future = scene.render(
|
let acquire_future = scene.render(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{f32::consts::PI, sync::Arc};
|
use std::{f32::consts::FRAC_PI_2, sync::Arc};
|
||||||
|
|
||||||
use glam::{Mat4, Quat, Vec3};
|
use glam::{Mat4, Vec3, Vec4};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
Validated,
|
Validated,
|
||||||
buffer::{AllocateBufferError, Subbuffer},
|
buffer::{AllocateBufferError, Subbuffer},
|
||||||
|
@ -13,7 +13,6 @@ use super::mvp::MVP;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
view: Mat4,
|
|
||||||
projection: Mat4,
|
projection: Mat4,
|
||||||
|
|
||||||
position: Vec3,
|
position: Vec3,
|
||||||
|
@ -21,9 +20,8 @@ pub struct Camera {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
pub fn new(view: Mat4, projection: Mat4) -> Self {
|
pub fn new(projection: Mat4) -> Self {
|
||||||
Self {
|
Self {
|
||||||
view,
|
|
||||||
projection,
|
projection,
|
||||||
position: Vec3::ZERO,
|
position: Vec3::ZERO,
|
||||||
rotation: Vec3::ZERO,
|
rotation: Vec3::ZERO,
|
||||||
|
@ -45,43 +43,57 @@ impl Camera {
|
||||||
0.0,
|
0.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.rotation.x > 90.0 {
|
if self.rotation.x > FRAC_PI_2 {
|
||||||
self.rotation = Vec3::new(90.0, self.rotation.y, 0.0);
|
self.rotation = Vec3::new(FRAC_PI_2, self.rotation.y, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.rotation.x < -90.0 {
|
if self.rotation.x < -FRAC_PI_2 {
|
||||||
self.rotation = Vec3::new(-90.0, self.rotation.y, 0.0);
|
self.rotation = Vec3::new(-FRAC_PI_2, self.rotation.y, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let movement_delta = movement_speed * timer.delta_time();
|
let movement_delta = movement_speed * timer.delta_time();
|
||||||
|
|
||||||
|
let (yaw_sin, yaw_cos) = self.rotation.y.sin_cos();
|
||||||
|
let forward = Vec3::new(yaw_cos, 0.0, yaw_sin).normalize();
|
||||||
|
let right = Vec3::new(-yaw_sin, 0.0, yaw_cos).normalize();
|
||||||
|
|
||||||
let tx = input_manager.get_virtual_input_state("move_right") * movement_delta;
|
let tx = input_manager.get_virtual_input_state("move_right") * movement_delta;
|
||||||
|
self.position += tx * right;
|
||||||
|
|
||||||
let tz = input_manager.get_virtual_input_state("move_forward") * movement_delta;
|
let tz = input_manager.get_virtual_input_state("move_forward") * movement_delta;
|
||||||
|
self.position += tz * forward;
|
||||||
self.position.x += tx * (self.rotation.y).cos();
|
|
||||||
self.position.z += tx * (self.rotation.y).sin();
|
|
||||||
|
|
||||||
self.position.x += tz * (self.rotation.y + PI / 2.0).cos();
|
|
||||||
self.position.z += tz * (self.rotation.y + PI / 2.0).sin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_projection(&mut self, projection: Mat4) {
|
pub fn set_projection(&mut self, projection: Mat4) {
|
||||||
self.projection = projection;
|
self.projection = projection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_position(&self) -> Vec3 {
|
||||||
|
self.position
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_rotation(&self) -> Vec3 {
|
||||||
|
self.rotation
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_buffer(
|
pub fn create_buffer(
|
||||||
&self,
|
&self,
|
||||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||||
) -> Result<Subbuffer<[MVP]>, Validated<AllocateBufferError>> {
|
) -> Result<Subbuffer<[MVP]>, Validated<AllocateBufferError>> {
|
||||||
let mut world_matrix = Mat4::IDENTITY;
|
let (sin_pitch, cos_pitch) = self.rotation.x.sin_cos();
|
||||||
world_matrix *= Mat4::from_quat(Quat::from_euler(
|
let (sin_yaw, cos_yaw) = self.rotation.y.sin_cos();
|
||||||
glam::EulerRot::XYX,
|
|
||||||
self.rotation.x,
|
|
||||||
self.rotation.y,
|
|
||||||
self.rotation.z,
|
|
||||||
));
|
|
||||||
world_matrix *= Mat4::from_translation(self.position);
|
|
||||||
|
|
||||||
MVP::new(&world_matrix, &self.view, &self.projection).into_buffer(memory_allocator)
|
let view_matrix = Mat4::look_to_rh(
|
||||||
|
self.position,
|
||||||
|
Vec3::new(cos_pitch * cos_yaw, sin_pitch, cos_pitch * sin_yaw).normalize(),
|
||||||
|
Vec3::Y,
|
||||||
|
);
|
||||||
|
|
||||||
|
MVP {
|
||||||
|
model: Mat4::IDENTITY.to_cols_array_2d(),
|
||||||
|
view: view_matrix.to_cols_array_2d(),
|
||||||
|
projection: self.projection.to_cols_array_2d(),
|
||||||
|
}
|
||||||
|
.into_buffer(memory_allocator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,20 +10,12 @@ use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, Standar
|
||||||
#[derive(BufferContents, Clone, Copy)]
|
#[derive(BufferContents, Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct MVP {
|
pub struct MVP {
|
||||||
world: [[f32; 4]; 4],
|
pub model: [[f32; 4]; 4],
|
||||||
view: [[f32; 4]; 4],
|
pub view: [[f32; 4]; 4],
|
||||||
projection: [[f32; 4]; 4],
|
pub projection: [[f32; 4]; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MVP {
|
impl MVP {
|
||||||
pub fn new(world: &Mat4, view: &Mat4, projection: &Mat4) -> Self {
|
|
||||||
Self {
|
|
||||||
world: world.to_cols_array_2d(),
|
|
||||||
view: view.to_cols_array_2d(),
|
|
||||||
projection: projection.to_cols_array_2d(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_buffer(
|
pub fn into_buffer(
|
||||||
self,
|
self,
|
||||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
use std::sync::Arc;
|
use vulkano::buffer::BufferContents;
|
||||||
use vulkano::Validated;
|
|
||||||
use vulkano::buffer::{
|
|
||||||
AllocateBufferError, Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer,
|
|
||||||
};
|
|
||||||
use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator};
|
|
||||||
use vulkano::pipeline::graphics::vertex_input::Vertex;
|
use vulkano::pipeline::graphics::vertex_input::Vertex;
|
||||||
|
|
||||||
#[derive(BufferContents, Vertex)]
|
#[derive(BufferContents, Vertex)]
|
||||||
|
@ -15,24 +10,3 @@ pub struct Vertex2D {
|
||||||
#[format(R32G32_SFLOAT)]
|
#[format(R32G32_SFLOAT)]
|
||||||
pub uv: [f32; 2],
|
pub uv: [f32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex2D {
|
|
||||||
pub fn create_buffer(
|
|
||||||
vertices: Vec<Vertex2D>,
|
|
||||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
|
||||||
) -> Result<Subbuffer<[Vertex2D]>, Validated<AllocateBufferError>> {
|
|
||||||
Buffer::from_iter(
|
|
||||||
memory_allocator.clone(),
|
|
||||||
BufferCreateInfo {
|
|
||||||
usage: BufferUsage::VERTEX_BUFFER,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
AllocationCreateInfo {
|
|
||||||
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
|
|
||||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
vertices,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,7 +14,9 @@ impl SceneManager {
|
||||||
pub fn load_scene_if_not_loaded(&mut self, scene_context: &SceneContext) {
|
pub fn load_scene_if_not_loaded(&mut self, scene_context: &SceneContext) {
|
||||||
if let Some(current_scene) = self.current_scene.as_mut() {
|
if let Some(current_scene) = self.current_scene.as_mut() {
|
||||||
if !current_scene.loaded() {
|
if !current_scene.loaded() {
|
||||||
current_scene.load(scene_context);
|
if let Err(e) = current_scene.load(scene_context) {
|
||||||
|
log::error!("Error loading scene: {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ pub use manager::SceneManager;
|
||||||
|
|
||||||
pub trait Scene {
|
pub trait Scene {
|
||||||
fn loaded(&self) -> bool;
|
fn loaded(&self) -> bool;
|
||||||
fn load(&mut self, scene_context: &SceneContext);
|
fn load(&mut self, scene_context: &SceneContext) -> Result<(), Box<dyn Error>>;
|
||||||
fn update(&mut self, scene_context: &SceneContext);
|
fn update(&mut self, scene_context: &SceneContext) -> Result<(), Box<dyn Error>>;
|
||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
image_view: &Arc<ImageView>,
|
image_view: &Arc<ImageView>,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::core::render::texture::Texture;
|
||||||
use crate::core::scene::Scene;
|
use crate::core::scene::Scene;
|
||||||
use crate::core::scene::SceneContext;
|
use crate::core::scene::SceneContext;
|
||||||
use egui_winit_vulkano::{Gui, egui};
|
use egui_winit_vulkano::{Gui, egui};
|
||||||
use glam::{Mat4, Vec3};
|
use glam::Mat4;
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
command_buffer::{
|
command_buffer::{
|
||||||
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract,
|
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract,
|
||||||
|
@ -36,48 +36,36 @@ impl Scene for MainScene {
|
||||||
self.state.is_some()
|
self.state.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(&mut self, scene_context: &SceneContext) {
|
fn load(&mut self, scene_context: &SceneContext) -> Result<(), Box<dyn Error>> {
|
||||||
let square = Square::new(
|
let square = Square::new(
|
||||||
&scene_context.device,
|
&scene_context.device,
|
||||||
&scene_context.memory_allocator,
|
&scene_context.memory_allocator,
|
||||||
scene_context.swapchain_format,
|
scene_context.swapchain_format,
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let camera = Camera::new(
|
let camera = Camera::new(Mat4::perspective_rh_gl(
|
||||||
Mat4::look_at_rh(
|
std::f32::consts::FRAC_PI_2,
|
||||||
Vec3::new(0.3, 0.3, 1.0),
|
scene_context.aspect_ratio,
|
||||||
Vec3::new(0.0, 0.0, 0.0),
|
0.01,
|
||||||
Vec3::new(0.0, -1.0, 0.0),
|
1000.0,
|
||||||
),
|
));
|
||||||
Mat4::perspective_rh_gl(
|
|
||||||
std::f32::consts::FRAC_PI_2,
|
|
||||||
scene_context.aspect_ratio,
|
|
||||||
0.01,
|
|
||||||
100.0,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut uploads = AutoCommandBufferBuilder::primary(
|
let mut uploads = AutoCommandBufferBuilder::primary(
|
||||||
scene_context.command_buffer_allocator.clone(),
|
scene_context.command_buffer_allocator.clone(),
|
||||||
scene_context.graphics_queue.queue_family_index(),
|
scene_context.graphics_queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let texture = Texture::from_file(
|
let texture = Texture::from_file(
|
||||||
&scene_context.device,
|
&scene_context.device,
|
||||||
&scene_context.memory_allocator,
|
&scene_context.memory_allocator,
|
||||||
&mut uploads,
|
&mut uploads,
|
||||||
"res/textures/wooden-crate.jpg",
|
"res/textures/wooden-crate.jpg",
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let _ = uploads
|
let _ = uploads
|
||||||
.build()
|
.build()?
|
||||||
.unwrap()
|
.execute(scene_context.graphics_queue.clone())?;
|
||||||
.execute(scene_context.graphics_queue.clone())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
self.state = Some(MainSceneState {
|
self.state = Some(MainSceneState {
|
||||||
square,
|
square,
|
||||||
|
@ -85,10 +73,12 @@ impl Scene for MainScene {
|
||||||
texture,
|
texture,
|
||||||
speed: 50.0,
|
speed: 50.0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, scene_context: &SceneContext) {
|
fn update(&mut self, scene_context: &SceneContext) -> Result<(), Box<dyn Error>> {
|
||||||
let state = self.state.as_mut().unwrap();
|
let state = self.state.as_mut().ok_or("State not found")?;
|
||||||
state.camera.update(
|
state.camera.update(
|
||||||
&scene_context.input_manager,
|
&scene_context.input_manager,
|
||||||
&scene_context.timer,
|
&scene_context.timer,
|
||||||
|
@ -96,12 +86,7 @@ impl Scene for MainScene {
|
||||||
10.0,
|
10.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
state.camera.set_projection(Mat4::perspective_rh_gl(
|
Ok(())
|
||||||
std::f32::consts::FRAC_PI_2,
|
|
||||||
scene_context.aspect_ratio,
|
|
||||||
0.01,
|
|
||||||
100.0,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
|
@ -111,7 +96,7 @@ impl Scene for MainScene {
|
||||||
scene_context: &SceneContext,
|
scene_context: &SceneContext,
|
||||||
gui: &mut Gui,
|
gui: &mut Gui,
|
||||||
) -> Result<Box<dyn GpuFuture>, Box<dyn Error>> {
|
) -> Result<Box<dyn GpuFuture>, Box<dyn Error>> {
|
||||||
let state = self.state.as_ref().unwrap();
|
let state = self.state.as_ref().ok_or("State not found")?;
|
||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
scene_context.command_buffer_allocator.clone(),
|
scene_context.command_buffer_allocator.clone(),
|
||||||
|
@ -174,6 +159,12 @@ impl Scene for MainScene {
|
||||||
"Delta time: {:?}",
|
"Delta time: {:?}",
|
||||||
scene_context.timer.delta_time()
|
scene_context.timer.delta_time()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
ui.label(format!(
|
||||||
|
"Position: {:?}, Rotation: {:?}",
|
||||||
|
state.camera.get_position(),
|
||||||
|
state.camera.get_rotation()
|
||||||
|
));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ fn main() {
|
||||||
vec![
|
vec![
|
||||||
VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyW), AxisDirection::Normal),
|
VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyW), AxisDirection::Normal),
|
||||||
VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyS), AxisDirection::Invert),
|
VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyS), AxisDirection::Invert),
|
||||||
VirtualBinding::Axis(0, AxisDirection::Normal, 0.0),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -29,7 +28,6 @@ fn main() {
|
||||||
vec![
|
vec![
|
||||||
VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyD), AxisDirection::Normal),
|
VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyD), AxisDirection::Normal),
|
||||||
VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyA), AxisDirection::Invert),
|
VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyA), AxisDirection::Invert),
|
||||||
VirtualBinding::Axis(1, AxisDirection::Normal, 0.0),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue