diff options
Diffstat (limited to 'engine')
-rw-r--r-- | engine/src/draw_flags.rs | 35 | ||||
-rw-r--r-- | engine/src/renderer/opengl.rs | 195 |
2 files changed, 68 insertions, 162 deletions
diff --git a/engine/src/draw_flags.rs b/engine/src/draw_flags.rs index 1352fe2..c8c11c9 100644 --- a/engine/src/draw_flags.rs +++ b/engine/src/draw_flags.rs @@ -1,11 +1,7 @@ -use std::sync::atomic::{AtomicUsize, Ordering}; - use ecs::Component; use crate::util::builder; -static CURRENT_BUNDLE_ID: AtomicUsize = AtomicUsize::new(0); - builder! { /// Flags for how a object should be drawn. #[builder(name = Builder, derives = (Debug, Default, Clone))] @@ -51,34 +47,3 @@ pub enum PolygonModeFace #[default] FrontAndBack, } - -/// Metadata for how a object should be drawn together with other objects. -#[derive(Debug, Clone, Component)] -pub struct DrawingBundled -{ - pub bundle_id: DrawingBundleId, - pub order: usize, -} - -/// The ID of a object drawing bundle. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct DrawingBundleId -{ - inner: usize, -} - -impl DrawingBundleId -{ - /// Creates a new unique bundle ID. - pub fn new() -> Self - { - Self { - inner: CURRENT_BUNDLE_ID.fetch_add(1, Ordering::Relaxed), - } - } - - pub fn inner(&self) -> usize - { - self.inner - } -} diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index 53e2a4b..108c504 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -7,17 +7,14 @@ use std::process::abort; use cstr::cstr; use ecs::component::local::Local; -use ecs::component::Sequence as ComponentSequence; -use ecs::query::options::{Not, With as WithComponent}; use ecs::sole::Single; -use ecs::system::{ComponentRefMut, Into as _, System}; -use ecs::tuple::{Pop, With}; +use ecs::system::{Into as _, System}; use ecs::{Component, Query}; use crate::camera::Camera; use crate::color::Color; use crate::data_types::dimens::Dimens; -use crate::draw_flags::{DrawFlags, DrawingBundled, PolygonModeConfig}; +use crate::draw_flags::{DrawFlags, PolygonModeConfig}; use crate::event::{Present as PresentEvent, Start as StartEvent}; use crate::lighting::{DirectionalLight, GlobalLight, PointLight}; use crate::material::{Flags as MaterialFlags, Material}; @@ -98,19 +95,16 @@ fn initialize(window: Single<Window>) enable(Capability::MultiSample); } -type EntityToRender = ( - Mesh, - ShaderProgram, - Material, - Option<MaterialFlags>, - Option<Position>, - Option<Scale>, - Option<DrawFlags>, -); - fn render( - query: Query<EntityToRender, Not<WithComponent<DrawingBundled>>>, - query_bundled: Query<<EntityToRender as With<DrawingBundled>>::With>, + query: Query<( + Mesh, + ShaderProgram, + Material, + Option<MaterialFlags>, + Option<Position>, + Option<Scale>, + Option<DrawFlags>, + )>, point_light_query: Query<(PointLight,)>, directional_lights: Query<(DirectionalLight,)>, camera_query: Query<(Camera,)>, @@ -145,128 +139,75 @@ fn render( clear_buffers(BufferClearMask::COLOR | BufferClearMask::DEPTH); - let mut bundles: Vec<Vec<(usize, _)>> = Vec::new(); - - bundles.resize_with( - query_bundled - .iter() - .map(|(.., bundled)| bundled.bundle_id.inner() as usize + 1) - .max() - .unwrap_or_default(), - || Vec::new(), - ); - - for entity_to_render in &query_bundled { - let (entity_to_render, bundled) = entity_to_render.pop(); - - bundles - .get_mut(bundled.bundle_id.inner()) - .unwrap() - .push((bundled.order, entity_to_render)); - } - - for bundle in &mut bundles { - bundle.sort_by(|(order_a, _), (order_b, _)| order_a.cmp(order_b)); - } - - for entity_to_render in query.iter().chain( - bundles - .into_iter() - .flatten() - .map(|(_, entity_to_render)| entity_to_render), - ) { - draw_single( - entity_to_render, + for (mesh, shader_program, material, material_flags, position, scale, draw_flags) in + &query + { + let material_flags = material_flags + .map(|material_flags| material_flags.clone()) + .unwrap_or_default(); + + let shader_program = gl_shader_programs + .entry(shader_program.u64_hash()) + .or_insert_with(|| create_gl_shader_program(&shader_program).unwrap()); + + apply_transformation_matrices( + Transformation { + position: position.map(|pos| *pos).unwrap_or_default().position, + scale: scale.map(|scale| *scale).unwrap_or_default().scale, + }, + shader_program, &camera, - &point_lights, - gl_shader_programs, - gl_textures, - &window, - &global_light, - &directional_lights, + window.size().expect("Failed to get window size"), ); - } -} -fn draw_single( - entity_to_render: <EntityToRender as ComponentSequence>::Refs<'_>, - camera: &Camera, - point_lights: &[ComponentRefMut<PointLight>], - gl_shader_programs: &mut HashMap<u64, GlShaderProgram>, - gl_textures: &mut HashMap<TextureId, GlTexture>, - window: &Window, - global_light: &GlobalLight, - directional_lights: &[(ComponentRefMut<DirectionalLight>,)], -) -{ - let (mesh, shader_program, material, material_flags, position, scale, draw_flags) = - entity_to_render; - - let material_flags = material_flags - .map(|material_flags| material_flags.clone()) - .unwrap_or_default(); - - let shader_program = gl_shader_programs - .entry(shader_program.u64_hash()) - .or_insert_with(|| create_gl_shader_program(&shader_program).unwrap()); - - apply_transformation_matrices( - Transformation { - position: position.map(|pos| *pos).unwrap_or_default().position, - scale: scale.map(|scale| *scale).unwrap_or_default().scale, - }, - shader_program, - &camera, - window.size().expect("Failed to get window size"), - ); - - apply_light( - &material, - &material_flags, - &global_light, - shader_program, - point_lights, - directional_lights - .iter() - .map(|(dir_light,)| &**dir_light) - .collect::<Vec<_>>() - .as_slice(), - &camera, - ); + apply_light( + &material, + &material_flags, + &global_light, + shader_program, + point_lights.as_slice(), + directional_lights + .iter() + .map(|(dir_light,)| &**dir_light) + .collect::<Vec<_>>() + .as_slice(), + &camera, + ); - for texture in &material.textures { - let gl_texture = gl_textures - .entry(texture.id()) - .or_insert_with(|| create_gl_texture(texture)); + for texture in &material.textures { + let gl_texture = gl_textures + .entry(texture.id()) + .or_insert_with(|| create_gl_texture(texture)); - let texture_unit = - TextureUnit::from_texture_id(texture.id()).unwrap_or_else(|| { - panic!("Texture id {} is a invalid texture unit", texture.id()); - }); + let texture_unit = + TextureUnit::from_texture_id(texture.id()).unwrap_or_else(|| { + panic!("Texture id {} is a invalid texture unit", texture.id()); + }); - set_active_texture_unit(texture_unit); + set_active_texture_unit(texture_unit); - gl_texture.bind(); - } + gl_texture.bind(); + } - shader_program.activate(); + shader_program.activate(); - if let Some(draw_flags) = &draw_flags { - crate::opengl::set_polygon_mode( - draw_flags.polygon_mode_config.face, - draw_flags.polygon_mode_config.mode, - ) - } + if let Some(draw_flags) = &draw_flags { + crate::opengl::set_polygon_mode( + draw_flags.polygon_mode_config.face, + draw_flags.polygon_mode_config.mode, + ) + } - draw_mesh(&mesh); + draw_mesh(&mesh); - if draw_flags.is_some() { - let default_polygon_mode_config = PolygonModeConfig::default(); + if draw_flags.is_some() { + let default_polygon_mode_config = PolygonModeConfig::default(); - crate::opengl::set_polygon_mode( - default_polygon_mode_config.face, - default_polygon_mode_config.mode, - ) + crate::opengl::set_polygon_mode( + default_polygon_mode_config.face, + default_polygon_mode_config.mode, + ) + } } } |