use std::error::Error; use std::path::Path; use engine::camera::Camera; use engine::delta_time::DeltaTime; use engine::ecs::sole::Single; use engine::ecs::Query; use engine::event::Update as UpdateEvent; use engine::input::{Extension as InputExtension, Keys}; use engine::lighting::{LightSource, LightSourceBuilder}; use engine::material::Builder as MaterialBuilder; use engine::renderer::Extension as RendererExtension; use engine::shader::{Kind as ShaderKind, Program as ShaderProgram, Shader}; use engine::texture::{Id as TextureId, Map as TextureMap, Texture}; use engine::transform::Transform; use engine::vector::{Vec2, Vec3}; use engine::vertex::Builder as VertexBuilder; use engine::window::{Extension as WindowExtension, Key, KeyState}; use engine::Engine; use tracing::Level; use tracing_subscriber::FmtSubscriber; use crate::cube::{create_cube_mesh, Corner as CubeCorner, Side as CubeSide}; mod cube; const VERTEX_SHADER_FILE: &str = "vertex.glsl"; const FRAGMENT_SHADER_FILE: &str = "fragment.glsl"; const SHADER_DIR: &str = "engine"; const CAM_SPEED: f32 = 3.0; const LIGHT_SOURCE_SPEED: f32 = 1.2; fn lmao( camera_query: Query<(Camera,)>, light_source_query: Query<(LightSource,)>, keys: Single, delta_time: Single, ) { let (mut camera,) = camera_query.iter().next().expect("No camera"); let (mut light_source,) = light_source_query.iter().next().expect("No light source"); let delta_time = delta_time.duration; if matches!(keys.get_key_state(Key::W), KeyState::Pressed) { let cam_target_direction = camera.target_direction().clone(); camera.position += cam_target_direction * CAM_SPEED * delta_time.as_secs_f32(); } if matches!(keys.get_key_state(Key::S), KeyState::Pressed) { let rev_cam_target_direction = -camera.target_direction().clone(); camera.position += rev_cam_target_direction * CAM_SPEED * delta_time.as_secs_f32(); } if matches!(keys.get_key_state(Key::A), KeyState::Pressed) { let cam_left = camera.left().clone(); // Camera speed adjusted to be same no matter how far the distance is to the // camera target let cam_speed_dist_adj = CAM_SPEED * (camera.position.clone() - camera.target.clone()).length(); camera.position += cam_left * cam_speed_dist_adj * delta_time.as_secs_f32(); } if matches!(keys.get_key_state(Key::D), KeyState::Pressed) { let cam_right = camera.right().clone(); // Camera speed adjusted to be same no matter how far the distance is to the // camera target let cam_speed_dist_adj = CAM_SPEED * (camera.position.clone() - camera.target.clone()).length(); camera.position += cam_right * cam_speed_dist_adj * delta_time.as_secs_f32(); } if matches!(keys.get_key_state(Key::K), KeyState::Pressed) { let cam_up = camera.up().clone(); // Camera speed adjusted to be same no matter how far the distance is to the // camera target let cam_speed_dist_adj = CAM_SPEED * (camera.position.clone() - camera.target.clone()).length(); camera.position += cam_up * cam_speed_dist_adj * delta_time.as_secs_f32(); } if matches!(keys.get_key_state(Key::J), KeyState::Pressed) { let cam_up = camera.down().clone(); // Camera speed adjusted to be same no matter how far the distance is to the // camera target let cam_speed_dist_adj = CAM_SPEED * (camera.position.clone() - camera.target.clone()).length(); camera.position += cam_up * cam_speed_dist_adj * delta_time.as_secs_f32(); } if matches!(keys.get_key_state(Key::O), KeyState::Pressed) { let front_right = Vec3 { x: 1.0, y: 0.0, z: 1.0 }; light_source .translate(front_right * LIGHT_SOURCE_SPEED * delta_time.as_secs_f32()); } if matches!(keys.get_key_state(Key::L), KeyState::Pressed) { let back_left = Vec3 { x: -1.0, y: 0.0, z: -1.0 }; light_source.translate(back_left * LIGHT_SOURCE_SPEED * delta_time.as_secs_f32()); } } fn main() -> Result<(), Box> { let subscriber = FmtSubscriber::builder() .with_max_level(Level::TRACE) .finish(); tracing::subscriber::set_global_default(subscriber)?; let mut engine = Engine::new(); let texture = Texture::open(Path::new("vent.png"))?; let material = MaterialBuilder::new() .ambient_map(TextureId::new(0)) .diffuse_map(TextureId::new(0)) .specular_map(TextureId::new(0)) .build(); /* let mut textured_cube = create_cube(cube_vertex_builder_cb) .texture(TextureId::new(0), texture.clone()) .material(material.clone()) .build(ObjectId::new(4))?; textured_cube.translate(Vec3 { x: 1.6, y: 0.0, z: 0.0 }); engine.add_object(textured_cube); */ let mut transform = Transform::new(); transform.set_position(Vec3 { x: 1.6, y: 0.0, z: 0.0 }); let mut shader_program = ShaderProgram::new(); shader_program.push_shader( Shader::read_shader_file( ShaderKind::Vertex, &Path::new(SHADER_DIR).join(VERTEX_SHADER_FILE), )? .preprocess()?, ); shader_program.push_shader( Shader::read_shader_file( ShaderKind::Fragment, &Path::new(SHADER_DIR).join(FRAGMENT_SHADER_FILE), )? .preprocess()?, ); engine.spawn(( create_cube_mesh(cube_vertex_builder_cb), TextureMap::from_iter([(TextureId::new(0), texture)]), material, transform, shader_program, )); let light_source = LightSourceBuilder::new() .position(Vec3 { x: 1.2, y: 1.0, z: 1.5 }) .build(); engine.spawn((light_source,)); engine.spawn((Camera { current: true, ..Default::default() },)); engine.register_system(UpdateEvent, lmao); engine.add_extension(RendererExtension::default()); engine.add_extension(WindowExtension::default().window_title("Game")); engine.add_extension(InputExtension::default()); engine.start(); Ok(()) } fn cube_vertex_builder_cb( vertex_builder: VertexBuilder, _side: CubeSide, corner: CubeCorner, ) -> VertexBuilder { vertex_builder.texture_coords(match corner { CubeCorner::TopRight => Vec2 { x: 1.0, y: 1.0 }, CubeCorner::TopLeft => Vec2 { x: 0.0, y: 1.0 }, CubeCorner::BottomRight => Vec2 { x: 1.0, y: 0.0 }, CubeCorner::BottomLeft => Vec2 { x: 0.0, y: 0.0 }, }) } trait CameraExt { fn target_direction(&self) -> Vec3; fn right(&self) -> Vec3; fn left(&self) -> Vec3; fn up(&self) -> Vec3; fn down(&self) -> Vec3; } impl CameraExt for Camera { fn target_direction(&self) -> Vec3 { -(&self.position - &self.target).normalize() } fn right(&self) -> Vec3 { let rev_target_direction = (&self.position - &self.target).normalize(); Vec3::UP.cross(&rev_target_direction).normalize() } fn left(&self) -> Vec3 { -self.right() } fn up(&self) -> Vec3 { let rev_target_direction = (&self.position - &self.target).normalize(); rev_target_direction.cross(&self.right()) } fn down(&self) -> Vec3 { -self.up() } }