summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shader.rs38
-rw-r--r--src/state.rs63
2 files changed, 96 insertions, 5 deletions
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<f32> = 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<f32> = 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<PointLight>,
pub log: Vec<(u64, String)>,
}
@@ -99,8 +106,10 @@ 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) {