diff --git a/assets/shaders/color.frag b/assets/shaders/color.frag new file mode 100644 index 0000000..ad218bd --- /dev/null +++ b/assets/shaders/color.frag @@ -0,0 +1,15 @@ +#version 140 + +uniform sampler2D tex; +uniform vec3 diffuse; + +in vec3 v_color; + +out vec4 color; + +void main() { + + color = vec4(v_color, 1.0); + +} + diff --git a/assets/shaders/color.vert b/assets/shaders/color.vert new file mode 100644 index 0000000..e8ebcc2 --- /dev/null +++ b/assets/shaders/color.vert @@ -0,0 +1,17 @@ +#version 140 + +uniform mat4 perspective; +uniform mat4 view; +uniform vec3 texture_size; + +in vec3 vertex; +in vec2 tex_coords; +in vec3 normal; +in vec3 face_color; + +out vec3 v_color; + +void main() { + v_color = face_color; + gl_Position = perspective * view * vec4(vertex, 1.0); +} diff --git a/assets/shaders/shader.frag b/assets/shaders/default.frag similarity index 100% rename from assets/shaders/shader.frag rename to assets/shaders/default.frag diff --git a/assets/shaders/shader.vert b/assets/shaders/default.vert similarity index 100% rename from assets/shaders/shader.vert rename to assets/shaders/default.vert diff --git a/src/model/face_vertex.rs b/src/model/face_vertex.rs deleted file mode 100644 index ae2ec8a..0000000 --- a/src/model/face_vertex.rs +++ /dev/null @@ -1,49 +0,0 @@ -//! This module contains the FaceVertex struct. - -use std::fmt; - -#[derive(Copy, Clone, PartialEq)] -/// The indices needed for each vertex of a face. -pub struct FaceVertex { - - /// The index of the vertex. - pub vertex: usize, - - /// The index of the texture coordinate, None if there is no texture coordinate. - pub texture_coordinate: Option, - - /// The index of the normal, None if there is no normal. - pub normal: Option, -} - -impl FaceVertex { - - /// Creates a new face vertex from its attributes. - pub fn new(vertex: usize, texture_coordinate: Option, normal: Option) -> FaceVertex { - FaceVertex { - vertex: vertex, - texture_coordinate: texture_coordinate, - normal: normal, - } - } - -} - -impl fmt::Debug for FaceVertex { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - - let texture_coordinate = if let Some(tc) = self.texture_coordinate { - tc.to_string() - } else { - "".to_owned() - }; - - let normal = if let Some(n) = self.normal { - n.to_string() - } else { - "".to_owned() - }; - - write!(formatter, "{}/{}/{}", self.vertex, texture_coordinate, normal) - } -} diff --git a/src/model/mod.rs b/src/model/mod.rs index 93ee955..118c4d4 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -26,9 +26,10 @@ pub struct Vertex { vertex: [f64; 3], tex_coords: [f64; 2], normal: [f64; 3], + face_color: [f64; 3], } -implement_vertex!(Vertex, vertex, tex_coords, normal); +implement_vertex!(Vertex, vertex, tex_coords, normal, face_color); /// A part of a 3D model. /// @@ -523,10 +524,26 @@ impl Model { [0.0, 0.0, 0.0] }; + let [r, g, b] = if let Some(id) = face.id { + let b = (id % 256) as u8; + let g = ((id - b as usize) / 256 % 256) as u8; + let r = ((id - g as usize * 256 - b as usize) / (256 * 256)) as u8; + [r, g, b] + } else { + [255, 255, 255] + }; + + let [r, g, b] = [ + r as f64 / 255.0, + g as f64 / 255.0, + b as f64 / 255.0, + ]; + vertex_buffer.push(Vertex { vertex: vertex, tex_coords: tex_coord, normal: normal, + face_color: [r, g, b], }); } } @@ -567,4 +584,9 @@ impl Model { pub fn textures_mut(&mut self) -> &mut HashMap> { &mut self.textures } + + /// Clears the OpenGL textures. + pub fn clear_textures(&mut self) { + self.textures = HashMap::new(); + } } diff --git a/src/renderer.rs b/src/renderer.rs index 0c32171..de51b24 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -56,17 +56,52 @@ pub struct Renderer { } impl Renderer { + + /// Creates the program with the default shader. + pub fn default_shader(display: &Display) -> Program { + Program::from_source( + display, + include_str!("../assets/shaders/default.vert"), + include_str!("../assets/shaders/default.frag"), + None + ).unwrap() + } + + /// Creates the shader with one color per face. + pub fn color_shader(display: &Display) -> Program { + Program::from_source( + display, + include_str!("../assets/shaders/color.vert"), + include_str!("../assets/shaders/color.frag"), + None + ).unwrap() + } + /// Creates a new renderer from a display. /// /// Is uses the default shaders and creates an empty vec of models. pub fn new(display: Display) -> Renderer { - let program = Program::from_source( - &display, - include_str!("../assets/shaders/shader.vert"), - include_str!("../assets/shaders/shader.frag"), - None - ).unwrap(); + let program = Renderer::default_shader(&display); + Renderer::from_display_and_program(display, program) + + } + + /// Creates a new colored renderer from a display. + /// + /// Is uses the face colors shaders and creates an empty vec of models. + pub fn color(display: Display) -> Renderer { + + let program = Renderer::color_shader(&display); + Renderer::from_display_and_program(display, program) + + } + + + /// Creates a new renderer from a program. + /// + /// It allows you to use a custom shader. + pub fn from_display_and_program(display: Display, program: Program) -> Renderer { let image = RawImage2d::from_raw_rgba(vec![1.0, 1.0, 1.0, 1.0], (1, 1)); let texture = SrgbTexture2d::new(&display, image).ok().unwrap();