From 8decddbf145ca51de22ce747e8bb6c99c0a44a46 Mon Sep 17 00:00:00 2001 From: IllusionMan1212 Date: Thu, 2 Nov 2023 22:02:00 +0200 Subject: [PATCH] textures: add support for emission textures --- TODO.md | 1 + shaders/frag.glsl | 12 ++++++++++++ src/importer/obj.rs | 3 ++- src/mesh.rs | 11 +++++++---- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/TODO.md b/TODO.md index ddf8530..5301928 100644 --- a/TODO.md +++ b/TODO.md @@ -34,5 +34,6 @@ - [ ] Move the invisible point lights to be around selected object from all sides so it's nicely illuminated - [x] Shortcuts/keybinds window under the 'Help' menu item - [x] Texture support (basic, but it's there) + - [ ] Make model loading async and show a loading indicator, instead of blocking the main thread - [ ] Bring back the regular camera movement (can maybe be a switch between them) (for later) diff --git a/shaders/frag.glsl b/shaders/frag.glsl index cae6e29..4af4737 100644 --- a/shaders/frag.glsl +++ b/shaders/frag.glsl @@ -9,6 +9,7 @@ struct Material { sampler2D texture_diffuse; sampler2D texture_specular; sampler2D texture_ambient; + sampler2D texture_emission; vec3 ambient; vec3 diffuse; @@ -61,6 +62,7 @@ uniform DirLight dirLight; uniform PointLight pointLights[NR_POINT_LIGHTS]; uniform SpotLight spotLight; uniform bool useTextures; +uniform bool hasEmissionTexture; vec3 CalculateDirLight(DirLight light, vec3 normal, vec3 viewDir) { vec3 lightDir = normalize(-light.direction); @@ -181,6 +183,12 @@ vec3 CalculateSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir void main() { + // discard completely transparent fragments, such as the ones used in + // leaves or grass textures + if (texture(material.texture_diffuse, texCoords).a == 0.0) { + discard; + } + vec3 norm = normalize(fragNormals); vec3 viewDir = normalize(viewPos - fragPos); @@ -194,6 +202,10 @@ void main() result += CalculateSpotLight(spotLight, norm, fragPos, viewDir); + if (useTextures && hasEmissionTexture) { + result += texture(material.texture_emission, texCoords).rgb; + } + FragColor = vec4(result, material.opacity); } diff --git a/src/importer/obj.rs b/src/importer/obj.rs index a762a0b..2baf7bc 100644 --- a/src/importer/obj.rs +++ b/src/importer/obj.rs @@ -144,7 +144,8 @@ fn parse_mtl(path: &PathBuf, obj_textures: &mut HashMap) -> Res } Some(MtlToken::DiffuseTexture) | Some(MtlToken::AmbientTexture) - | Some(MtlToken::SpecularTexture) => { + | Some(MtlToken::SpecularTexture) + | Some(MtlToken::EmissiveTexture) => { let tex_type = TextureType::from_material_str(token).unwrap(); let name = iter.next().unwrap().to_string(); diff --git a/src/mesh.rs b/src/mesh.rs index dcf7564..906b718 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -126,7 +126,7 @@ impl Mesh { shader.set_3fv("material.ambient", self.material.ambient_color); shader.set_3fv("material.diffuse", self.material.diffuse_color); shader.set_3fv("material.specular", self.material.specular_color); - shader.set_float("material.shininess", 32.0); + shader.set_float("material.shininess", self.material.specular_exponent); shader.set_float("material.opacity", self.material.opacity); } else { shader.set_3fv("material.ambient", glm::vec3(0.0, 0.0, 0.0)); @@ -136,6 +136,7 @@ impl Mesh { if show_textures { shader.set_bool("useTextures", self.material.textures.len() > 0); for (i, tex) in self.material.textures.iter().enumerate() { + shader.set_bool("hasEmissionTexture", false); unsafe { gl::ActiveTexture(gl::TEXTURE0 + i as u32); match tex.typ { @@ -146,11 +147,13 @@ impl Mesh { shader.set_int("material.texture_diffuse", i as i32); }, TextureType::Specular => { - shader.set_int("material.texture_specular{}", i as i32); + shader.set_int("material.texture_specular", i as i32); }, - _ => { - warn!("Unsupported texture type: {:?}", tex.typ); + TextureType::Emissive => { + shader.set_int("material.texture_emission", i as i32); + shader.set_bool("hasEmissionTexture", true); }, + _ => {}, } gl::BindTexture(gl::TEXTURE_2D, tex.id);