diff options
-rw-r--r-- | Cargo.lock | 41 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | engine/Cargo.toml | 9 | ||||
-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 |
6 files changed, 188 insertions, 1 deletions
@@ -82,6 +82,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] +name = "engine" +version = "0.1.0" +dependencies = [ + "gl", + "glfw", + "thiserror", +] + +[[package]] name = "errno" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -107,6 +116,26 @@ name = "game-newest" version = "0.1.0" [[package]] +name = "gl" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94edab108827d67608095e269cf862e60d920f144a5026d3dbcfd8b877fb404" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] name = "glfw" version = "0.1.0" dependencies = [ @@ -131,6 +160,12 @@ dependencies = [ ] [[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -422,3 +457,9 @@ name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "xml-rs" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" @@ -4,6 +4,6 @@ version = "0.1.0" edition = "2021" [workspace] -members = ["glfw"] +members = ["glfw", "engine"] [dependencies] diff --git a/engine/Cargo.toml b/engine/Cargo.toml new file mode 100644 index 0000000..7b42cab --- /dev/null +++ b/engine/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "engine" +version = "0.1.0" +edition = "2021" + +[dependencies] +glfw = { path = "../glfw" } +thiserror = "1.0.49" +gl = "0.14.0" 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, +} |