Added support for Kd
This commit is contained in:
parent
f6dd2a34ad
commit
a487822790
|
@ -1,6 +1,7 @@
|
||||||
#version 140
|
#version 140
|
||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
uniform vec3 diffuse;
|
||||||
|
|
||||||
in vec3 v_normal;
|
in vec3 v_normal;
|
||||||
in vec2 v_tex_coords;
|
in vec2 v_tex_coords;
|
||||||
|
@ -18,7 +19,7 @@ void main() {
|
||||||
|
|
||||||
vec4 factor = vec4(ambientLight + lambertComponent, 1.0);
|
vec4 factor = vec4(ambientLight + lambertComponent, 1.0);
|
||||||
|
|
||||||
color = factor * texture(tex, v_tex_coords);
|
color = factor * vec4(diffuse, 1.0) * texture(tex, v_tex_coords);
|
||||||
|
|
||||||
if (color.a < 0.05) {
|
if (color.a < 0.05) {
|
||||||
discard;
|
discard;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! This module contains everything related to materials.
|
//! This module contains everything related to materials.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use math::vector::Vector3;
|
||||||
|
|
||||||
/// A 3D material.
|
/// A 3D material.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -9,6 +10,9 @@ pub struct Material {
|
||||||
/// The name of the material.
|
/// The name of the material.
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
|
/// The diffuse color of the material.
|
||||||
|
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>,
|
||||||
|
|
||||||
|
@ -24,6 +28,7 @@ impl Material {
|
||||||
pub fn new(name: &str) -> Material {
|
pub fn new(name: &str) -> Material {
|
||||||
Material {
|
Material {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
|
diffuse: Vector3::new(1.0, 1.0, 1.0),
|
||||||
textures: HashMap::new(),
|
textures: HashMap::new(),
|
||||||
unknown_instructions: vec![],
|
unknown_instructions: vec![],
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub enum Element {
|
||||||
Texture(String, String),
|
Texture(String, String),
|
||||||
|
|
||||||
/// Change the main color of the current material.
|
/// Change the main color of the current material.
|
||||||
Color(Vector3<f64>),
|
Diffuse(Vector3<f32>),
|
||||||
|
|
||||||
/// An unknown material instruction that will be copied into the mtl file.
|
/// An unknown material instruction that will be copied into the mtl file.
|
||||||
UnknownMaterialInstruction(String),
|
UnknownMaterialInstruction(String),
|
||||||
|
@ -102,11 +102,10 @@ pub enum ParserError {
|
||||||
/// String is the name of the material that is already defined.
|
/// String is the name of the material that is already defined.
|
||||||
MaterialAlreadyExists(String, usize, String),
|
MaterialAlreadyExists(String, usize, String),
|
||||||
|
|
||||||
/// Texture arrived before creating a material.
|
/// Some material information arrived before creating a material.
|
||||||
///
|
///
|
||||||
/// usize is the line.
|
/// usize is the line.
|
||||||
/// String is the path to the texture.
|
NoMaterialExist(String, usize),
|
||||||
NoMaterialExist(String, usize, String),
|
|
||||||
|
|
||||||
/// Something weird happened
|
/// Something weird happened
|
||||||
OtherError(String),
|
OtherError(String),
|
||||||
|
@ -174,8 +173,8 @@ impl fmt::Display for ParserError {
|
||||||
write!(f, "Index out of bound in {}:{}:\n\tsize is {} but got {}", p, l, i, s),
|
write!(f, "Index out of bound in {}:{}:\n\tsize is {} but got {}", p, l, i, s),
|
||||||
ParserError::MaterialAlreadyExists(ref p, l, ref n) =>
|
ParserError::MaterialAlreadyExists(ref p, l, ref n) =>
|
||||||
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, ref n) =>
|
ParserError::NoMaterialExist(ref p, l) =>
|
||||||
write!(f, "Missing material in {}:{}\n\tNo material were defined, can't set {} as textuure", p, l, n),
|
write!(f, "Missing material in {}:{}\n\tNo material were defined, can't set attribute", p, l),
|
||||||
ParserError::OtherError(ref p) =>
|
ParserError::OtherError(ref p) =>
|
||||||
write!(f, "Something weird happened in {}...", p),
|
write!(f, "Something weird happened in {}...", p),
|
||||||
}
|
}
|
||||||
|
@ -268,7 +267,7 @@ impl<LP: LineParser> Parser for LP {
|
||||||
|
|
||||||
Element::Texture(texture_name, texture_path) => {
|
Element::Texture(texture_name, texture_path) => {
|
||||||
if current_material_name.is_none() {
|
if current_material_name.is_none() {
|
||||||
return Err(ParserError::NoMaterialExist(path.to_owned(), num, texture_path));
|
return Err(ParserError::NoMaterialExist(path.to_owned(), num));
|
||||||
}
|
}
|
||||||
|
|
||||||
let material_name = current_material_name.as_ref().unwrap().clone();
|
let material_name = current_material_name.as_ref().unwrap().clone();
|
||||||
|
@ -276,18 +275,16 @@ impl<LP: LineParser> Parser for LP {
|
||||||
let current_material = model.materials.get_mut(&material_name);
|
let current_material = model.materials.get_mut(&material_name);
|
||||||
|
|
||||||
if current_material.is_none() {
|
if current_material.is_none() {
|
||||||
return Err(ParserError::NoMaterialExist(path.to_owned(), num, texture_path))
|
return Err(ParserError::NoMaterialExist(path.to_owned(), num))
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
},
|
},
|
||||||
|
|
||||||
Element::Color(_) => (),
|
Element::Diffuse(v) => {
|
||||||
|
|
||||||
Element::UnknownMaterialInstruction(s) => {
|
|
||||||
if current_material_name.is_none() {
|
if current_material_name.is_none() {
|
||||||
return Err(ParserError::NoMaterialExist(path.to_owned(), num, s));
|
return Err(ParserError::NoMaterialExist(path.to_owned(), num));
|
||||||
}
|
}
|
||||||
|
|
||||||
let material_name = current_material_name.as_ref().unwrap().clone();
|
let material_name = current_material_name.as_ref().unwrap().clone();
|
||||||
|
@ -295,7 +292,25 @@ impl<LP: LineParser> Parser for LP {
|
||||||
let current_material = model.materials.get_mut(&material_name);
|
let current_material = model.materials.get_mut(&material_name);
|
||||||
|
|
||||||
if current_material.is_none() {
|
if current_material.is_none() {
|
||||||
return Err(ParserError::NoMaterialExist(path.to_owned(), num, s))
|
return Err(ParserError::NoMaterialExist(path.to_owned(), num));
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_material = current_material.unwrap();
|
||||||
|
|
||||||
|
current_material.diffuse = v;
|
||||||
|
},
|
||||||
|
|
||||||
|
Element::UnknownMaterialInstruction(s) => {
|
||||||
|
if current_material_name.is_none() {
|
||||||
|
return Err(ParserError::NoMaterialExist(path.to_owned(), num));
|
||||||
|
}
|
||||||
|
|
||||||
|
let material_name = current_material_name.as_ref().unwrap().clone();
|
||||||
|
|
||||||
|
let current_material = model.materials.get_mut(&material_name);
|
||||||
|
|
||||||
|
if current_material.is_none() {
|
||||||
|
return Err(ParserError::NoMaterialExist(path.to_owned(), num))
|
||||||
}
|
}
|
||||||
|
|
||||||
current_material.unwrap().add_unknown_instruction(s);
|
current_material.unwrap().add_unknown_instruction(s);
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use parser::{Element, ParserError, LineParser};
|
use parser::{Element, ParserError, LineParser};
|
||||||
|
use parser::obj::parse_values;
|
||||||
|
|
||||||
|
use math::vector::Vector3;
|
||||||
|
|
||||||
/// Wavefront material file format parser.
|
/// Wavefront material file format parser.
|
||||||
pub struct MtlParser {
|
pub struct MtlParser {
|
||||||
|
@ -21,7 +24,7 @@ impl MtlParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LineParser for MtlParser {
|
impl LineParser for MtlParser {
|
||||||
fn parse_line(&mut self, _line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
fn parse_line(&mut self, line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
||||||
|
|
||||||
let mut root = PathBuf::from(path);
|
let mut root = PathBuf::from(path);
|
||||||
root.pop();
|
root.pop();
|
||||||
|
@ -40,6 +43,15 @@ impl LineParser for MtlParser {
|
||||||
// Starts a new material
|
// Starts a new material
|
||||||
"newmtl" => Ok(Element::NewMaterial(split.nth(0).unwrap().to_owned())),
|
"newmtl" => Ok(Element::NewMaterial(split.nth(0).unwrap().to_owned())),
|
||||||
|
|
||||||
|
"Kd" => {
|
||||||
|
let values = parse_values(line_number, line, path, 3)?;
|
||||||
|
Ok(Element::Diffuse(Vector3::new(
|
||||||
|
values[0] as f32,
|
||||||
|
values[1] as f32,
|
||||||
|
values[2] as f32,
|
||||||
|
)))
|
||||||
|
},
|
||||||
|
|
||||||
map if map.starts_with("map_") => {
|
map if map.starts_with("map_") => {
|
||||||
|
|
||||||
let mut full_path = root.clone();
|
let mut full_path = root.clone();
|
||||||
|
|
|
@ -4,6 +4,31 @@ use parser::{Element, ParserError, LineParser};
|
||||||
use math::vector::{Vector2, Vector3};
|
use math::vector::{Vector2, Vector3};
|
||||||
use model::face::{FaceVertex, Face};
|
use model::face::{FaceVertex, Face};
|
||||||
|
|
||||||
|
/// Parses a certain number of value in a line, and returns a Vec containing the values.
|
||||||
|
///
|
||||||
|
/// Will return an error if the number of values expected is incorrect.
|
||||||
|
pub fn parse_values(line_number: usize, line: &str, path: &str, number_of_values: usize) -> Result<Vec<f64>, ParserError> {
|
||||||
|
|
||||||
|
let mut split = line.split_whitespace();
|
||||||
|
split.next();
|
||||||
|
|
||||||
|
let mut ret = vec![];
|
||||||
|
|
||||||
|
for elt in split {
|
||||||
|
if let Ok(value) = elt.parse::<f64>() {
|
||||||
|
ret.push(value);
|
||||||
|
} else {
|
||||||
|
return Err(ParserError::ParseNumberError(path.to_owned(), line_number, elt.to_owned()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ret.len() == number_of_values {
|
||||||
|
Ok(ret)
|
||||||
|
} else {
|
||||||
|
Err(ParserError::IncorrectNumberOfParameters(path.to_owned(), line_number, number_of_values, ret.len()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// The wavefront OBJ format parser.
|
/// The wavefront OBJ format parser.
|
||||||
pub struct ObjParser {
|
pub struct ObjParser {
|
||||||
|
|
||||||
|
@ -18,30 +43,6 @@ impl ObjParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a certain number of value in a line, and returns a Vec containing the values.
|
|
||||||
///
|
|
||||||
/// Will return an error if the number of values expected is incorrect.
|
|
||||||
fn parse_values(&self, line_number: usize, line: &str, path: &str, number_of_values: usize) -> Result<Vec<f64>, ParserError> {
|
|
||||||
|
|
||||||
let mut split = line.split_whitespace();
|
|
||||||
split.next();
|
|
||||||
|
|
||||||
let mut ret = vec![];
|
|
||||||
|
|
||||||
for elt in split {
|
|
||||||
if let Ok(value) = elt.parse::<f64>() {
|
|
||||||
ret.push(value);
|
|
||||||
} else {
|
|
||||||
return Err(ParserError::ParseNumberError(path.to_owned(), line_number, elt.to_owned()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ret.len() == number_of_values {
|
|
||||||
Ok(ret)
|
|
||||||
} else {
|
|
||||||
Err(ParserError::IncorrectNumberOfParameters(path.to_owned(), line_number, number_of_values, ret.len()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parses an obj vertex line.
|
/// Parses an obj vertex line.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -54,7 +55,7 @@ impl ObjParser {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn parse_vertex(&self, line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
pub fn parse_vertex(&self, line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
||||||
|
|
||||||
let values = self.parse_values(line_number, line, path, 3)?;
|
let values = parse_values(line_number, line, path, 3)?;
|
||||||
Ok(Element::Vertex(Vector3::<f64>::new(
|
Ok(Element::Vertex(Vector3::<f64>::new(
|
||||||
values[0],
|
values[0],
|
||||||
values[1],
|
values[1],
|
||||||
|
@ -74,7 +75,7 @@ impl ObjParser {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn parse_texture_coordinate(&self, line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
pub fn parse_texture_coordinate(&self, line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
||||||
|
|
||||||
let values = self.parse_values(line_number, line, path, 2)?;
|
let values = parse_values(line_number, line, path, 2)?;
|
||||||
Ok(Element::TextureCoordinate(Vector2::<f64>::new(
|
Ok(Element::TextureCoordinate(Vector2::<f64>::new(
|
||||||
values[0],
|
values[0],
|
||||||
values[1],
|
values[1],
|
||||||
|
@ -93,7 +94,7 @@ impl ObjParser {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn parse_normal(&self, line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
pub fn parse_normal(&self, line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
||||||
|
|
||||||
let values = self.parse_values(line_number, line, path, 3)?;
|
let values = parse_values(line_number, line, path, 3)?;
|
||||||
Ok(Element::Normal(Vector3::<f64>::new(
|
Ok(Element::Normal(Vector3::<f64>::new(
|
||||||
values[0],
|
values[0],
|
||||||
values[1],
|
values[1],
|
||||||
|
|
|
@ -19,6 +19,7 @@ use scene::Scene;
|
||||||
use camera::RenderCamera;
|
use camera::RenderCamera;
|
||||||
|
|
||||||
use model::{Vertex, Part, Model};
|
use model::{Vertex, Part, Model};
|
||||||
|
use math::vector::Vector3;
|
||||||
|
|
||||||
/// Image data stored as RGBA.
|
/// Image data stored as RGBA.
|
||||||
pub struct RgbaImageData {
|
pub struct RgbaImageData {
|
||||||
|
@ -142,6 +143,12 @@ impl Renderer {
|
||||||
|
|
||||||
if let &Some(ref buffer) = part.vertex_buffer() {
|
if let &Some(ref buffer) = part.vertex_buffer() {
|
||||||
|
|
||||||
|
let diffuse = if let Some(ref name) = part.material_name {
|
||||||
|
model.materials.get(name).unwrap().diffuse
|
||||||
|
} else {
|
||||||
|
Vector3::new(1.0, 1.0, 1.0)
|
||||||
|
};
|
||||||
|
|
||||||
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 = if let Some(texture) = texture {
|
||||||
|
@ -155,6 +162,7 @@ impl Renderer {
|
||||||
NoIndices(PrimitiveType::TrianglesList),
|
NoIndices(PrimitiveType::TrianglesList),
|
||||||
&self.program,
|
&self.program,
|
||||||
&uniform!(
|
&uniform!(
|
||||||
|
diffuse: Into::<[f32; 3]>::into(diffuse),
|
||||||
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),
|
||||||
|
|
Loading…
Reference in New Issue