use crate::model::Model; use crate::camera::Camera; use crate::shader::shader; use std::sync::Arc; use std::rc::Rc; use glow::*; use imgui_glow_renderer::AutoRenderer; use imgui_sdl2_support::SdlPlatform; use cgmath::{Matrix4, vec3, Point3, Deg, perspective}; use cgmath::prelude::*; use sdl2::keyboard::Keycode; use sdl2::event::Event; const SCR_WIDTH: u32 = 1600; const SCR_HEIGHT: u32 = 900; const MODELS: [&str; 3]= ["resources/models/TestCarModel/CarW4.obj", "resources/models/TestCarModel/CarW1.obj", "resources/models/TestCarModel/CarW0.obj"]; /// XXX this is temporary, thus the name pub struct tempData { pub projection: Matrix4, pub spinSpeed: f32, pub current_rad: f32, pub currentFrame: f32, pub deltaTime: f32, pub lastFrame: f32, DebugMode: bool, } use crate::debug::Debug; pub enum SceneEnum { Exit, Pause, Resume, } pub struct Scene { gl: Arc, pub Car: Model, camera: Camera, debug: Debug, shaders: Vec>, time: std::time::Instant, tempData: tempData, } impl Scene{ pub fn new(gl: Arc) -> Scene { let Car = Model::new(MODELS[0], Arc::clone(&gl)); let shader = Rc::new(shader::new("model", Arc::clone(&gl))); let time = std::time::Instant::now(); let camera = Camera { Position: Point3::new(0.0, 0.40, 1.0), Pitch: -20.0, ..Camera::default() }; let tempData = tempData { projection: perspective(Deg(45.0), 1600.0/ 900.0, 0.1, 100.0), spinSpeed: 1.0, current_rad: 1.0, currentFrame: 0.0, deltaTime: 0.0, lastFrame: 0.0, DebugMode: false, }; let debug = Debug::new(gl.clone()); Scene{ gl, Car, camera, debug, shaders: vec![shader], time, tempData, } } pub fn update(&mut self ,events_loop: &mut sdl2::EventPump, window: &sdl2::video::Window) -> SceneEnum { self.tempData.currentFrame = self.time.elapsed().as_secs_f32(); self.tempData.deltaTime = self.tempData.currentFrame - self.tempData.lastFrame; self.tempData.lastFrame = self.tempData.currentFrame; self.tempData.current_rad += self.tempData.spinSpeed/15.0; let mut ret = SceneEnum::Resume; unsafe { self.gl.enable(glow::DEPTH_TEST); self.gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT); self.shaders[0].Use(); self.tempData.projection = perspective(Deg(self.camera.Zoom), SCR_WIDTH as f32 /SCR_HEIGHT as f32, 0.1, 100.0); let view = self.camera.GetViewMatrix(); self.shaders[0].setMat4("projection", &self.tempData.projection); self.shaders[0].setMat4("view", &view); let mut model: Matrix4 = Matrix4::from_axis_angle(vec3(0.0, -1.0, 0.0).normalize(), cgmath::Rad(self.tempData.current_rad)); model = model * Matrix4::from_scale(0.2); self.shaders[0].setMat4("model", &model); } self.Car.Draw(&self.shaders[0]); if self.tempData.DebugMode{ for command in self.debug.drawImgui(&events_loop, &window, &mut self.tempData, &self.Car) { use crate::debug::dEvent; match command { dEvent::exit => ret = SceneEnum::Exit, dEvent::loadModel(i) => { self.Car = Model::new(MODELS[i as usize], Arc::clone(&self.gl)); } _ => (), } } } for event in events_loop.poll_iter() { if self.tempData.DebugMode { self.debug.handle(&event); } match event { Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { ret = SceneEnum::Exit; }, Event::KeyDown {keycode: Some(Keycode::P), ..} => { }, Event::KeyDown {keycode: Some(Keycode::D), ..} => { self.tempData.DebugMode = !self.tempData.DebugMode } _ => {} } } ret } }