use crate::custom_errors::Errors;
use crate::input;
use glfw::{Action, Context, Key, WindowEvent};
use std::sync::mpsc::Receiver;
pub struct Window {
glfw: glfw::Glfw,
window_handle: glfw::Window,
events: Receiver<(f64, WindowEvent)>,
}
impl Window {
pub fn new(width: u32, height: u32, title: &str) -> Result<Self, Errors> {
let glfw = glfw::init(glfw::FAIL_ON_ERRORS)
.map_err(|e| Errors::GlfwInitializationError(e.to_string()))?;
let (mut window, events) = glfw
.create_window(width, height, title, glfw::WindowMode::Windowed)
.ok_or_else(|| {
Errors::WindowCreationError("Failed to create GLFW window".to_string())
})?;
window.set_framebuffer_size_polling(true);
window.set_key_polling(true);
window.set_mouse_button_polling(true);
window.set_cursor_pos_polling(true);
window.set_scroll_polling(true);
Ok(Self {
glfw,
window_handle: window,
events,
})
}
pub fn init_gl(&mut self) -> Result<(), Errors> {
self.window_handle.make_current();
gl::load_with(|s| self.window_handle.get_proc_address(s) as *const _);
crate::custom_errors::check_opengl_error()?;
Ok(())
}
pub fn should_close(&self) -> bool {
self.window_handle.should_close()
}
pub fn enable_depth_test(&self) {
unsafe {
gl::Enable(gl::DEPTH_TEST);
}
}
pub fn enable_blend(&self) {
unsafe {
gl::Enable(gl::BLEND);
gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
}
}
pub fn clear(&self, r: f32, g: f32, b: f32, a: f32) {
unsafe {
gl::ClearColor(r, g, b, a);
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
}
}
pub fn update(&mut self) {
self.process_events();
self.glfw.poll_events();
self.window_handle.swap_buffers();
}
fn process_events(&mut self) {
for (_, event) in glfw::flush_messages(&self.events) {
input::process_event(&event);
match event {
glfw::WindowEvent::FramebufferSize(width, height) => {
unsafe { gl::Viewport(0, 0, width, height) }
}
glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
self.window_handle.set_should_close(true)
}
_ => {}
}
}
}
}