From 841cb0203b0af0e37fee29912b6aecb1747d9ec2 Mon Sep 17 00:00:00 2001 From: Piotr Date: Sat, 26 Sep 2020 20:37:13 +0200 Subject: [PATCH] Lights! --- resources/shaders/multiple_lights.fs | 7 ++- src/example_client.rs | 61 ++++++++++++++++++++--- src/gaia/light.rs | 72 ++++++++++++++++++++++++++++ src/gaia/mesh.rs | 9 ++++ src/gaia/mod.rs | 1 + 5 files changed, 141 insertions(+), 9 deletions(-) create mode 100644 src/gaia/light.rs diff --git a/resources/shaders/multiple_lights.fs b/resources/shaders/multiple_lights.fs index f49fba7..d3eac9f 100644 --- a/resources/shaders/multiple_lights.fs +++ b/resources/shaders/multiple_lights.fs @@ -60,7 +60,10 @@ vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); void main() -{ +{ + vec4 texColor = texture(material.diffuse, TexCoords); + if(texColor.a < 0.1) + discard; // properties vec3 norm = normalize(Normal); vec3 viewDir = normalize(viewPos - FragPos); @@ -77,7 +80,7 @@ void main() for(int i = 0; i < NR_POINT_LIGHTS; i++) result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); // phase 3: spot light - result += CalcSpotLight(spotLight, norm, FragPos, viewDir); + //result += CalcSpotLight(spotLight, norm, FragPos, viewDir); FragColor = vec4(result, 1.0); } diff --git a/src/example_client.rs b/src/example_client.rs index d3c404c..f929bb9 100644 --- a/src/example_client.rs +++ b/src/example_client.rs @@ -4,9 +4,11 @@ use crate::gaia::client::Client; use crate::gaia::components::{ModelComponent, Transform}; use crate::gaia::consts; use crate::gaia::engine::Engine; +use crate::gaia::light::*; use crate::gaia::sky::Sky; use crate::gaia::*; -use cgmath::{perspective, vec3, Deg, Matrix4, Point3}; +use cgmath::prelude::*; +use cgmath::{perspective, vec3, Deg, Matrix4, Point3, Vector3}; use imgui_glfw_rs::glfw; pub struct ExampleClient { @@ -14,6 +16,7 @@ pub struct ExampleClient { camera: Camera, shader: shader::Shader, sky: Sky, + point_lights: Vec, show_object_info: bool, show_camera_info: bool, object_info_id: i32, @@ -21,9 +24,19 @@ pub struct ExampleClient { impl ExampleClient { pub fn create() -> ExampleClient { - let sky; - unsafe { - sky = Sky::new(); + let sky = unsafe { Sky::new() }; + let pointLightPositions: [Vector3; 4] = [ + vec3(0.7, 5.0, 2.0), + vec3(2.3, 3.3, -4.0), + vec3(-4.0, 4.0, -12.0), + vec3(0.0, 2.0, -3.0), + ]; + let mut point_lights = vec![]; + for light in pointLightPositions.iter() { + point_lights.push(PointLight { + pos: *light, + ..PointLight::default() + }) } ExampleClient { object_info_id: 0, @@ -40,10 +53,11 @@ impl ExampleClient { ..Camera::default() }, shader: shader::Shader::from_file( - "resources/shaders/model_loading.vs", - "resources/shaders/model_loading.fs", + "resources/shaders/multiple_lights.vs", + "resources/shaders/multiple_lights.fs", ), sky: sky, + point_lights: point_lights, } } } @@ -85,10 +99,15 @@ impl Client for ExampleClient { }, model: cache.get_model_ext("resources/objects/tree/tree_6_c.obj", Some("tree_e.png")), }; - self.models = vec![tree, tree2, tree3, ground, robot]; + let ruins = ModelComponent { + transform: Transform::default(), + model: cache.get_model("resources/objects/ruins/ruins.obj"), + }; + self.models = vec![tree, tree2, tree3, ground, robot, ruins]; } unsafe fn draw(&mut self) { + use inline_tweak::*; self.shader.use_program(); // view/projection transformations @@ -101,6 +120,34 @@ impl Client for ExampleClient { let view = self.camera.get_view_matrix(); self.shader.set_mat4(c_str!("projection"), &projection); self.shader.set_mat4(c_str!("view"), &view); + self.shader + .set_vector3(c_str!("viewPos"), &self.camera.position.to_vec()); + self.shader.setFloat(c_str!("material.shininess"), 32.0); + + self.shader.set_vec3( + c_str!("dirLight.direction"), + tweak!(-0.3), + tweak!(-1.0), + tweak!(-0.3), + ); + self.shader.set_vec3( + c_str!("dirLight.ambient"), + tweak!(0.14), + tweak!(0.14), + tweak!(0.14), + ); + self.shader.set_vec3( + c_str!("dirLight.diffuse"), + tweak!(0.4), + tweak!(0.4), + tweak!(0.4), + ); + self.shader + .set_vec3(c_str!("dirLight.specular"), 0.5, 0.5, 0.5); + // point light 1 + for (i, v) in self.point_lights.iter().enumerate() { + v.shader_update(i, &self.shader); + } for model in self.models.iter() { model.draw(&self.shader); diff --git a/src/gaia/light.rs b/src/gaia/light.rs new file mode 100644 index 0000000..db74ac9 --- /dev/null +++ b/src/gaia/light.rs @@ -0,0 +1,72 @@ +use crate::gaia::shader::Shader; +use cgmath::{perspective, vec3, Deg, Matrix4, Point3, Vector3}; + +pub struct PointLight { + pub pos: Vector3, + pub ambient: Vector3, + pub diffuse: Vector3, + pub specular: Vector3, + pub constant: f32, + pub linear: f32, + pub quadratic: f32, +} + +impl PointLight { + pub unsafe fn shader_update(&self, i: usize, shader: &Shader) { + let mut id = format!("pointLights[{}].position\0", i); + shader.set_vector3( + std::ffi::CStr::from_bytes_with_nul_unchecked(id.as_bytes()), + &self.pos, + ); + id = format!("pointLights[{}].ambient\0", i); + shader.set_vec3( + std::ffi::CStr::from_bytes_with_nul_unchecked(id.as_bytes()), + self.ambient.x, + self.ambient.y, + self.ambient.z, + ); + id = format!("pointLights[{}].diffuse\0", i); + shader.set_vec3( + std::ffi::CStr::from_bytes_with_nul_unchecked(id.as_bytes()), + self.diffuse.x, + self.diffuse.y, + self.diffuse.z, + ); + id = format!("pointLights[{}].specular\0", i); + shader.set_vec3( + std::ffi::CStr::from_bytes_with_nul_unchecked(id.as_bytes()), + self.specular.x, + self.specular.y, + self.specular.z, + ); + id = format!("pointLights[{}].constant\0", i); + shader.setFloat( + std::ffi::CStr::from_bytes_with_nul_unchecked(id.as_bytes()), + self.constant, + ); + id = format!("pointLights[{}].linear\0", i); + shader.setFloat( + std::ffi::CStr::from_bytes_with_nul_unchecked(id.as_bytes()), + self.linear, + ); + id = format!("pointLights[{}].quadratic\0", i); + shader.setFloat( + std::ffi::CStr::from_bytes_with_nul_unchecked(id.as_bytes()), + self.quadratic, + ); + } +} + +impl Default for PointLight { + fn default() -> Self { + PointLight { + pos: vec3(0.0, 0.0, 0.0), + ambient: vec3(0.05, 0.05, 0.05), + diffuse: vec3(0.8, 0.8, 0.8), + specular: vec3(1.0, 1.0, 1.0), + constant: 1.0, + linear: 0.09, + quadratic: 0.032, + } + } +} diff --git a/src/gaia/mesh.rs b/src/gaia/mesh.rs index 6600904..6314d01 100644 --- a/src/gaia/mesh.rs +++ b/src/gaia/mesh.rs @@ -62,6 +62,15 @@ pub struct Mesh { EBO: u32, } +impl Drop for Mesh { + fn drop(&mut self) { + unsafe { + gl::DeleteVertexArrays(1, &self.VAO); + gl::DeleteBuffers(1, &self.VBO); + } + } +} + impl Mesh { pub fn new(vertices: Vec, indices: Vec, textures: Vec) -> Mesh { let mut mesh = Mesh { diff --git a/src/gaia/mod.rs b/src/gaia/mod.rs index be2ac52..3094a15 100644 --- a/src/gaia/mod.rs +++ b/src/gaia/mod.rs @@ -7,6 +7,7 @@ pub mod client; pub mod components; pub mod consts; pub mod engine; +pub mod light; pub mod mesh; pub mod model; pub mod shader;