diff options
-rw-r--r-- | engine/src/lib.rs | 15 | ||||
-rw-r--r-- | engine/src/renderer/mod.rs | 252 |
2 files changed, 147 insertions, 120 deletions
diff --git a/engine/src/lib.rs b/engine/src/lib.rs index 9f82b26..ae603b0 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -8,6 +8,7 @@ use glfw::{Window, WindowBuilder}; use crate::camera::Camera; use crate::object::{Id as ObjectId, Object}; +use crate::renderer::Renderer; use crate::vector::Vec2; mod matrix; @@ -32,7 +33,7 @@ pub struct Engine /// Objects have to be dropped before window. Otherwise, UB. objects: BTreeMap<ObjectId, Object>, window: Window, - camera: Camera, + renderer: Renderer, delta_time: Duration, } @@ -59,15 +60,15 @@ impl Engine .map_err(Error::ConfigureWindowFailed)?; window.set_framebuffer_size_callback(move |new_window_size| { - crate::renderer::set_viewport(&Vec2::ZERO, &new_window_size); + Renderer::set_viewport(&Vec2::ZERO, &new_window_size); }); - crate::renderer::initialize(&window).map_err(Error::InitializeRendererFailed)?; + let renderer = Renderer::new(&window).map_err(Error::InitializeRendererFailed)?; Ok(Self { window, + renderer, objects: BTreeMap::new(), - camera: Camera::new(), delta_time: Duration::ZERO, }) } @@ -110,7 +111,7 @@ impl Engine let window_size = self.window.size().map_err(Error::GetWindowSizeFailed)?; - crate::renderer::render(self.objects.values(), &window_size, &self.camera); + self.renderer.render(self.objects.values(), &window_size); self.window .swap_buffers() @@ -127,12 +128,12 @@ impl Engine #[must_use] pub fn camera(&self) -> &Camera { - &self.camera + self.renderer.camera() } pub fn camera_mut(&mut self) -> &mut Camera { - &mut self.camera + self.renderer.camera_mut() } /// Returns the current delta time. Will be 0 if not called from the function diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs index 3691f76..cad4deb 100644 --- a/engine/src/renderer/mod.rs +++ b/engine/src/renderer/mod.rs @@ -21,134 +21,121 @@ use crate::projection::new_perspective; use crate::vector::Vec2; use crate::vertex::Vertex; -pub fn initialize(window: &glfw::Window) -> Result<(), Error> +#[derive(Debug)] +pub struct Renderer { - 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(); - } - } - }); + camera: Camera, +} - #[cfg(feature = "debug")] +impl Renderer +{ + pub fn new(window: &glfw::Window) -> Result<Self, Error> { - use crate::opengl::debug::{ - enable_debug_output, - set_debug_message_callback, - set_debug_message_control, - MessageIdsAction, - }; - - enable_debug_output(); - - set_debug_message_callback(opengl_debug_message_cb); - - set_debug_message_control(None, None, None, &[], MessageIdsAction::Disable); - } + 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 + ); - let window_size = window.size().map_err(Error::GetWindowSizeFailed)?; + abort(); + } + } + }); - set_viewport(&Vec2 { x: 0, y: 0 }, &window_size); + #[cfg(feature = "debug")] + Self::initialize_debug(); - enable(Capability::DepthTest); + let window_size = window.size().map_err(Error::GetWindowSizeFailed)?; - Ok(()) -} + Self::set_viewport(&Vec2 { x: 0, y: 0 }, &window_size); -#[cfg(feature = "debug")] -#[tracing::instrument(skip_all)] -fn opengl_debug_message_cb( - source: MessageSource, - ty: MessageType, - id: u32, - severity: MessageSeverity, - message: &str, -) -{ - use std::backtrace::{Backtrace, BacktraceStatus}; + enable(Capability::DepthTest); - use tracing::{event, Level}; + let camera = Camera::new(); - macro_rules! create_event { - ($level: expr) => { - event!($level, ?source, ?ty, id, ?severity, message); - }; + Ok(Self { camera }) } - match ty { - MessageType::Error => { - create_event!(Level::ERROR); - - let backtrace = Backtrace::capture(); + pub fn render<'obj>( + &self, + objects: impl IntoIterator<Item = &'obj Object>, + window_size: &WindowSize, + ) + { + clear_buffers(BufferClearMask::COLOR | BufferClearMask::DEPTH); + + for obj in objects { + obj.renderable().shader_program.activate(); + + apply_transformation_matrices(obj, &self.camera, window_size); + + let draw = || { + obj.renderable().vertex_arr.bind(|vert_arr_curr_bound| { + if let Some(index_info) = &obj.renderable().index_info { + VertexArray::draw_elements( + &vert_arr_curr_bound, + PrimitiveKind::Triangles, + 0, + index_info.cnt, + ); + } else { + VertexArray::draw_arrays( + &vert_arr_curr_bound, + PrimitiveKind::Triangles, + 0, + 3, + ); + } + }); + }; - if matches!(backtrace.status(), BacktraceStatus::Captured) { - event!(Level::TRACE, "{backtrace}"); + if let Some(texture) = obj.texture() { + texture.inner().bind(|_| { + draw(); + }); + } else { + draw(); } } - MessageType::Other => { - create_event!(Level::INFO); - } - _ => { - create_event!(Level::WARN); - } - }; -} + } -pub fn render<'obj>( - objects: impl IntoIterator<Item = &'obj Object>, - window_size: &WindowSize, - camera: &Camera, -) -{ - clear_buffers(BufferClearMask::COLOR | BufferClearMask::DEPTH); + pub fn set_viewport(position: &Vec2<u32>, size: &WindowSize) + { + crate::opengl::set_viewport(position, size); + } - for obj in objects { - obj.renderable().shader_program.activate(); + #[must_use] + pub fn camera(&self) -> &Camera + { + &self.camera + } - apply_transformation_matrices(obj, camera, window_size); + pub fn camera_mut(&mut self) -> &mut Camera + { + &mut self.camera + } - let draw = || { - obj.renderable().vertex_arr.bind(|vert_arr_curr_bound| { - if let Some(index_info) = &obj.renderable().index_info { - VertexArray::draw_elements( - &vert_arr_curr_bound, - PrimitiveKind::Triangles, - 0, - index_info.cnt, - ); - } else { - VertexArray::draw_arrays( - &vert_arr_curr_bound, - PrimitiveKind::Triangles, - 0, - 3, - ); - } - }); + #[cfg(feature = "debug")] + fn initialize_debug() + { + use crate::opengl::debug::{ + enable_debug_output, + set_debug_message_callback, + set_debug_message_control, + MessageIdsAction, }; - if let Some(texture) = obj.texture() { - texture.inner().bind(|_| { - draw(); - }); - } else { - draw(); - } - } -} + enable_debug_output(); -pub fn set_viewport(position: &Vec2<u32>, size: &WindowSize) -{ - crate::opengl::set_viewport(position, size); + set_debug_message_callback(opengl_debug_message_cb); + + set_debug_message_control(None, None, None, &[], MessageIdsAction::Disable); + } } #[derive(Debug)] @@ -162,13 +149,6 @@ pub struct Renderable index_info: Option<IndexInfo>, } -#[derive(Debug)] -struct IndexInfo -{ - _buffer: Buffer<u32, ElementArrayBufferKind>, - cnt: u32, -} - impl Renderable { pub fn new( @@ -251,3 +231,49 @@ fn apply_transformation_matrices( .shader_program .set_uniform_matrix_4fv(cstr!("projection"), &projection); } + +#[cfg(feature = "debug")] +#[tracing::instrument(skip_all)] +fn opengl_debug_message_cb( + source: MessageSource, + ty: MessageType, + id: u32, + severity: MessageSeverity, + message: &str, +) +{ + use std::backtrace::{Backtrace, BacktraceStatus}; + + use tracing::{event, Level}; + + macro_rules! create_event { + ($level: expr) => { + event!($level, ?source, ?ty, id, ?severity, message); + }; + } + + match ty { + MessageType::Error => { + create_event!(Level::ERROR); + + let backtrace = Backtrace::capture(); + + if matches!(backtrace.status(), BacktraceStatus::Captured) { + event!(Level::TRACE, "{backtrace}"); + } + } + MessageType::Other => { + create_event!(Level::INFO); + } + _ => { + create_event!(Level::WARN); + } + }; +} + +#[derive(Debug)] +struct IndexInfo +{ + _buffer: Buffer<u32, ElementArrayBufferKind>, + cnt: u32, +} |