use crate::opengl::shader::{ Error as ShaderError, Kind as ShaderKind, Program as ShaderProgram, Shader, }; use crate::renderer::Renderable; use crate::vertex::Vertex; #[derive(Debug)] pub struct Object { id: Id, renderable: Renderable, } impl Object { /// Returns a new `Object`. /// /// # Errors /// Will return `Err` if shader creation fails or if shader program linking fails. pub fn new(id: Id, vertices: &[Vertex]) -> Result { let vertex_shader = Shader::new(ShaderKind::Vertex); vertex_shader .set_source(include_str!("../vertex.glsl")) .map_err(Error::CreateVertexShaderFailed)?; vertex_shader .compile() .map_err(Error::CreateVertexShaderFailed)?; let fragment_shader = Shader::new(ShaderKind::Fragment); fragment_shader .set_source(include_str!("../fragment.glsl")) .map_err(Error::CreateFragmentShaderFailed)?; fragment_shader .compile() .map_err(Error::CreateFragmentShaderFailed)?; let shader_program = ShaderProgram::new(); shader_program.attach(&vertex_shader); shader_program.attach(&fragment_shader); shader_program .link() .map_err(Error::LinkShaderProgramFailed)?; let renderable = Renderable::new(shader_program, vertices); Ok(Self { id, renderable }) } /// Returns the object ID. #[must_use] pub fn id(&self) -> Id { self.id } pub(crate) fn renderable(&self) -> &Renderable { &self.renderable } } /// Object error #[derive(Debug, thiserror::Error)] pub enum Error { #[error("Failed to create vertex shader")] CreateVertexShaderFailed(#[source] ShaderError), #[error("Failed to create fragment shader")] CreateFragmentShaderFailed(#[source] ShaderError), #[error("Failed to link shader program")] LinkShaderProgramFailed(#[source] ShaderError), } /// Object ID. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Id { id: u16, } impl Id { /// Returns a new object ID. #[must_use] pub fn new(id: u16) -> Self { Self { id } } }