diff options
Diffstat (limited to 'engine/src/renderer/opengl.rs')
| -rw-r--r-- | engine/src/renderer/opengl.rs | 297 |
1 files changed, 74 insertions, 223 deletions
diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index a713d41..1cd46b2 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -5,14 +5,12 @@ use std::borrow::Cow; use std::collections::HashMap; use ecs::actions::Actions; -use ecs::entity::obtainer::Obtainer as EntityObtainer; -use ecs::event::component::{Changed, Removed}; -use ecs::pair::{ChildOf, Pair, Wildcard}; -use ecs::phase::Phase; +use ecs::event::component::Removed; +use ecs::pair::{Pair, Wildcard}; use ecs::query::term::Without; use ecs::sole::Single; use ecs::system::observer::Observe; -use ecs::{Component, Query, declare_entity}; +use ecs::{Component, Query}; use glutin::display::GetGlDisplay; use glutin::prelude::GlDisplay; use glutin::surface::{ @@ -38,12 +36,12 @@ use opengl_bindings::debug::{ use opengl_bindings::misc::{ BufferClearMask as GlBufferClearMask, Capability, - SetViewportError as GlSetViewportError, clear_buffers, define_scissor_box as gl_define_scissor_box, enable, get_viewport as gl_get_viewport, set_enabled, + set_viewport as gl_set_viewport, }; use opengl_bindings::shader::{ Error as GlShaderError, @@ -73,7 +71,6 @@ use crate::asset::{Assets, Handle as AssetHandle}; use crate::data_types::dimens::Dimens; use crate::image::{ColorType as ImageColorType, Image}; use crate::matrix::Matrix; -use crate::model::Model; use crate::renderer::blending::{Equation as BlendingEquation, Factor as BlendingFactor}; use crate::renderer::object::{ Id as RendererObjectId, @@ -96,6 +93,7 @@ use crate::renderer::{ DrawMeshOptions, DrawPropertiesUpdateFlags, GraphicsProperties, + POST_RENDER_PHASE, PRE_RENDER_PHASE, RENDER_PHASE, RenderPasses, @@ -128,11 +126,6 @@ use crate::windowing::window::{ mod glutin_compat; mod graphics_mesh; -declare_entity!( - pub POST_RENDER_PHASE, - (Phase, Pair::builder().relation::<ChildOf>().target_id(*RENDER_PHASE).build()) -); - #[derive(Debug, Component)] struct WindowGlConfig { @@ -174,7 +167,10 @@ impl ecs::extension::Extension for Extension let _ = collector.add_sole(RenderPasses::default()); - collector.add_system(*PRE_RENDER_PHASE, super::add_main_render_passes); + collector.add_system( + *PRE_RENDER_PHASE, + crate::renderer::main_render_pass::add_main_render_passes, + ); collector.add_system(*RENDER_PHASE, super::enqueue_commands_from_render_passes); collector.add_system(*RENDER_PHASE, handle_commands); @@ -182,201 +178,12 @@ impl ecs::extension::Extension for Extension collector.add_system(*POST_RENDER_PHASE, prepare_windows); collector.add_system(*POST_RENDER_PHASE, init_window_graphics); - collector.add_observer(handle_model_removed); - - collector.add_observer(handle_window_changed); + collector.add_observer(super::handle_window_changed); collector.add_observer(handle_window_removed); } } #[tracing::instrument(skip_all)] -fn handle_model_removed( - observe: Observe<Pair<Removed, Model>>, - renderer_ctx_query: Query<( - &mut GraphicsContext, - &RendererObjectStore, - Pair<RendererCtxUsedByWindow, Wildcard>, - )>, - assets: Single<Assets>, -) -{ - for evt_match in &observe { - let model_ent_id = evt_match.id(); - - for ( - renderer_ctx_ent_id, - (mut graphics_ctx, renderer_object_store, renderer_ctx_used_by_window), - ) in renderer_ctx_query.iter_with_euids() - { - let GraphicsContext { - ref gl_context, - ref surfaces, - objects: ref mut graphics_ctx_objects, - .. - } = *graphics_ctx; - - let model = evt_match.get_removed_comp(); - - let Some(model_spec) = assets.get(&model.spec_asset) else { - continue; - }; - - let Some(mesh_asset) = &model_spec.mesh_asset else { - continue; - }; - - let Some(graphics_ctx_object_id) = renderer_object_store - .get_obj(&RendererObjectId::Asset(mesh_asset.id())) - .map(|obj| obj.as_raw()) - else { - continue; - }; - - if !graphics_ctx_objects.contains_key(&graphics_ctx_object_id) { - continue; - } - - let Some(window_ent) = renderer_ctx_used_by_window.get_target_ent() else { - tracing::error!( - window_entity_id = %renderer_ctx_used_by_window.id().target_entity(), - "Window entity does not exist" - ); - continue; - }; - - let Some(surface_spec) = window_ent.get::<SurfaceSpec>() else { - tracing::error!( - window_entity_id = %window_ent.uid(), - "Window entity does not have a {} component", - type_name::<SurfaceSpec>() - ); - continue; - }; - - let Some(surface) = surfaces.get(&surface_spec.id) else { - tracing::error!( - window_entity_id = %window_ent.uid(), - "Surface specified by window entity's {} component does not exist", - type_name::<SurfaceSpec>() - ); - continue; - }; - - let curr_gl_ctx = match gl_context.make_current(surface) { - Ok(curr_gl_ctx) => curr_gl_ctx, - Err(err) => { - tracing::error!("{err}"); - continue; - } - }; - - tracing::debug!( - model_entity_id=%model_ent_id, - renderer_ctx_entity_id=%renderer_ctx_ent_id, - "Cleaning up after model in renderer context" - ); - - let Some(removed_graphics_ctx_obj) = - graphics_ctx_objects.remove(&graphics_ctx_object_id) - else { - tracing::warn!( - model_entity_id=%model_ent_id, - "No graphics context object exists for model" - ); - continue; - }; - - #[allow(irrefutable_let_patterns)] - let GraphicsContextObject::Mesh { - mesh: mut graphics_mesh, - compatible_shader_program_obj_id: _, - } = removed_graphics_ctx_obj - else { - tracing::error!( - model_entity_id=%model_ent_id, - "Graphics context object for model is not a mesh" - ); - - continue; - }; - - graphics_mesh.destroy(&curr_gl_ctx); - } - } -} - -#[tracing::instrument(skip_all)] -fn handle_window_changed( - observe: Observe<Pair<Changed, Window>>, - entity_obtainer: EntityObtainer, -) -{ - for evt_match in &observe { - let window_ent = evt_match.get_ent_infallible(); - - tracing::trace!( - new_state = ?evt_match.get_changed_comp(), - "Handling window change" - ); - - let Some(surface_spec) = window_ent.get::<SurfaceSpec>() else { - continue; - }; - - let Some(renderer_ctx_ent_id) = window_ent - .get_matching_components( - Pair::builder() - .relation::<WindowUsingRendererCtx>() - .target_id(Wildcard::uid()) - .build() - .id(), - ) - .next() - .map(|comp_ref| comp_ref.id().target_entity()) - else { - continue; - }; - - let Some(renderer_ctx_ent) = entity_obtainer.get_entity(renderer_ctx_ent_id) - else { - tracing::error!("Renderer context entity does not exist"); - continue; - }; - - let Some(graphics_context) = renderer_ctx_ent.get::<GraphicsContext>() else { - tracing::error!( - "Renderer context entity does not have a GraphicsContext component" - ); - continue; - }; - - let Some(surface) = graphics_context.surfaces.get(&surface_spec.id) else { - tracing::error!( - window_entity_id = %window_ent.uid(), - "Surface specified by window entity's {} component does not exist", - type_name::<SurfaceSpec>() - ); - continue; - }; - - let Ok(current_graphics_context) = - graphics_context.gl_context.make_current(surface) - else { - tracing::error!("Failed to make graphics context current"); - continue; - }; - - if let Err(err) = set_viewport( - ¤t_graphics_context, - Vec2::default(), - evt_match.get_changed_comp().inner_size(), - ) { - tracing::error!("Failed to set viewport: {err}"); - } - } -} - -#[tracing::instrument(skip_all)] fn handle_window_removed(observe: Observe<Pair<Removed, Window>>, mut actions: Actions) { for evt_match in &observe { @@ -609,9 +416,11 @@ fn init_window_graphics( continue; }; - if let Err(err) = - set_viewport(&curr_gl_context, Vec2 { x: 0, y: 0 }, window.inner_size()) - { + if let Err(err) = gl_set_viewport( + &curr_gl_context, + &Vec2 { x: 0, y: 0 }.into(), + &window.inner_size().clone().into(), + ) { tracing::error!("Failed to set viewport: {err}"); } @@ -1090,6 +899,48 @@ fn handle_commands( tracing::error!("Failed to update mesh: {err}"); } } + RendererCommand::RemoveMesh(mesh_object_id) => { + let Some(curr_gl_ctx) = &opt_curr_gl_ctx else { + tracing::error!("No GL context is current"); + continue; + }; + + let Some(mesh_graphics_ctx_obj_key) = renderer_object_store + .remove(&mesh_object_id) + .map(|obj| obj.as_raw()) + else { + tracing::error!( + object_id=?mesh_object_id, + "Object store does not contain a mesh object with this ID" + ); + continue; + }; + + let Some(mesh_graphics_ctx_obj) = + graphics_ctx_objects.remove(&mesh_graphics_ctx_obj_key) + else { + tracing::error!( + object_id=?mesh_object_id, + key=mesh_graphics_ctx_obj_key, + "Graphics context does not contain a mesh object with this key" + ); + continue; + }; + + #[allow(irrefutable_let_patterns)] + let GraphicsContextObject::Mesh { mesh: mut graphics_mesh, .. } = + mesh_graphics_ctx_obj + else { + tracing::error!( + object_id=?mesh_object_id, + key=mesh_graphics_ctx_obj_key, + "Graphics context object with this key is not a mesh" + ); + continue; + }; + + graphics_mesh.destroy(curr_gl_ctx); + } RendererCommand::DrawMesh(mesh_object_id, draw_mesh_opts) => { let Some(curr_gl_ctx) = &opt_curr_gl_ctx else { tracing::error!("No GL context is current"); @@ -1256,6 +1107,23 @@ fn handle_commands( ); } } + RendererCommand::SetViewport { + size: viewport_size, + position: viewport_position, + } => { + let Some(curr_gl_ctx) = &opt_curr_gl_ctx else { + tracing::error!("No GL context is current"); + continue; + }; + + if let Err(err) = gl_set_viewport( + curr_gl_ctx, + &viewport_position.into(), + &viewport_size.into(), + ) { + tracing::error!("Failed to set viewport: {err}"); + } + } } } } @@ -1323,23 +1191,6 @@ fn create_texture_object( Ok(()) } -fn set_viewport( - current_context: &CurrentContextWithFns<'_>, - position: Vec2<u32>, - size: &Dimens<u32>, -) -> Result<(), GlSetViewportError> -{ - let position = - opengl_bindings::data_types::Vec2::<u32> { x: position.x, y: position.y }; - - let size = opengl_bindings::data_types::Dimens::<u32> { - width: size.width, - height: size.height, - }; - - opengl_bindings::misc::set_viewport(current_context, &position, &size) -} - fn draw_mesh( current_context: &CurrentContextWithFns<'_>, graphics_mesh: &GraphicsMesh, |
