Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 8m5s
214 lines
6.6 KiB
Rust
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) {}
|
|
}
|