diff options
Diffstat (limited to 'engine/src')
-rw-r--r-- | engine/src/lib.rs | 74 | ||||
-rw-r--r-- | engine/src/renderer/mod.rs | 57 | ||||
-rw-r--r-- | engine/src/vector.rs | 6 |
3 files changed, 137 insertions, 0 deletions
diff --git a/engine/src/lib.rs b/engine/src/lib.rs new file mode 100644 index 0000000..618bc75 --- /dev/null +++ b/engine/src/lib.rs @@ -0,0 +1,74 @@ +#![deny(clippy::all, clippy::pedantic)] + +use glfw::Window; +pub use glfw::WindowSize; + +mod renderer; + +pub mod vector; + +pub struct Engine +{ + window: Window, +} + +impl Engine +{ + /// Creates and initializes a new engine. + /// + /// # Errors + /// Will return `Err` if window creation or window configuration fails. + pub fn new(window_size: &WindowSize, window_title: &str) -> Result<Self, Error> + { + let window = Window::create(window_size, window_title) + .map_err(Error::CreateWindowFailed)?; + + window + .make_context_current() + .map_err(Error::ConfigureWindowFailed)?; + + crate::renderer::initialize(&window).map_err(Error::InitializeRendererFailed)?; + + Ok(Self { window }) + } + + /// Starts the engine. + /// + /// # Errors + /// Will return `Err` if updating the window fails. + pub fn start(&self, mut func: impl FnMut()) -> Result<(), Error> + { + while !self.window.should_close() { + func(); + + crate::renderer::render(); + + self.window + .swap_buffers() + .map_err(Error::UpdateWindowFailed)?; + + self.window + .poll_events() + .map_err(Error::UpdateWindowFailed)?; + } + + Ok(()) + } +} + +/// Engine Error +#[derive(Debug, thiserror::Error)] +pub enum Error +{ + #[error("Failed to create window")] + CreateWindowFailed(#[source] glfw::Error), + + #[error("Failed to configure window")] + ConfigureWindowFailed(#[source] glfw::Error), + + #[error("Failed to initialize renderer")] + InitializeRendererFailed(#[source] renderer::Error), + + #[error("Failed to update window")] + UpdateWindowFailed(#[source] glfw::Error), +} diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs new file mode 100644 index 0000000..c34441c --- /dev/null +++ b/engine/src/renderer/mod.rs @@ -0,0 +1,57 @@ +use std::ffi::{c_void, CString}; +use std::process::abort; + +use crate::vector::Vec2; + +pub fn initialize(window: &glfw::Window) -> Result<(), Error> +{ + gl::load_with(|symbol| { + let proc_name = unsafe { CString::from_vec_unchecked(symbol.into()) }; + + match window.get_proc_address(proc_name.as_c_str()) { + Ok(addr) => addr as *const c_void, + Err(err) => { + println!( + "FATAL ERROR: Failed to get adress of OpenGL function {}. {}", + symbol, err + ); + + abort(); + } + } + }); + + let window_size = window.size().map_err(Error::GetWindowSizeFailed)?; + + set_viewport(&Vec2 { x: 0, y: 0 }, &window_size); + + Ok(()) +} + +pub fn render() +{ + unsafe { + gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); + } +} + +/// Renderer error. +#[derive(Debug, thiserror::Error)] +pub enum Error +{ + #[error("Failed to get window size")] + GetWindowSizeFailed(#[source] glfw::Error), +} + +fn set_viewport(position: &Vec2<u32>, size: &crate::WindowSize) +{ + unsafe { + #[allow(clippy::cast_possible_wrap)] + gl::Viewport( + position.x as i32, + position.y as i32, + size.width as i32, + size.height as i32, + ); + } +} diff --git a/engine/src/vector.rs b/engine/src/vector.rs new file mode 100644 index 0000000..92192bf --- /dev/null +++ b/engine/src/vector.rs @@ -0,0 +1,6 @@ +#[derive(Debug)] +pub struct Vec2<Value> +{ + pub x: Value, + pub y: Value, +} |