use std::convert::TryInto; use glfw; use glfw::{Action, Context, Key}; use cgmath::{Matrix4, vec3, Point3, Deg, perspective}; use cgmath::prelude::*; const SCR_WIDTH: u32 = 1600; const SCR_HEIGHT: u32 = 900; const TITLE: &str = "GLFWtest"; use std::sync::mpsc::Receiver; use std::ptr; use std::mem; use std::os::raw::c_void; use std::path::Path; use std::ffi::{CString, CStr}; mod shader; mod model; mod camera; fn main() { 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(true)); glfw.window_hint(glfw::WindowHint::Decorated(false)); 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(); 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 mut camera = camera::Camera { Position: Point3::new(0.0, 0.25, 1.0), Pitch: -20.0, ..camera::Camera::default() }; let mut firstMouse = true; let mut lastX: f32 = SCR_WIDTH as f32 / 2.0; let mut lastY: f32 = SCR_HEIGHT as f32 / 2.0; // timing let mut deltaTime: f32; // time between current frame and last frame let mut lastFrame: f32 = 0.0; gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); unsafe{ gl::Enable(gl::DEPTH_TEST); gl::DepthFunc(gl::LESS); gl::Enable(gl::STENCIL_TEST); gl::StencilFunc(gl::NOTEQUAL, 1, 0xFF); gl::StencilOp(gl::KEEP, gl::KEEP, gl::REPLACE); }; let (ourshader, ourModel) = unsafe { gl::Enable(gl::DEPTH_TEST); let ourShader = shader::shader::new("model"); let ourModel = model::Model::new("resources/models/TestCarModel/CarW4.obj"); (ourShader, ourModel) }; 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; process_events(&events, &mut firstMouse, &mut lastX, &mut lastY, &mut camera); processInput(&mut window, deltaTime, &mut camera); unsafe { gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT); gl::ClearColor(1.0, 1.0, 1.0, 1.0); 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(&CString::new("projection").unwrap(), &projection); ourshader.setMat4(&CString::new("view").unwrap(), &view); let mut model = Matrix4::::from_translation(vec3(0.0, -0.3, 0.0)); model = model * Matrix4::from_scale(0.2); ourshader.setMat4(&CString::new("model").unwrap(), &model); gl::StencilFunc(gl::NOTEQUAL, 1, 0xFF); gl::StencilMask(0x00); //gl::Disable(gl::DEPTH_TEST); ourModel.Draw(&ourshader); gl::Enable(gl::DEPTH_TEST); } window.swap_buffers(); glfw.poll_events(); } } 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; } let xoffset = xpos - *lastX; let yoffset = *lastY - ypos; // reversed since y-coordinates go from bottom to top *lastX = xpos; *lastY = ypos; camera.ProcessMouseMovement(xoffset, yoffset, true); } glfw::WindowEvent::Scroll(_xoffset, yoffset) => { camera.ProcessMouseScroll(yoffset as f32); } _ => {} } } }