diff --git a/Cargo.toml b/Cargo.toml index 9742bb9..da63741 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,4 @@ image = "0.24.5" cgmath = "0.18.0" tobj = "2.0.0" glow = "0.12.1" -[dependencies.glfw] -version = "*" +sdl2 = "0.35.2" diff --git a/src/main.rs b/src/main.rs index 1f3ab4a..03554d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,20 @@ use std::convert::TryInto; -use glfw; -use glfw::{Action, Context, Key}; +//use glfw; +//use glfw::{Action, Context, Key}; use cgmath::{Matrix4, vec3, Point3, Deg, perspective}; use cgmath::prelude::*; -use std::rc::Rc; +use std::sync::Arc; const SCR_WIDTH: u32 = 1600; const SCR_HEIGHT: u32 = 900; const TITLE: &str = "GLFWtest"; -use glow::*; +use glow::*; +use sdl2; +use sdl2::pixels::Color; + +use sdl2::keyboard::Keycode; +use sdl2::event::Event; use std::sync::mpsc::Receiver; use std::ptr; use std::mem; @@ -21,27 +26,57 @@ mod model; mod camera; fn main() { - let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); + //let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); - glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3)); - glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core)); - glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); - glfw.window_hint(glfw::WindowHint::Resizable(false)); - glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(false)); - glfw.window_hint(glfw::WindowHint::Decorated(true)); + // glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3)); + // glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core)); + // glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); + // glfw.window_hint(glfw::WindowHint::Resizable(false)); + // glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(false)); + // glfw.window_hint(glfw::WindowHint::Decorated(true)); - let (mut window, events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, TITLE, glfw::WindowMode::Windowed).unwrap(); + // let (mut window, events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, TITLE, glfw::WindowMode::Windowed).unwrap(); - let (screen_width, screen_height) = window.get_framebuffer_size(); + //let (screen_width, screen_height) = window.get_framebuffer_size(); - window.make_current(); - window.set_key_polling(true); - window.set_framebuffer_size_polling(true); - window.set_cursor_pos_polling(true); - window.set_cursor_mode(glfw::CursorMode::Disabled); + let (gl, shader_version, window, mut events_loop, _context) = { + let sdl = match sdl2::init() + { + Ok(sdl) => sdl, + Err(s) => panic!("Error with Initializing SDL: {}", s), + }; + let video = sdl.video().unwrap(); + let gl_attr = video.gl_attr(); + gl_attr.set_context_profile(sdl2::video::GLProfile::Core); + gl_attr.set_context_version(3, 3); + let window = match video + .window("DairyTest", SCR_WIDTH, SCR_HEIGHT) + .opengl() + .resizable() + .build() { + Ok(ret) => ret, + Err(s) => panic!("Error with Initializing SDL Window: {}", s), + }; + + let gl_context = match window.gl_create_context() + { + Ok(ret) => ret, + Err(s) => panic!("Error with Initializing SDL Context: {}", s) + }; + let gl = std::sync::Arc::new(unsafe{glow::Context::from_loader_function(|s| video.gl_get_proc_address(s) as *const _)}); + + let event_loop = match sdl.event_pump() + { + Ok(ret) => ret, + Err(s) => panic!("Error with Initializing SDL Event Loop: {}", s) + }; + (gl, "#version 330", window, event_loop, gl_context) + + }; + let mut camera = camera::Camera { Position: Point3::new(0.0, 0.40, 1.0), Pitch: -20.0, @@ -57,114 +92,59 @@ fn main() { let mut lastFrame: f32 = 0.0; //gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); - let gl = std::rc::Rc::new(unsafe{glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _)}); let (ourshader, ourModel) = unsafe { gl.enable(glow::DEPTH_TEST); - let ourShader = shader::shader::new("model", Rc::clone(&gl)); + let ourShader = shader::shader::new("model", Arc::clone(&gl)); - let ourModel = model::Model::new("resources/models/TestCarModel/CarW4.obj", Rc::clone(&gl)); + let ourModel = model::Model::new("resources/models/TestCarModel/CarW4.obj", Arc::clone(&gl)); (ourShader, ourModel) }; + let time = std::time::Instant::now(); let projection: Matrix4 = perspective(Deg(45.0), SCR_WIDTH as f32/ SCR_HEIGHT as f32, 0.1, 100.0); println!("entering main loop"); - - while !window.should_close() { - let currentFrame = glfw.get_time() as f32; - deltaTime = currentFrame - lastFrame; - lastFrame = currentFrame; - - processInput(&mut window, deltaTime, &mut camera); - - unsafe { - gl.enable(glow::DEPTH_TEST); - gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT); - - // outline - - ourshader.Use(); - let Projection: Matrix4 = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32, 0.1, 100.0); - let view = camera.GetViewMatrix(); - ourshader.setMat4("projection", &projection); - ourshader.setMat4("view", &view); + // NOTE main loop here + 'running: loop { + let currentFrame = time.elapsed().as_secs_f32(); + deltaTime = currentFrame - lastFrame; + lastFrame = currentFrame; - //let mut model = Matrix4::::from_translation(vec3(0.0, -0.3, 0.0)); - let mut model: Matrix4 = Matrix4::from_axis_angle(vec3(0.0, -1.0, 0.0).normalize(), - cgmath::Rad(glfw.get_time() as f32)); - model = model * Matrix4::from_scale(0.2); - ourshader.setMat4("model", &model); + unsafe{ + gl.enable(glow::DEPTH_TEST); + gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT); - ourModel.Draw(&ourshader); + ourshader.Use(); + let Projection: Matrix4 = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32, 0.1, 100.0); - } + let view = camera.GetViewMatrix(); + ourshader.setMat4("projection", &projection); + ourshader.setMat4("view", &view); - window.swap_buffers(); - glfw.poll_events(); - } -} + let mut model: Matrix4 = Matrix4::from_axis_angle(vec3(0.0, -1.0, 0.0).normalize(), + cgmath::Rad(time.elapsed().as_secs_f32())); + model = model * Matrix4::from_scale(0.2); + ourshader.setMat4("model", &model); - - - - fn processInput(window: &mut glfw::Window, deltaTime: f32, camera: &mut camera::Camera) { - if window.get_key(Key::Escape) == Action::Press { - window.set_should_close(true) - } - /* - if window.get_key(Key::W) == Action::Press { - camera.ProcessKeyboard(camera::Camera_Movement::FORWARD, deltaTime); - } - if window.get_key(Key::S) == Action::Press { - camera.ProcessKeyboard(camera::Camera_Movement::BACKWARD, deltaTime); - } - if window.get_key(Key::A) == Action::Press { - camera.ProcessKeyboard(camera::Camera_Movement::LEFT, deltaTime); - } - if window.get_key(Key::D) == Action::Press { - camera.ProcessKeyboard(camera::Camera_Movement::RIGHT, deltaTime); - } - */ -} -/* -fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>, - firstMouse: &mut bool, - lastX: &mut f32, - lastY: &mut f32, - camera: &mut camera::Camera) { - for (_, event) in glfw::flush_messages(events) { - match event { - glfw::WindowEvent::FramebufferSize(width, height) => { - // make sure the viewport matches the new window dimensions; note that width and - // height will be significantly larger than specified on retina displays. - unsafe { gl.viewport(0, 0, width, height) } } - glfw::WindowEvent::CursorPos(xpos, ypos) => { - let (xpos, ypos) = (xpos as f32, ypos as f32); - if *firstMouse { - *lastX = xpos; - *lastY = ypos; - *firstMouse = false; - } + ourModel.Draw(&ourshader); - let xoffset = xpos - *lastX; - let yoffset = *lastY - ypos; // reversed since y-coordinates go from bottom to top + window.gl_swap_window(); + for event in events_loop.poll_iter() { - *lastX = xpos; - *lastY = ypos; - camera.ProcessMouseMovement(xoffset, yoffset, true); + match event { + Event::Quit {..} | + Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { + break 'running + }, + _ => {} } - glfw::WindowEvent::Scroll(_xoffset, yoffset) => { - camera.ProcessMouseScroll(yoffset as f32); - } - _ => {} } } } -*/ diff --git a/src/model.rs b/src/model.rs index d513a4b..f24fdda 100644 --- a/src/model.rs +++ b/src/model.rs @@ -3,7 +3,7 @@ use std::os::raw::c_void; use std::path::Path; -use std::rc::Rc; +use std::sync::Arc; use cgmath::{vec2, vec3}; use image; use glow::*; @@ -24,9 +24,9 @@ pub struct Model { impl Model { /// constructor, expects a filepath to a 3D model. - pub fn new(path: &str, gl: std::rc::Rc) -> Model { + pub fn new(path: &str, gl: std::sync::Arc) -> Model { let mut model = Model::default(); - model.loadModel(path, Rc::clone(&gl)); + model.loadModel(path, Arc::clone(&gl)); model } @@ -38,7 +38,7 @@ impl Model { } // loads a model from file and stores the resulting meshes in the meshes vector. - fn loadModel(&mut self, path: &str, gl: std::rc::Rc) { + fn loadModel(&mut self, path: &str, gl: Arc) { let path = Path::new(path); // retrieve the directory path of the filepath @@ -71,28 +71,28 @@ impl Model { // 1. diffuse map if !material.diffuse_texture.is_empty() { - let texture = self.loadMaterialTexture(&material.diffuse_texture, "texture_diffuse", Rc::clone(&gl)); + let texture = self.loadMaterialTexture(&material.diffuse_texture, "texture_diffuse", Arc::clone(&gl)); textures.push(texture); } // 2. specular map if !material.specular_texture.is_empty() { - let texture = self.loadMaterialTexture(&material.specular_texture, "texture_specular", Rc::clone(&gl)); + let texture = self.loadMaterialTexture(&material.specular_texture, "texture_specular", Arc::clone(&gl)); textures.push(texture); } // 3. normal map if !material.normal_texture.is_empty() { - let texture = self.loadMaterialTexture(&material.normal_texture, "texture_normal", Rc::clone(&gl)); + let texture = self.loadMaterialTexture(&material.normal_texture, "texture_normal", Arc::clone(&gl)); textures.push(texture); } // NOTE: no height maps } - self.meshes.push(Mesh::new(vertices, indices, textures, Rc::clone(&gl))); + self.meshes.push(Mesh::new(vertices, indices, textures, Arc::clone(&gl))); } } - fn loadMaterialTexture(&mut self, path: &str, typeName: &str, gl: Rc) -> Texture { + fn loadMaterialTexture(&mut self, path: &str, typeName: &str, gl: Arc) -> Texture { { let texture = self.textures_loaded.iter().find(|t| t.path == path); if let Some(texture) = texture { @@ -101,7 +101,7 @@ impl Model { } let texture = Texture { - id: unsafe { TextureFromFile(path, &self.directory, std::rc::Rc::clone(&gl)) }, + id: unsafe { TextureFromFile(path, &self.directory, Arc::clone(&gl)) }, type_: typeName.into(), path: path.into() }; @@ -110,7 +110,7 @@ impl Model { } } -unsafe fn TextureFromFile(path: &str, directory: &str, gl: Rc) -> glow::NativeTexture { +unsafe fn TextureFromFile(path: &str, directory: &str, gl: Arc) -> glow::NativeTexture { let filename = format!("{}/{}", directory, path); let mut textureID = gl.create_texture().unwrap(); diff --git a/src/model/mesh.rs b/src/model/mesh.rs index 92bda72..37727da 100644 --- a/src/model/mesh.rs +++ b/src/model/mesh.rs @@ -61,7 +61,7 @@ pub struct Mesh { } impl Mesh { - pub fn new(vertices: Vec, indices: Vec, textures: Vec,gl: std::rc::Rc) -> Mesh { + pub fn new(vertices: Vec, indices: Vec, textures: Vec,gl: std::sync::Arc) -> Mesh { let mut mesh = { @@ -124,7 +124,7 @@ impl Mesh { shader.gl.active_texture(glow::TEXTURE0); } - unsafe fn setupMesh(&mut self, gl: std::rc::Rc) { + unsafe fn setupMesh(&mut self, gl: std::sync::Arc) { self.VAO = Some(gl.create_vertex_array().unwrap()); self.VBO = Some(gl.create_buffer().unwrap()); diff --git a/src/shader.rs b/src/shader.rs index 9f066bc..8252d9c 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -1,14 +1,14 @@ use glow::*; use std::fs; -use std::rc::Rc; +use std::sync::Arc; use std::str; /// Shader Struct for creating and using shaders in the Context of engine /// pub struct shader { pub ID: NativeProgram, - pub gl: Rc + pub gl: Arc } @@ -21,7 +21,7 @@ use std::str; /// `new(String::from("Example"))` /// if the String given was "Example" the Program expects both shaders to be in the directory "resources/shaders/Example/" /// with the vertex shader being called "shader.vert" and fragment "shader.frag" - pub fn new(path: &str, gl: Rc) -> shader + pub fn new(path: &str, gl: Arc) -> shader { //read file contents let VERT_SHADER = fs::read_to_string(format!("resources/shaders/{path}/shader.vert")).unwrap(); @@ -58,7 +58,7 @@ use std::str; shader { ID: shader_program, - gl: Rc::clone(&gl), + gl: Arc::clone(&gl), } } }