diff options
-rw-r--r-- | engine/src/lighting.rs | 5 | ||||
-rw-r--r-- | engine/src/renderer/opengl.rs | 40 |
2 files changed, 25 insertions, 20 deletions
diff --git a/engine/src/lighting.rs b/engine/src/lighting.rs index 48adb0e..09dd980 100644 --- a/engine/src/lighting.rs +++ b/engine/src/lighting.rs @@ -10,7 +10,8 @@ builder! { #[non_exhaustive] pub struct PointLight { - pub position: Vec3<f32>, + /// Position in local space. + pub local_position: Vec3<f32>, pub diffuse: Color<f32>, pub specular: Color<f32>, pub attenuation_params: AttenuationParams, @@ -31,7 +32,7 @@ impl Default for PointLight fn default() -> Self { Self { - position: Vec3::default(), + local_position: Vec3::default(), diffuse: Color { red: 0.5, green: 0.5, blue: 0.5 }, specular: Color { red: 1.0, green: 1.0, blue: 1.0 }, attenuation_params: AttenuationParams::default(), diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index 18b0041..00ce2f8 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -3,12 +3,12 @@ use std::collections::HashMap; use std::ffi::{c_void, CString}; use std::io::{Error as IoError, ErrorKind as IoErrorKind}; -use std::ops::Deref; use std::path::Path; use std::process::abort; use ecs::actions::Actions; use ecs::component::local::Local; +use ecs::component::Handle as ComponentHandle; use ecs::phase::START as START_PHASE; use ecs::query::term::Without; use ecs::sole::Single; @@ -137,7 +137,7 @@ fn initialize(window: Single<Window>) #[allow(clippy::too_many_arguments)] fn render( query: Query<RenderableEntity<'_>, (Without<NoDraw>,)>, - point_light_query: Query<(&PointLight,)>, + point_light_query: Query<(&PointLight, &Position)>, directional_lights: Query<(&DirectionalLight,)>, camera_query: Query<(&Camera, &Position, &ActiveCamera)>, window: Single<Window>, @@ -151,11 +151,6 @@ fn render( return; }; - let point_lights = point_light_query - .iter() - .map(|(point_light,)| point_light) - .collect::<Vec<_>>(); - let directional_lights = directional_lights.iter().collect::<Vec<_>>(); let GlobalGlObjects { @@ -204,7 +199,7 @@ fn render( &material_flags, &global_light, shader_program, - point_lights.as_slice(), + (point_light_query.iter(), point_light_query.iter().count()), directional_lights .iter() .map(|(dir_light,)| &**dir_light) @@ -472,19 +467,26 @@ fn apply_transformation_matrices( gl_shader_program.set_uniform(c"projection", &proj_matrix); } -fn apply_light<PointLightHolder>( +fn apply_light<'point_light>( material: &Material, material_flags: &MaterialFlags, global_light: &GlobalLight, gl_shader_program: &mut GlShaderProgram, - point_lights: &[PointLightHolder], + (point_light_iter, point_light_cnt): ( + impl Iterator< + Item = ( + ComponentHandle<'point_light, PointLight>, + ComponentHandle<'point_light, Position>, + ), + >, + usize, + ), directional_lights: &[&DirectionalLight], camera_pos: &Position, -) where - PointLightHolder: Deref<Target = PointLight>, +) { debug_assert!( - point_lights.len() < 64, + point_light_cnt < 64, "Shader cannot handle more than 64 point lights" ); @@ -516,30 +518,32 @@ fn apply_light<PointLightHolder>( gl_shader_program .set_uniform(c"directional_light_cnt", &(directional_lights.len() as i32)); - for (point_light_index, point_light) in point_lights.iter().enumerate() { + for (point_light_index, (point_light, point_light_world_pos)) in + point_light_iter.enumerate() + { gl_shader_program.set_uniform( &create_light_uniform_name("point_lights", point_light_index, "position"), - &point_light.position, + &(point_light_world_pos.position + point_light.local_position), ); set_light_phong_uniforms( gl_shader_program, "point_lights", point_light_index, - &**point_light, + &*point_light, ); set_light_attenuation_uniforms( gl_shader_program, "point_lights", point_light_index, - point_light, + &*point_light, ); } // There probably won't be more than 2147483648 point lights #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] - gl_shader_program.set_uniform(c"point_light_cnt", &(point_lights.len() as i32)); + gl_shader_program.set_uniform(c"point_light_cnt", &(point_light_cnt as i32)); gl_shader_program.set_uniform( c"material.ambient", |