summaryrefslogtreecommitdiff
path: root/engine/src
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src')
-rw-r--r--engine/src/draw_flags.rs35
-rw-r--r--engine/src/renderer/opengl.rs195
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,
+ )
+ }
}
}