mirror of
https://github.com/IllusionMan1212/3dobs.git
synced 2026-10-24 10:12:35 +00:00
WIP: normal maps
This commit is contained in:
@@ -3,3 +3,4 @@
|
||||
3rdparty/*/target
|
||||
models/**/*
|
||||
3dobs.log
|
||||
capture-*
|
||||
|
||||
@@ -35,5 +35,9 @@
|
||||
- [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
|
||||
- [ ] Multi-thread the texture loading and then join all threads before finishing the model loading func
|
||||
- [ ] (BUG) Loading the Kairi model creates a weird red specular on it, and a weird blue specular on the nier model. I imagine other models are also affected
|
||||
- [ ] Add support for .fbx (if it's an easy enough format, otherwise we'll look into something else)
|
||||
- [ ] Draw a gizmo thingy for the light sources in the viewport
|
||||
|
||||
- [ ] Bring back the regular camera movement (can maybe be a switch between them) (for later)
|
||||
|
||||
+21
-9
@@ -2,6 +2,7 @@
|
||||
in vec3 fragNormals;
|
||||
in vec3 fragPos;
|
||||
in vec2 texCoords;
|
||||
in mat3 fragTBN;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
@@ -10,6 +11,7 @@ struct Material {
|
||||
sampler2D texture_specular;
|
||||
sampler2D texture_ambient;
|
||||
sampler2D texture_emission;
|
||||
sampler2D texture_normal;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
@@ -63,6 +65,7 @@ uniform PointLight pointLights[NR_POINT_LIGHTS];
|
||||
uniform SpotLight spotLight;
|
||||
uniform bool useTextures;
|
||||
uniform bool hasEmissionTexture;
|
||||
uniform bool hasNormalTexture;
|
||||
|
||||
vec3 CalculateDirLight(DirLight light, vec3 normal, vec3 viewDir) {
|
||||
vec3 lightDir = normalize(-light.direction);
|
||||
@@ -83,9 +86,9 @@ vec3 CalculateDirLight(DirLight light, vec3 normal, vec3 viewDir) {
|
||||
vec3 specular = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
if (useTextures) {
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords)) * material.ambient;
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords)) * material.diffuse;
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords)) * material.specular;
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords));
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords));
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords));
|
||||
} else {
|
||||
ambient = light.ambient * material.ambient;
|
||||
diffuse = light.diffuse * (diff * material.diffuse);
|
||||
@@ -118,9 +121,9 @@ vec3 CalculatePointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewD
|
||||
vec3 specular = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
if (useTextures) {
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords)) * material.ambient;
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords)) * material.diffuse;
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords)) * material.specular;
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords));
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords));
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords));
|
||||
} else {
|
||||
ambient = light.ambient * material.ambient;
|
||||
diffuse = light.diffuse * (diff * material.diffuse);
|
||||
@@ -162,9 +165,9 @@ vec3 CalculateSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir
|
||||
vec3 specular = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
if (useTextures) {
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords)) * material.ambient;
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords)) * material.diffuse;
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords)) * material.specular;
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords));
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords));
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords));
|
||||
} else {
|
||||
ambient = light.ambient * material.ambient;
|
||||
diffuse = light.diffuse * (diff * material.diffuse);
|
||||
@@ -190,6 +193,14 @@ void main()
|
||||
}
|
||||
|
||||
vec3 norm = normalize(fragNormals);
|
||||
|
||||
// use normal map if available
|
||||
if (useTextures && hasNormalTexture) {
|
||||
vec3 normal = texture(material.texture_normal, texCoords).rgb;
|
||||
normal = normal * 2.0 - 1.0;
|
||||
norm = normalize(fragTBN * normal);
|
||||
}
|
||||
|
||||
vec3 viewDir = normalize(viewPos - fragPos);
|
||||
|
||||
// direction light
|
||||
@@ -202,6 +213,7 @@ void main()
|
||||
|
||||
result += CalculateSpotLight(spotLight, norm, fragPos, viewDir);
|
||||
|
||||
// emission
|
||||
if (useTextures && hasEmissionTexture) {
|
||||
result += texture(material.texture_emission, texCoords).rgb;
|
||||
}
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec2 aTexCoords;
|
||||
layout (location = 3) in vec3 aTangent;
|
||||
layout (location = 4) in vec3 aBitangent;
|
||||
out vec3 fragNormals;
|
||||
out vec3 fragPos;
|
||||
out vec2 texCoords;
|
||||
out mat3 fragTBN;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
@@ -19,7 +22,14 @@ void main()
|
||||
fragNormals = normalMatrix * aNormal;
|
||||
else
|
||||
fragNormals = mat3(transpose(inverse(model))) * aNormal;
|
||||
|
||||
vec3 T = normalize(vec3(model * vec4(aTangent, 0.0)));
|
||||
vec3 B = normalize(vec3(model * vec4(aBitangent, 0.0)));
|
||||
vec3 N = normalize(vec3(model * vec4(aNormal, 0.0)));
|
||||
mat3 TBN = mat3(T, B, N);
|
||||
|
||||
fragPos = vec3(model * vec4(aPos, 1.0));
|
||||
texCoords = aTexCoords;
|
||||
fragTBN = TBN;
|
||||
}
|
||||
|
||||
|
||||
+56
-8
@@ -19,14 +19,62 @@ impl AABB {
|
||||
let mut ebo = 0;
|
||||
|
||||
let vertices = vec![
|
||||
Vertex { position: glm::vec3(min.x, min.y, min.z), tex_coords: glm::vec2(0.0, 0.0), normal: glm::vec3(0.0, 0.0, 0.0) },
|
||||
Vertex { position: glm::vec3(max.x, min.y, min.z), tex_coords: glm::vec2(1.0, 0.0), normal: glm::vec3(0.0, 0.0, 0.0) },
|
||||
Vertex { position: glm::vec3(max.x, max.y, min.z), tex_coords: glm::vec2(1.0, 1.0), normal: glm::vec3(0.0, 0.0, 0.0) },
|
||||
Vertex { position: glm::vec3(min.x, max.y, min.z), tex_coords: glm::vec2(0.0, 1.0), normal: glm::vec3(0.0, 0.0, 0.0) },
|
||||
Vertex { position: glm::vec3(min.x, min.y, max.z), tex_coords: glm::vec2(0.0, 0.0), normal: glm::vec3(0.0, 0.0, 0.0) },
|
||||
Vertex { position: glm::vec3(max.x, min.y, max.z), tex_coords: glm::vec2(1.0, 0.0), normal: glm::vec3(0.0, 0.0, 0.0) },
|
||||
Vertex { position: glm::vec3(max.x, max.y, max.z), tex_coords: glm::vec2(1.0, 1.0), normal: glm::vec3(0.0, 0.0, 0.0) },
|
||||
Vertex { position: glm::vec3(min.x, max.y, max.z), tex_coords: glm::vec2(0.0, 1.0), normal: glm::vec3(0.0, 0.0, 0.0) },
|
||||
Vertex {
|
||||
position: glm::vec3(min.x, min.y, min.z),
|
||||
tex_coords: glm::vec2(0.0, 0.0),
|
||||
normal: glm::vec3(0.0, 0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Vertex {
|
||||
position: glm::vec3(max.x, min.y, min.z),
|
||||
tex_coords: glm::vec2(1.0, 0.0),
|
||||
normal: glm::vec3(0.0, 0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Vertex {
|
||||
position: glm::vec3(max.x, max.y, min.z),
|
||||
tex_coords: glm::vec2(1.0, 1.0),
|
||||
normal: glm::vec3(0.0, 0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Vertex {
|
||||
position: glm::vec3(min.x, max.y, min.z),
|
||||
tex_coords: glm::vec2(0.0, 1.0),
|
||||
normal: glm::vec3(0.0, 0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Vertex {
|
||||
position: glm::vec3(min.x, min.y, max.z),
|
||||
tex_coords: glm::vec2(0.0, 0.0),
|
||||
normal: glm::vec3(0.0, 0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Vertex {
|
||||
position: glm::vec3(max.x, min.y, max.z),
|
||||
tex_coords: glm::vec2(1.0, 0.0),
|
||||
normal: glm::vec3(0.0, 0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Vertex {
|
||||
position: glm::vec3(max.x, max.y, max.z),
|
||||
tex_coords: glm::vec2(1.0, 1.0),
|
||||
normal: glm::vec3(0.0, 0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Vertex {
|
||||
position: glm::vec3(min.x, max.y, max.z),
|
||||
tex_coords: glm::vec2(0.0, 1.0),
|
||||
normal: glm::vec3(0.0, 0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
];
|
||||
|
||||
let indices = vec![
|
||||
|
||||
+4
-1
@@ -25,7 +25,10 @@ impl TextureType {
|
||||
"map_Kd" => Some(TextureType::Diffuse),
|
||||
"map_Ks" => Some(TextureType::Specular),
|
||||
"map_Ns" => Some(TextureType::SpecularHighlight),
|
||||
"map_bump" => Some(TextureType::Bump),
|
||||
"map_Bump" => Some(TextureType::Bump),
|
||||
"bump" => Some(TextureType::Bump),
|
||||
"norm" => Some(TextureType::Bump),
|
||||
"map_Kn" => Some(TextureType::Bump),
|
||||
"map_d" => Some(TextureType::Displacement),
|
||||
"decal" => Some(TextureType::Decal),
|
||||
"refl" => Some(TextureType::Reflection),
|
||||
|
||||
+174
-8
@@ -1,6 +1,6 @@
|
||||
use std::{io::{BufReader, BufRead}, collections::HashMap, path::PathBuf};
|
||||
|
||||
use log::{error, warn, trace};
|
||||
use log::{error, warn, trace, info};
|
||||
|
||||
use crate::{mesh::Vertex, aabb::AABB, importer::{ObjMesh, Object, Material, Texture, TextureType}};
|
||||
|
||||
@@ -77,7 +77,11 @@ impl MtlToken {
|
||||
"map_Ks" => Some(MtlToken::SpecularTexture),
|
||||
"map_Ns" => Some(MtlToken::SpecularHighlightTexture),
|
||||
"map_Ke" => Some(MtlToken::EmissiveTexture),
|
||||
"map_bump" => Some(MtlToken::BumpTexture),
|
||||
"map_Bump" => Some(MtlToken::BumpTexture),
|
||||
"bump" => Some(MtlToken::BumpTexture),
|
||||
// "map_Kn" => Some(MtlToken::BumpTexture), // non-standard, we don't
|
||||
// yet know if it specifies a bump parameter so we let it log a warning
|
||||
"norm" => Some(MtlToken::BumpTexture),
|
||||
"map_d" => Some(MtlToken::DisplacementTexture),
|
||||
"decal" => Some(MtlToken::DecalTexture),
|
||||
"refl" => Some(MtlToken::ReflectionTexture),
|
||||
@@ -174,7 +178,49 @@ fn parse_mtl(path: &PathBuf, obj_textures: &mut HashMap<String, Texture>) -> Res
|
||||
tex
|
||||
};
|
||||
|
||||
mat_textures.push(mat);
|
||||
mat_textures.push(tex);
|
||||
}
|
||||
Some(MtlToken::BumpTexture) => {
|
||||
// norm doesn't specify a bump parameter
|
||||
// map_bump does
|
||||
|
||||
let mut bm = 1.0;
|
||||
let mut name = String::new();
|
||||
|
||||
let next = iter.next().unwrap();
|
||||
if next == "-bm" {
|
||||
bm = iter.next().unwrap().parse::<f32>().unwrap();
|
||||
name = iter.next().unwrap().to_string();
|
||||
} else {
|
||||
name = next.to_string();
|
||||
|
||||
if let Some(possible_bump) = iter.next() {
|
||||
if possible_bump == "-bm" {
|
||||
bm = iter.next().unwrap().parse::<f32>().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let tex = if obj_textures.contains_key(&name) {
|
||||
let mut tex = obj_textures.get(&name).unwrap().clone();
|
||||
tex.typ = TextureType::Bump;
|
||||
tex
|
||||
} else {
|
||||
let path = path.parent().unwrap().join(&name);
|
||||
let tex = match Texture::new(path, TextureType::Bump) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Failed to load texture: {}", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
obj_textures.insert(name, tex.clone());
|
||||
tex
|
||||
};
|
||||
|
||||
// TODO: use bm somewhere
|
||||
mat_textures.push(tex);
|
||||
}
|
||||
_ => { warn!("Unhandled material token: {}", token) },
|
||||
}
|
||||
@@ -335,7 +381,9 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
vertices.push(Vertex{
|
||||
position: *temp_vertices.get(vert as usize).unwrap(),
|
||||
normal: *normals.get(normal as usize).unwrap(),
|
||||
tex_coords: glm::vec2(0.0, 0.0)
|
||||
tex_coords: glm::vec2(0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0)
|
||||
});
|
||||
} else if vert.matches("/").count() == 2 {
|
||||
let mut it = vert.split("/");
|
||||
@@ -360,7 +408,9 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
vertices.push(Vertex{
|
||||
position: *temp_vertices.get(vertex as usize).unwrap(),
|
||||
normal: *normals.get(normal as usize).unwrap(),
|
||||
tex_coords: *tex_coords.get(t_coords as usize).unwrap()
|
||||
tex_coords: *tex_coords.get(t_coords as usize).unwrap(),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0)
|
||||
});
|
||||
} else if vert.matches("/").count() == 1 {
|
||||
let mut it = vert.split("/");
|
||||
@@ -379,7 +429,9 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
vertices.push(Vertex{
|
||||
position: *temp_vertices.get(vertex as usize).unwrap(),
|
||||
normal: calculated_normal,
|
||||
tex_coords: *tex_coords.get(t_coords as usize).unwrap()
|
||||
tex_coords: *tex_coords.get(t_coords as usize).unwrap(),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0)
|
||||
});
|
||||
} else {
|
||||
let mut vert = vert.parse::<i32>().unwrap();
|
||||
@@ -392,10 +444,12 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
position: *temp_vertices.get(vert as usize).unwrap(),
|
||||
normal: calculated_normal,
|
||||
tex_coords: glm::vec2(0.0, 0.0),
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0)
|
||||
});
|
||||
}
|
||||
|
||||
// Triangulate faces. 2 triangles per face
|
||||
// Triangulate faces
|
||||
if i < face.len() - 2 {
|
||||
indices.push(indices_counter);
|
||||
indices.push(indices_counter + i as u32 + 1);
|
||||
@@ -403,6 +457,84 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// println!("indices counter: {}", indices_counter);
|
||||
// println!("indices: {:?}", indices);
|
||||
|
||||
for i in 0..face.len() - 2 {
|
||||
// let vert1 = &vertices[indices[indices_counter as usize] as usize];
|
||||
// let vert2 = &vertices[indices[indices_counter as usize + 1 + i] as usize];
|
||||
// let vert3 = &vertices[indices[indices_counter as usize + 2 + i] as usize];
|
||||
// let edge1 = vert2.position - vert1.position;
|
||||
// let edge2 = vert3.position - vert1.position;
|
||||
// let delta_uv1 = vert2.tex_coords - vert1.tex_coords;
|
||||
// let delta_uv2 = vert3.tex_coords - vert1.tex_coords;
|
||||
|
||||
// let f = 1.0 / (delta_uv1.x * delta_uv2.y - delta_uv2.x * delta_uv1.y);
|
||||
|
||||
// let tangent = glm::vec3(
|
||||
// f * (delta_uv2.y * edge1.x - delta_uv1.y * edge2.x),
|
||||
// f * (delta_uv2.y * edge1.y - delta_uv1.y * edge2.y),
|
||||
// f * (delta_uv2.y * edge1.z - delta_uv1.y * edge2.z),
|
||||
// );
|
||||
|
||||
// let bitangent = glm::vec3(
|
||||
// f * (-delta_uv2.x * edge1.x + delta_uv1.x * edge2.x),
|
||||
// f * (-delta_uv2.x * edge1.y + delta_uv1.x * edge2.y),
|
||||
// f * (-delta_uv2.x * edge1.z + delta_uv1.x * edge2.z),
|
||||
// );
|
||||
|
||||
// vertices[indices[indices_counter as usize] as usize].tangent = vertices[indices[indices_counter as usize] as usize].tangent + tangent;
|
||||
// vertices[indices[indices_counter as usize + 1 + i] as usize].tangent = vertices[indices[indices_counter as usize + 1 + i] as usize].tangent + tangent;
|
||||
// vertices[indices[indices_counter as usize + 2 + i] as usize].tangent = vertices[indices[indices_counter as usize + 2 + i] as usize].tangent + tangent;
|
||||
|
||||
// vertices[indices[indices_counter as usize] as usize].bitangent = bitangent;
|
||||
// vertices[indices[indices_counter as usize + 1 + i] as usize].bitangent = bitangent;
|
||||
// vertices[indices[indices_counter as usize + 2 + i] as usize].bitangent = bitangent;
|
||||
|
||||
// println!("tangent: {:?}", tangent);
|
||||
// println!("bitangent: {:?}", bitangent);
|
||||
|
||||
let index1 = indices_counter as usize;
|
||||
let index2 = indices_counter as usize + i + 1;
|
||||
let index3 = indices_counter as usize + i + 2;
|
||||
|
||||
let vert1 = &vertices[index1];
|
||||
let vert2 = &vertices[index2];
|
||||
let vert3 = &vertices[index3];
|
||||
|
||||
// println!("vert1: {:?}", vert1);
|
||||
// println!("vert2: {:?}", vert2);
|
||||
// println!("vert3: {:?}", vert3);
|
||||
|
||||
let edge1 = vert2.position - vert1.position;
|
||||
let edge2 = vert3.position - vert1.position;
|
||||
let delta_uv1 = vert2.tex_coords - vert1.tex_coords;
|
||||
let delta_uv2 = vert3.tex_coords - vert1.tex_coords;
|
||||
|
||||
let f = 1.0 / (delta_uv1.x * delta_uv2.y - delta_uv2.x * delta_uv1.y);
|
||||
|
||||
let temp_tangent = glm::vec3(
|
||||
f * (delta_uv2.y * edge1.x - delta_uv1.y * edge2.x),
|
||||
f * (delta_uv2.y * edge1.y - delta_uv1.y * edge2.y),
|
||||
f * (delta_uv2.y * edge1.z - delta_uv1.y * edge2.z),
|
||||
);
|
||||
|
||||
let tangent = glm::normalize(temp_tangent - vert1.normal * glm::dot(vert1.normal, temp_tangent));
|
||||
let bitangent = glm::cross(vert1.normal, tangent);
|
||||
|
||||
vertices[index1].tangent = vertices[index1].tangent + tangent;
|
||||
vertices[index2].tangent = vertices[index2].tangent + tangent;
|
||||
vertices[index3].tangent = vertices[index3].tangent + tangent;
|
||||
|
||||
vertices[index1].bitangent = vertices[index1].bitangent + bitangent;
|
||||
vertices[index2].bitangent = vertices[index2].bitangent + bitangent;
|
||||
vertices[index3].bitangent = vertices[index3].bitangent + bitangent;
|
||||
|
||||
// println!("tangent: {:?}", tangent);
|
||||
// println!("bitangent: {:?}", bitangent);
|
||||
}
|
||||
|
||||
indices_counter += face.len() as u32;
|
||||
}
|
||||
Some(ObjToken::MaterialLib) => {
|
||||
@@ -457,7 +589,7 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
}
|
||||
}
|
||||
let elapsed = now.elapsed();
|
||||
trace!("Loaded in {}ms", elapsed.as_millis());
|
||||
info!("Loaded in {}ms", elapsed.as_millis());
|
||||
|
||||
let mesh_name = {
|
||||
if current_mesh_name.is_empty() && !object_name.is_empty() {
|
||||
@@ -469,6 +601,40 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
}
|
||||
};
|
||||
|
||||
// for i in (0..indices.len()).step_by(3) {
|
||||
// let index1 = indices[i] as usize;
|
||||
// let index2 = indices[i + 1] as usize;
|
||||
// let index3 = indices[i + 2] as usize;
|
||||
|
||||
// let vert1 = &vertices[index1];
|
||||
// let vert2 = &vertices[index2];
|
||||
// let vert3 = &vertices[index3];
|
||||
|
||||
// let edge1 = vert2.position - vert1.position;
|
||||
// let edge2 = vert3.position - vert1.position;
|
||||
// let delta_uv1 = vert2.tex_coords - vert1.tex_coords;
|
||||
// let delta_uv2 = vert3.tex_coords - vert1.tex_coords;
|
||||
|
||||
// let f = 1.0 / (delta_uv1.x * delta_uv2.y - delta_uv2.x * delta_uv1.y);
|
||||
|
||||
// let temp_tangent = glm::vec3(
|
||||
// f * (delta_uv2.y * edge1.x - delta_uv1.y * edge2.x),
|
||||
// f * (delta_uv2.y * edge1.y - delta_uv1.y * edge2.y),
|
||||
// f * (delta_uv2.y * edge1.z - delta_uv1.y * edge2.z),
|
||||
// );
|
||||
|
||||
// let tangent = glm::normalize(temp_tangent - vert1.normal * glm::dot(vert1.normal, temp_tangent));
|
||||
// let bitangent = glm::cross(vert1.normal, tangent);
|
||||
|
||||
// vertices[index1].tangent = vertices[index1].tangent + tangent;
|
||||
// vertices[index2].tangent = vertices[index2].tangent + tangent;
|
||||
// vertices[index3].tangent = vertices[index3].tangent + tangent;
|
||||
|
||||
// vertices[index1].bitangent = vertices[index1].bitangent + bitangent;
|
||||
// vertices[index2].bitangent = vertices[index2].bitangent + bitangent;
|
||||
// vertices[index3].bitangent = vertices[index3].bitangent + bitangent;
|
||||
// }
|
||||
|
||||
meshes.push(ObjMesh{
|
||||
name: mesh_name,
|
||||
vertices: vertices.clone(),
|
||||
|
||||
@@ -85,6 +85,8 @@ fn parse_ascii_stl(file: std::fs::File) -> Result<Object, Box<dyn std::error::Er
|
||||
position: glm::vec3(vert.x, vert.y, vert.z),
|
||||
normal: glm::vec3(triangle.normal.x, triangle.normal.y, triangle.normal.z),
|
||||
tex_coords,
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
});
|
||||
|
||||
min_aabb = glm::min(min_aabb, vert);
|
||||
@@ -183,6 +185,8 @@ fn parse_binary_stl(mut file: std::fs::File) -> Result<Object, Box<dyn std::erro
|
||||
position: glm::vec3(vert.x, vert.y, vert.z),
|
||||
normal: glm::vec3(triangle.normal.x, triangle.normal.y, triangle.normal.z),
|
||||
tex_coords,
|
||||
tangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
bitangent: glm::vec3(0.0, 0.0, 0.0),
|
||||
});
|
||||
|
||||
min_aabb = glm::min(min_aabb, vert);
|
||||
|
||||
+2
-2
@@ -147,7 +147,7 @@ fn main() -> anyhow::Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
mesh_shader.set_3fv("dirLight.direction", glm::vec3(-0.2, -1.0, -0.3));
|
||||
mesh_shader.set_3fv("dirLight.ambient", glm::vec3(0.1, 0.1, 0.1));
|
||||
mesh_shader.set_3fv("dirLight.diffuse", glm::vec3(1.0, 1.0, 1.0));
|
||||
mesh_shader.set_3fv("dirLight.diffuse", glm::vec3(0.5, 0.5, 0.5));
|
||||
mesh_shader.set_3fv("dirLight.specular", glm::vec3(1.0, 1.0, 1.0));
|
||||
|
||||
let scene_fb = create_scene_framebuffer();
|
||||
@@ -264,7 +264,7 @@ fn main() -> anyhow::Result<(), Box<dyn std::error::Error>> {
|
||||
} else {
|
||||
gl::PolygonMode(gl::FRONT_AND_BACK, gl::FILL);
|
||||
}
|
||||
if Some(obj.id) == state.active_model {obj.draw(&mesh_shader, state.draw_aabb, state.show_textures);}
|
||||
if Some(obj.id) == state.active_model {obj.draw(&mesh_shader, state.draw_aabb, state.show_textures, state.show_normal, state.show_emission);}
|
||||
}
|
||||
gl::PolygonMode(gl::FRONT_AND_BACK, gl::FILL);
|
||||
|
||||
|
||||
+31
-10
@@ -1,5 +1,4 @@
|
||||
use glad_gl::gl;
|
||||
use log::warn;
|
||||
|
||||
use crate::{shader::Shader, utils, importer::{Material, TextureType}};
|
||||
|
||||
@@ -75,6 +74,14 @@ impl Mesh {
|
||||
gl::EnableVertexAttribArray(2);
|
||||
gl::VertexAttribPointer(2, 2, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, (6 * std::mem::size_of::<f32>()) as *const std::ffi::c_void);
|
||||
|
||||
// vertex tangent
|
||||
gl::EnableVertexAttribArray(3);
|
||||
gl::VertexAttribPointer(3, 3, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, (8 * std::mem::size_of::<f32>()) as *const std::ffi::c_void);
|
||||
|
||||
// vertex bitangent
|
||||
gl::EnableVertexAttribArray(4);
|
||||
gl::VertexAttribPointer(4, 3, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, (11 * std::mem::size_of::<f32>()) as *const std::ffi::c_void);
|
||||
|
||||
gl::BindVertexArray(0);
|
||||
}
|
||||
|
||||
@@ -93,7 +100,7 @@ impl Mesh {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&self, shader: &Shader, scale: f32, pivot: glm::Vec3, show_textures: bool) {
|
||||
pub fn draw(&self, shader: &Shader, scale: f32, pivot: glm::Vec3, show_textures: bool, use_normal: bool, use_emissive: bool) {
|
||||
shader.use_shader();
|
||||
|
||||
let model_mat = glm::ext::scale(&utils::mat_ident(), glm::vec3(scale, scale, scale));
|
||||
@@ -135,11 +142,13 @@ 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("hasNormalTexture", false);
|
||||
shader.set_bool("hasEmissionTexture", false);
|
||||
for i in 0..self.material.textures.len() {
|
||||
unsafe {
|
||||
gl::ActiveTexture(gl::TEXTURE0 + i as u32);
|
||||
match tex.typ {
|
||||
gl::BindTexture(gl::TEXTURE_2D, self.material.textures[i].id);
|
||||
match self.material.textures[i].typ {
|
||||
TextureType::Ambient => {
|
||||
shader.set_int("material.texture_ambient", i as i32);
|
||||
},
|
||||
@@ -150,13 +159,20 @@ impl Mesh {
|
||||
shader.set_int("material.texture_specular", i as i32);
|
||||
},
|
||||
TextureType::Emissive => {
|
||||
shader.set_int("material.texture_emission", i as i32);
|
||||
if use_emissive {
|
||||
shader.set_bool("hasEmissionTexture", true);
|
||||
}
|
||||
shader.set_int("material.texture_emission", i as i32);
|
||||
},
|
||||
_ => {},
|
||||
TextureType::Bump => {
|
||||
if use_normal {
|
||||
shader.set_bool("hasNormalTexture", true);
|
||||
}
|
||||
shader.set_int("material.texture_normal", i as i32);
|
||||
},
|
||||
_ => { continue; },
|
||||
}
|
||||
|
||||
gl::BindTexture(gl::TEXTURE_2D, tex.id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -185,12 +201,13 @@ impl Mesh {
|
||||
|
||||
impl Drop for Mesh {
|
||||
fn drop(&mut self) {
|
||||
// TODO: should we impl a Drop on material to delete the textures from gpu??
|
||||
unsafe {
|
||||
gl::ActiveTexture(gl::TEXTURE0);
|
||||
gl::BindVertexArray(0);
|
||||
gl::DeleteBuffers(1, &self.vbo);
|
||||
gl::DeleteBuffers(1, &self.ebo);
|
||||
gl::DeleteVertexArrays(1, &self.vao);
|
||||
gl::DeleteTextures(self.material.textures.len() as i32, self.material.textures.iter().map(|t| t.id).collect::<Vec<u32>>().as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,14 +218,18 @@ pub struct Vertex {
|
||||
pub position: glm::Vec3,
|
||||
pub normal: glm::Vec3,
|
||||
pub tex_coords: glm::Vec2,
|
||||
pub tangent: glm::Vec3,
|
||||
pub bitangent: glm::Vec3,
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
pub fn new(position: glm::Vec3, normal: glm::Vec3, tex_coords: glm::Vec2) -> Self {
|
||||
pub fn new(position: glm::Vec3, normal: glm::Vec3, tex_coords: glm::Vec2, tangent: glm::Vec3, bitangent: glm::Vec3) -> Self {
|
||||
Vertex {
|
||||
position,
|
||||
normal,
|
||||
tex_coords
|
||||
tex_coords,
|
||||
tangent,
|
||||
bitangent,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ impl Model {
|
||||
return model;
|
||||
}
|
||||
|
||||
pub fn draw(&self, shader: &Shader, draw_aabb: bool, show_textures: bool) {
|
||||
pub fn draw(&self, shader: &Shader, draw_aabb: bool, show_textures: bool, use_normal: bool, use_emissive: bool) {
|
||||
let center_x = ((self.aabb.max.x / 2.0) + (self.aabb.min.x / 2.0)) * self.scaling_factor;
|
||||
let center_y = ((self.aabb.max.y / 2.0) + (self.aabb.min.y / 2.0)) * self.scaling_factor;
|
||||
let center_z = ((self.aabb.max.z / 2.0) + (self.aabb.min.z / 2.0)) * self.scaling_factor;
|
||||
@@ -53,7 +53,7 @@ impl Model {
|
||||
|
||||
|
||||
for mesh in &self.meshes {
|
||||
mesh.draw(shader, self.scaling_factor, pivot, show_textures);
|
||||
mesh.draw(shader, self.scaling_factor, pivot, show_textures, use_normal, use_emissive);
|
||||
}
|
||||
|
||||
if draw_aabb {
|
||||
|
||||
+10
-2
@@ -31,7 +31,9 @@ pub struct State {
|
||||
pub logger: logger::WritableLog,
|
||||
pub settings: Settings,
|
||||
pub fps: f32,
|
||||
pub show_textures: bool
|
||||
pub show_textures: bool,
|
||||
pub show_normal: bool,
|
||||
pub show_emission: bool,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
@@ -56,7 +58,9 @@ impl Default for State {
|
||||
logger: logger::WritableLog::default(),
|
||||
settings: Settings::default(),
|
||||
fps: 0.0,
|
||||
show_textures: true
|
||||
show_textures: true,
|
||||
show_normal: true,
|
||||
show_emission: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -491,6 +495,10 @@ fn draw_viewport(ui: &imgui::Ui, state: &mut State, texture: u32) {
|
||||
ui.same_line();
|
||||
ui.checkbox("Show Textures", &mut state.show_textures);
|
||||
ui.same_line();
|
||||
ui.checkbox("Use Normal", &mut state.show_normal);
|
||||
ui.same_line();
|
||||
ui.checkbox("Use Emissive", &mut state.show_emission);
|
||||
ui.same_line();
|
||||
ui.set_next_item_width(150.0);
|
||||
imgui::Drag::new("Camera Speed")
|
||||
.range(1.0, 10000.0)
|
||||
|
||||
Reference in New Issue
Block a user