vulkano_test/src/game/main_scene.rs
Florian RICHER 09bfe6fb48
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 8m5s
camera: Try fix camera
2025-05-27 23:31:23 +02:00

214 lines
6.6 KiB
Rust

use crate::core::input::InputManager;
use crate::core::render::pipelines::triangle_pipeline::create_triangle_pipeline;
use crate::core::render::primitives::camera::Camera;
use crate::core::render::primitives::vertex::Vertex2D;
use crate::core::render::render_context::RenderContext;
use crate::core::render::texture::Texture;
use crate::core::scene::Scene;
use crate::core::timer::Timer;
use glam::{Mat4, Vec3};
use std::sync::Arc;
use vulkano::buffer::Subbuffer;
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer,
PrimaryCommandBufferAbstract,
};
use vulkano::descriptor_set::{DescriptorSet, WriteDescriptorSet};
use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint};
const VERTICES: [Vertex2D; 4] = [
Vertex2D {
position: [0.0, 0.0],
uv: [0.0, 0.0],
},
Vertex2D {
position: [0.0, 5.0],
uv: [0.0, 0.5],
},
Vertex2D {
position: [10.0, 0.0],
uv: [1.0, 0.0],
},
Vertex2D {
position: [10.0, 5.0],
uv: [1.0, 0.5],
},
];
pub struct MainSceneState {
pipeline: Arc<GraphicsPipeline>,
vertex_buffer: Subbuffer<[Vertex2D]>,
camera: Camera,
texture: Texture,
speed: f32,
}
#[derive(Default)]
pub struct MainScene {
state: Option<MainSceneState>,
}
impl Scene for MainScene {
fn loaded(&self) -> bool {
self.state.is_some()
}
fn load(&mut self, render_context: &RenderContext) {
let pipeline =
create_triangle_pipeline(render_context.device(), render_context.swapchain_format())
.unwrap();
let vertex_buffer =
Vertex2D::create_buffer(Vec::from_iter(VERTICES), render_context.memory_allocator())
.unwrap();
let mut camera = Camera::new(
Mat4::look_at_rh(
Vec3::new(0.3, 0.3, 1.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, -1.0, 0.0),
),
Mat4::perspective_rh_gl(
std::f32::consts::FRAC_PI_2,
render_context.aspect_ratio(),
0.01,
100.0,
),
);
camera.set_position(Vec3::new(-10.0, 0.0, -10.0));
let mut uploads = AutoCommandBufferBuilder::primary(
render_context.command_buffer_allocator().clone(),
render_context.graphics_queue().queue_family_index(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
let texture = Texture::from_file(
render_context.device(),
render_context.memory_allocator(),
&mut uploads,
"res/textures/wooden-crate.jpg",
)
.unwrap();
let _ = uploads
.build()
.unwrap()
.execute(render_context.graphics_queue().clone())
.unwrap();
self.state = Some(MainSceneState {
pipeline,
vertex_buffer,
camera,
texture,
speed: 50.0,
});
}
fn update(
&mut self,
render_context: &RenderContext,
input_manager: &InputManager,
timer: &Timer,
) {
let state = self.state.as_mut().unwrap();
state.speed += input_manager.get_virtual_input_state("mouse_wheel") * 10.0;
let speed = state.speed * timer.delta_time();
state.camera.rotate(Vec3::new(
(input_manager.get_virtual_input_state("mouse_y") * 50.0 * timer.delta_time())
.to_radians(),
(input_manager.get_virtual_input_state("mouse_x") * 50.0 * timer.delta_time())
.to_radians(),
0.0,
));
if state.camera.get_rotation().x > 89.0 {
state
.camera
.set_rotation(Vec3::new(89.0, state.camera.get_rotation().y, 0.0));
}
if state.camera.get_rotation().x < -89.0 {
state
.camera
.set_rotation(Vec3::new(-89.0, state.camera.get_rotation().y, 0.0));
}
let rotation = state.camera.get_rotation();
let mut translation = Vec3::ZERO;
let tx = input_manager.get_virtual_input_state("move_right") * timer.delta_time() * speed;
translation.x += tx * (rotation.y).to_radians().cos();
translation.z += tx * (rotation.y).to_radians().sin();
let ty = input_manager.get_virtual_input_state("move_forward") * timer.delta_time() * speed;
translation.x += ty * (rotation.y + 90.0).to_radians().cos();
translation.z += ty * (rotation.y + 90.0).to_radians().sin();
state.camera.translate(translation);
state.camera.set_projection(Mat4::perspective_rh_gl(
std::f32::consts::FRAC_PI_2,
render_context.aspect_ratio(),
0.01,
100.0,
));
}
fn render(
&self,
render_context: &RenderContext,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
) {
let state = self.state.as_ref().unwrap();
let vertex_count = state.vertex_buffer.len() as u32;
let instance_count = vertex_count / 4;
let layouts = state.pipeline.layout().set_layouts();
let uniform_buffer = state
.camera
.create_buffer(render_context.memory_allocator())
.unwrap();
let uniform_descriptor_set = DescriptorSet::new(
render_context.descriptor_set_allocator().clone(),
layouts[0].clone(),
[WriteDescriptorSet::buffer(0, uniform_buffer)],
[],
)
.unwrap();
let texture_descriptor_set = DescriptorSet::new(
render_context.descriptor_set_allocator().clone(),
layouts[1].clone(),
[
WriteDescriptorSet::sampler(0, state.texture.get_sampler().clone()),
WriteDescriptorSet::image_view(1, state.texture.get_texture().clone()),
],
[],
)
.unwrap();
unsafe {
builder
.bind_pipeline_graphics(state.pipeline.clone())
.unwrap()
.bind_descriptor_sets(
PipelineBindPoint::Graphics,
state.pipeline.layout().clone(),
0,
vec![uniform_descriptor_set, texture_descriptor_set],
)
.unwrap()
.bind_vertex_buffers(0, state.vertex_buffer.clone())
.unwrap()
.draw(vertex_count, instance_count, 0, 0)
.unwrap();
}
}
fn unload(&mut self) {}
}