Added -s mtl option
This commit is contained in:
parent
a487822790
commit
2b9a1064a7
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
uniform mat4 perspective;
|
uniform mat4 perspective;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
|
uniform vec3 texture_size;
|
||||||
|
|
||||||
in vec3 vertex;
|
in vec3 vertex;
|
||||||
in vec2 tex_coords;
|
in vec2 tex_coords;
|
||||||
|
@ -12,7 +13,7 @@ out vec3 v_normal;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
v_normal = normal;
|
v_normal = normal;
|
||||||
v_tex_coords = tex_coords;
|
v_tex_coords = vec2(tex_coords.x * texture_size.x, tex_coords.y * texture_size.y);
|
||||||
|
|
||||||
gl_Position = perspective * view * vec4(vertex, 1.0);
|
gl_Position = perspective * view * vec4(vertex, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub struct Material {
|
||||||
pub diffuse: Vector3<f32>,
|
pub diffuse: Vector3<f32>,
|
||||||
|
|
||||||
/// Map linking each texture map to its file path.
|
/// Map linking each texture map to its file path.
|
||||||
pub textures: HashMap<String, String>,
|
pub textures: HashMap<String, (String, Vector3<f32>)>,
|
||||||
|
|
||||||
/// Instructions that are unknown.
|
/// Instructions that are unknown.
|
||||||
///
|
///
|
||||||
|
|
|
@ -102,7 +102,7 @@ pub struct Model {
|
||||||
pub materials: HashMap<String, Material>,
|
pub materials: HashMap<String, Material>,
|
||||||
|
|
||||||
/// Map associating the name of a texture and the real texture.
|
/// Map associating the name of a texture and the real texture.
|
||||||
pub textures: HashMap<String, Rc<SrgbTexture2d>>,
|
pub textures: HashMap<String, (Rc<SrgbTexture2d>, Vector3<f32>)>,
|
||||||
|
|
||||||
/// The list of parts of the model.
|
/// The list of parts of the model.
|
||||||
pub parts: Vec<Part>,
|
pub parts: Vec<Part>,
|
||||||
|
@ -544,15 +544,15 @@ impl Model {
|
||||||
|
|
||||||
/// Builds the SrgbTextures for rendering.
|
/// Builds the SrgbTextures for rendering.
|
||||||
pub fn build_texture_for_material(&mut self, material: &Material, renderer: &Renderer) {
|
pub fn build_texture_for_material(&mut self, material: &Material, renderer: &Renderer) {
|
||||||
if let Some(path) = material.textures.get("map_Kd") {
|
if let Some((path, size)) = material.textures.get("map_Kd") {
|
||||||
let texture = renderer.make_texture(path);
|
let texture = renderer.make_texture(path);
|
||||||
// Don't need to insert multiple times the same texture
|
// Don't need to insert multiple times the same texture
|
||||||
self.textures.entry(path.to_owned()).or_insert(Rc::new(texture));
|
self.textures.entry(path.to_owned()).or_insert((Rc::new(texture), *size));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the rendering texture.
|
/// Returns the rendering texture.
|
||||||
pub fn get_texture_by_name(&self, name: &str) -> Option<&Rc<SrgbTexture2d>> {
|
pub fn get_texture_by_name(&self, name: &str) -> Option<&(Rc<SrgbTexture2d>, Vector3<f32>)> {
|
||||||
self.textures.get(name)
|
self.textures.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ impl Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a ref mut to the table of textures.
|
/// Returns a ref mut to the table of textures.
|
||||||
pub fn textures_mut(&mut self) -> &mut HashMap<String, Rc<SrgbTexture2d>> {
|
pub fn textures_mut(&mut self) -> &mut HashMap<String, (Rc<SrgbTexture2d>, Vector3<f32>)> {
|
||||||
&mut self.textures
|
&mut self.textures
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,8 @@ pub enum Element {
|
||||||
///
|
///
|
||||||
/// First string is the name of the map.
|
/// First string is the name of the map.
|
||||||
/// Second string is the path to the image file.
|
/// Second string is the path to the image file.
|
||||||
Texture(String, String),
|
/// Vector3 is the size of the texture.
|
||||||
|
Texture(String, String, Vector3<f32>),
|
||||||
|
|
||||||
/// Change the main color of the current material.
|
/// Change the main color of the current material.
|
||||||
Diffuse(Vector3<f32>),
|
Diffuse(Vector3<f32>),
|
||||||
|
@ -107,6 +108,12 @@ pub enum ParserError {
|
||||||
/// usize is the line.
|
/// usize is the line.
|
||||||
NoMaterialExist(String, usize),
|
NoMaterialExist(String, usize),
|
||||||
|
|
||||||
|
/// No path after a map
|
||||||
|
NoPathAfterMap(String, usize),
|
||||||
|
|
||||||
|
/// Unexpected token
|
||||||
|
UnexpectedToken(String, usize, String),
|
||||||
|
|
||||||
/// Something weird happened
|
/// Something weird happened
|
||||||
OtherError(String),
|
OtherError(String),
|
||||||
}
|
}
|
||||||
|
@ -175,6 +182,10 @@ impl fmt::Display for ParserError {
|
||||||
write!(f, "Redecralation of material in {}:{}:\n\t{} already exists", p, n, l),
|
write!(f, "Redecralation of material in {}:{}:\n\t{} already exists", p, n, l),
|
||||||
ParserError::NoMaterialExist(ref p, l) =>
|
ParserError::NoMaterialExist(ref p, l) =>
|
||||||
write!(f, "Missing material in {}:{}\n\tNo material were defined, can't set attribute", p, l),
|
write!(f, "Missing material in {}:{}\n\tNo material were defined, can't set attribute", p, l),
|
||||||
|
ParserError::NoPathAfterMap(ref p, l) =>
|
||||||
|
write!(f, "Missing path for map in {}:{}", p, l),
|
||||||
|
ParserError::UnexpectedToken(ref p, l, ref t) =>
|
||||||
|
write!(f, "Unexpected token {} in {}:{}", t, p, l),
|
||||||
ParserError::OtherError(ref p) =>
|
ParserError::OtherError(ref p) =>
|
||||||
write!(f, "Something weird happened in {}...", p),
|
write!(f, "Something weird happened in {}...", p),
|
||||||
}
|
}
|
||||||
|
@ -265,7 +276,7 @@ impl<LP: LineParser> Parser for LP {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Element::Texture(texture_name, texture_path) => {
|
Element::Texture(texture_name, texture_path, size) => {
|
||||||
if current_material_name.is_none() {
|
if current_material_name.is_none() {
|
||||||
return Err(ParserError::NoMaterialExist(path.to_owned(), num));
|
return Err(ParserError::NoMaterialExist(path.to_owned(), num));
|
||||||
}
|
}
|
||||||
|
@ -279,7 +290,7 @@ impl<LP: LineParser> Parser for LP {
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_material = current_material.unwrap();
|
let current_material = current_material.unwrap();
|
||||||
current_material.textures.insert(texture_name, texture_path);
|
current_material.textures.insert(texture_name, (texture_path, size));
|
||||||
},
|
},
|
||||||
|
|
||||||
Element::Diffuse(v) => {
|
Element::Diffuse(v) => {
|
||||||
|
|
|
@ -54,9 +54,25 @@ impl LineParser for MtlParser {
|
||||||
|
|
||||||
map if map.starts_with("map_") => {
|
map if map.starts_with("map_") => {
|
||||||
|
|
||||||
let mut full_path = root.clone();
|
let split = split.collect::<Vec<_>>();
|
||||||
full_path.push(split.nth(0).unwrap().to_owned());
|
if split.len() == 0 {
|
||||||
Ok(Element::Texture(first.to_owned(), full_path.to_str().unwrap().to_owned()))
|
Err(ParserError::NoPathAfterMap(path.to_owned(), line_number))
|
||||||
|
} else if split.len() == 1 {
|
||||||
|
let mut full_path = root.clone();
|
||||||
|
full_path.push(split[0].to_owned());
|
||||||
|
Ok(Element::Texture(first.to_owned(), full_path.to_str().unwrap().to_owned(), Vector3::new(1.0, 1.0, 1.0)))
|
||||||
|
} else if split[0] == "-s" {
|
||||||
|
let size = Vector3::new(
|
||||||
|
if let Ok(f) = split[1].parse::<f32>() { f } else { return Err(ParserError::ParseNumberError(path.to_owned(), line_number, split[1].to_owned())); },
|
||||||
|
if let Ok(f) = split[2].parse::<f32>() { f } else { return Err(ParserError::ParseNumberError(path.to_owned(), line_number, split[2].to_owned())); },
|
||||||
|
if let Ok(f) = split[3].parse::<f32>() { f } else { return Err(ParserError::ParseNumberError(path.to_owned(), line_number, split[3].to_owned())); },
|
||||||
|
);
|
||||||
|
let mut full_path = root.clone();
|
||||||
|
full_path.push(split[4].to_owned());
|
||||||
|
Ok(Element::Texture(first.to_owned(), full_path.to_str().unwrap().to_owned(), size))
|
||||||
|
} else {
|
||||||
|
Err(ParserError::UnexpectedKeyword(path.to_owned(), line_number, split[2].to_owned()))
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -151,10 +151,10 @@ impl Renderer {
|
||||||
|
|
||||||
let texture = self.get_texture_of_part(&model, part);
|
let texture = self.get_texture_of_part(&model, part);
|
||||||
|
|
||||||
let texture = if let Some(texture) = texture {
|
let (texture, size) = if let Some((texture, size)) = texture {
|
||||||
texture
|
(texture, size)
|
||||||
} else {
|
} else {
|
||||||
&self.default_texture
|
(&self.default_texture, Vector3::new(1.0, 1.0, 1.0))
|
||||||
};
|
};
|
||||||
|
|
||||||
target.draw(
|
target.draw(
|
||||||
|
@ -166,6 +166,7 @@ impl Renderer {
|
||||||
tex: texture,
|
tex: texture,
|
||||||
perspective: Into::<[[f32; 4]; 4]>::into(perspective),
|
perspective: Into::<[[f32; 4]; 4]>::into(perspective),
|
||||||
view: Into::<[[f32; 4]; 4]>::into(view),
|
view: Into::<[[f32; 4]; 4]>::into(view),
|
||||||
|
texture_size: Into::<[f32; 3]>::into(size),
|
||||||
),
|
),
|
||||||
¶ms,
|
¶ms,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
@ -177,12 +178,12 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders a part of a model.
|
/// Renders a part of a model.
|
||||||
fn get_texture_of_part<'a>(&self, model: &'a Model, part: &Part) -> Option<&'a SrgbTexture2d> {
|
fn get_texture_of_part<'a>(&self, model: &'a Model, part: &Part) -> Option<(&'a SrgbTexture2d, Vector3<f32>)> {
|
||||||
if let Some(ref material_name) = part.material_name {
|
if let Some(ref material_name) = part.material_name {
|
||||||
if let Some(ref material) = model.materials.get(material_name) {
|
if let Some(ref material) = model.materials.get(material_name) {
|
||||||
if let Some(texture) = material.textures.get("map_Kd") {
|
if let Some((texture, _)) = material.textures.get("map_Kd") {
|
||||||
if let Some(ref texture) = model.get_texture_by_name(&texture) {
|
if let Some((texture, size)) = model.get_texture_by_name(texture) {
|
||||||
Some(texture)
|
Some((texture, *size))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue