From f449efbebd6f04a94648c8c662191845a6ed9472 Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Tue, 16 Apr 2024 15:55:04 -0400 Subject: Point lights --- src/shader.rs | 38 +++++++++++++++++++++++++++++++++++ src/state.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 96 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/shader.rs b/src/shader.rs index 6e58bb7..ec0f24b 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -70,6 +70,8 @@ impl Shader { } else { log::warn!("failed to get location for uniform: {}", active.name); } + } else { + log::warn!("failed to get active uniform for index: {}", index); } } @@ -105,6 +107,30 @@ impl Shader { unsafe { ctx.gl.uniform_1_f32(Some(loc), val) } } } + + pub fn set_vec2(&self, ctx: &context::Context, name: &str, val: &glam::Vec2) { + if let Some(loc) = self.uniforms.get(name) { + unsafe { + ctx.gl.uniform_2_f32( + Some(loc), + val.x, + val.y, + ); + } + } + } + + pub fn set_vec2_array(&self, ctx: &context::Context, name: &str, val: &[glam::Vec2]) { + if let Some(loc) = self.uniforms.get(name) { + let vs: Vec = val.iter().flat_map(|v| [v.x, v.y]).collect(); + unsafe { + ctx.gl.uniform_2_f32_slice( + Some(loc), + &vs, + ); + } + } + } pub fn set_vec3(&self, ctx: &context::Context, name: &str, val: &glam::Vec3) { if let Some(loc) = self.uniforms.get(name) { @@ -119,6 +145,18 @@ impl Shader { } } + pub fn set_vec3_array(&self, ctx: &context::Context, name: &str, val: &[glam::Vec3]) { + if let Some(loc) = self.uniforms.get(name) { + let vs: Vec = val.iter().flat_map(|v| [v.x, v.y, v.z]).collect(); + unsafe { + ctx.gl.uniform_3_f32_slice( + Some(loc), + &vs, + ); + } + } + } + pub fn set_vec4(&self, ctx: &context::Context, name: &str, val: &glam::Vec4) { if let Some(loc) = self.uniforms.get(name) { unsafe { diff --git a/src/state.rs b/src/state.rs index 7a9cdbe..7170a84 100644 --- a/src/state.rs +++ b/src/state.rs @@ -42,6 +42,12 @@ impl Keys { } } +pub struct PointLight { + pub pos: glam::Vec3, + pub color: glam::Vec3, + pub attenuation: glam::Vec2, +} + pub struct State { pub acc: f64, pub last: f64, @@ -56,7 +62,8 @@ pub struct State { pub projection: glam::Mat4, pub camera: (glam::Vec3, glam::Vec3, glam::Vec3), - pub lighting: (glam::Vec3, glam::Vec3), + pub lighting: (glam::Vec3, glam::Vec3, glam::Vec3), + pub point_lights: Vec, pub log: Vec<(u64, String)>, } @@ -98,9 +105,11 @@ impl State { ), camera: (glam::Vec3::new(0.0, 0.0, 0.0), glam::Vec3::new(0.0, 0.0, 1.0), glam::Vec3::new(0.0, 1.0, 0.0)), lighting: ( + glam::Vec3::new(1.0, 1.0, 1.0), glam::Vec3::new(1.0, 1.0, 1.0), glam::Vec3::new(1.0, -1.0, 1.0), ), + point_lights: Vec::new(), log: Vec::new(), } @@ -128,10 +137,31 @@ impl State { pub fn set_lighting( &mut self, _ctx: &context::Context, + ambient: &glam::Vec3, color: &glam::Vec3, dir: &glam::Vec3, ) { - self.lighting = (color.clone(), dir.clone()); + self.lighting = (ambient.clone(), color.clone(), dir.clone()); + } + + pub fn add_point_light( + &mut self, + _ctx: &context::Context, + pos: &glam::Vec3, + color: &glam::Vec3, + attenuation: &glam::Vec2, + ) { + self.point_lights.push( + PointLight { + pos: pos.clone(), + color: color.clone(), + attenuation: attenuation.clone(), + }, + ); + } + + pub fn clear_point_lights(&mut self, _ctx: &context::Context) { + self.point_lights.clear(); } pub fn view(&self) -> glam::Mat4 { @@ -148,15 +178,38 @@ impl State { shader.set_mat4(ctx, "view", &self.view()); shader.set_vec3( ctx, "light_ambient_color", - &glam::Vec3::new(1.0, 1.0, 1.0)); + &self.lighting.0, + ); shader.set_vec3( ctx, "light_dir_color", - &self.lighting.0, + &self.lighting.1, ); shader.set_vec3( ctx, "light_dir", - &self.lighting.1, + &self.lighting.2.normalize(), ); + let plc = self.point_lights.len().min(5); + shader.set_i32( + ctx, &format!("light_count"), + plc as _, + ); + if plc > 0 { + let lpos: Vec<_> = self.point_lights.iter().take(plc).map(|l| l.pos).collect(); + shader.set_vec3_array( + ctx, &format!("light_pos[0]"), + &lpos, + ); + let lcolor: Vec<_> = self.point_lights.iter().take(plc).map(|l| l.color).collect(); + shader.set_vec3_array( + ctx, &format!("light_color[0]"), + &lcolor, + ); + let lattenuation: Vec<_> = self.point_lights.iter().take(plc).map(|l| l.attenuation).collect(); + shader.set_vec2_array( + ctx, &format!("light_attenuation[0]"), + &lattenuation, + ); + } } pub fn bind_2d(&mut self, ctx: &context::Context, shader: &shader::Shader) { -- cgit v1.2.3