diff --git a/src/gfx/lib.rs b/src/gfx/lib.rs index 83eff4fe102..170b0efc57e 100644 --- a/src/gfx/lib.rs +++ b/src/gfx/lib.rs @@ -74,8 +74,8 @@ impl Graphics { /// Create a new ref batch. pub fn make_batch(&mut self, program: &ProgramHandle, - mesh: &Mesh, - slice: Slice, + mesh: &Mesh, + slice: Slice, state: &DrawState) -> Result, batch::BatchError> { self.context.make_batch(program, mesh, slice, state) diff --git a/src/gfx_macros/vertex_format.rs b/src/gfx_macros/vertex_format.rs index 58d927fd956..e99a7901e7c 100644 --- a/src/gfx_macros/vertex_format.rs +++ b/src/gfx_macros/vertex_format.rs @@ -271,8 +271,13 @@ impl ItemDecorator for VertexFormat { path: vec!["Vec"], lifetime: None, params: vec![ - box generic::ty::Literal(generic::ty::Path::new( - vec![super::EXTERN_CRATE_HACK, "gfx", "Attribute"])), + box generic::ty::Literal(generic::ty::Path { + path: vec![super::EXTERN_CRATE_HACK, "gfx", "Attribute"], + lifetime: None, + params: vec![box generic::ty::Literal(generic::ty::Path::new( + vec![super::EXTERN_CRATE_HACK, "gfx", "GlResources"]))], + global: false, + }), ], global: false, }, @@ -283,7 +288,10 @@ impl ItemDecorator for VertexFormat { box |c, s, ss| method_body(c, s, ss, path_root)), }, ], - associated_types: Vec::new(), + associated_types: vec![ + (context.ident_of("Resources"), generic::ty::Literal(generic::ty::Path::new( + vec![super::EXTERN_CRATE_HACK, "gfx", "GlResources"]))), + ], }.expand(context, meta_item, item, fixup); } } diff --git a/src/render/batch.rs b/src/render/batch.rs index da439a87754..6f27a2833b0 100644 --- a/src/render/batch.rs +++ b/src/render/batch.rs @@ -52,7 +52,7 @@ pub enum BatchError { /// Match mesh attributes against shader inputs, produce a mesh link. /// Exposed to public to allow external `Batch` implementations to use it. -pub fn link_mesh(mesh: &mesh::Mesh, pinfo: &ProgramInfo) -> Result { +pub fn link_mesh(mesh: &mesh::Mesh, pinfo: &ProgramInfo) -> Result { let mut indices = Vec::new(); for sat in pinfo.attributes.iter() { match mesh.attributes.iter().enumerate() @@ -69,8 +69,8 @@ pub fn link_mesh(mesh: &mesh::Mesh, pinfo: &ProgramInfo) -> Result = (&'a mesh::Mesh, mesh::AttributeIter, &'a mesh::Slice, - &'a DrawState); +pub type BatchData<'a> = (&'a mesh::Mesh, mesh::AttributeIter, + &'a mesh::Slice, &'a DrawState); /// Abstract batch trait pub trait Batch { @@ -83,7 +83,7 @@ pub trait Batch { -> Result<&ProgramHandle, Self::Error>; } -impl<'a, T: ShaderParam> Batch for (&'a mesh::Mesh, mesh::Slice, +impl<'a, T: ShaderParam> Batch for (&'a mesh::Mesh, mesh::Slice, &'a ProgramHandle, &'a T, &'a DrawState) { type Error = BatchError; @@ -110,10 +110,10 @@ impl<'a, T: ShaderParam> Batch for (&'a mesh::Mesh, mesh::Slice, /// Owned batch - self-contained, but has heap-allocated data pub struct OwnedBatch { - mesh: mesh::Mesh, + mesh: mesh::Mesh, mesh_link: mesh::Link, /// Mesh slice - pub slice: mesh::Slice, + pub slice: mesh::Slice, /// Parameter data. pub param: T, program: ProgramHandle, @@ -124,7 +124,7 @@ pub struct OwnedBatch { impl OwnedBatch { /// Create a new owned batch - pub fn new(mesh: mesh::Mesh, program: ProgramHandle, param: T) + pub fn new(mesh: mesh::Mesh, program: ProgramHandle, param: T) -> Result, BatchError> { let slice = mesh.to_slice(PrimitiveType::TriangleList); let mesh_link = match link_mesh(&mesh, program.get_info()) { @@ -248,10 +248,10 @@ impl Array { /// It has references to the resources (mesh, program, state), that are held /// by the context that created the batch, so these have to be used together. pub struct RefBatch { - mesh_id: Id, + mesh_id: Id>, mesh_link: mesh::Link, /// Mesh slice - pub slice: mesh::Slice, + pub slice: mesh::Slice, program_id: Id>, param_link: T::Link, state_id: Id, @@ -306,7 +306,7 @@ impl RefBatch { /// Factory of ref batches, required to always be used with them. pub struct Context { - meshes: Array, + meshes: Array>, programs: Array>, states: Array, } @@ -326,8 +326,8 @@ impl Context { /// Produce a new ref batch pub fn make_batch(&mut self, program: &ProgramHandle, - mesh: &mesh::Mesh, - slice: mesh::Slice, + mesh: &mesh::Mesh, + slice: mesh::Slice, state: &DrawState) -> Result, BatchError> { let mesh_link = match link_mesh(mesh, program.get_info()) { diff --git a/src/render/device_ext.rs b/src/render/device_ext.rs index b530f9240ae..f18076cf36d 100644 --- a/src/render/device_ext.rs +++ b/src/render/device_ext.rs @@ -63,7 +63,8 @@ pub trait DeviceExt: device::Device { fn create_renderer(&mut self) -> ::Renderer; /// Create a new mesh from the given vertex data. /// Convenience function around `create_buffer` and `Mesh::from_format`. - fn create_mesh(&mut self, data: &[T]) -> Mesh; + fn create_mesh(&mut self, data: &[T]) -> Mesh where + T: VertexFormat + Copy; /// Create a simple program given a vertex shader with a fragment one. fn link_program(&mut self, vs_code: &[u8], fs_code: &[u8]) -> Result, ProgramError>; @@ -87,7 +88,9 @@ impl DeviceExt for D { } } - fn create_mesh(&mut self, data: &[T]) -> Mesh { + fn create_mesh(&mut self, data: &[T]) -> Mesh where + T: VertexFormat + Copy, + { let nv = data.len(); debug_assert!(nv < { use std::num::Int; diff --git a/src/render/lib.rs b/src/render/lib.rs index 8393fe1305a..0921694854a 100644 --- a/src/render/lib.rs +++ b/src/render/lib.rs @@ -423,7 +423,7 @@ impl Renderer { } fn bind_mesh>(&mut self, - mesh: &mesh::Mesh, attrib_iter: I, info: &ProgramInfo) { + mesh: &mesh::Mesh, attrib_iter: I, info: &ProgramInfo) { if !self.render_state.is_array_buffer_set { // It's Ok if the array buffer is not supported. We can just ignore it. self.common_array_buffer.map(|ab| @@ -456,7 +456,7 @@ impl Renderer { } } - fn draw_slice(&mut self, slice: &mesh::Slice, + fn draw_slice(&mut self, slice: &mesh::Slice, instances: Option<(device::InstanceCount, device::VertexCount)>) { let mesh::Slice { start, end, prim_type, kind } = slice.clone(); match kind { diff --git a/src/render/mesh.rs b/src/render/mesh.rs index 7c11500a57a..30b009e148e 100644 --- a/src/render/mesh.rs +++ b/src/render/mesh.rs @@ -21,16 +21,16 @@ //! `Buffer`, and then use `Mesh::from`. use device; -use device::{PrimitiveType, BufferHandle, VertexCount}; -use device::{attrib, back}; +use device::{PrimitiveType, BufferHandle, Resources, VertexCount}; +use device::attrib; /// Describes a single attribute of a vertex buffer, including its type, name, etc. #[derive(Clone, Debug, PartialEq)] -pub struct Attribute { +pub struct Attribute { /// A name to match the shader input pub name: String, /// Vertex buffer to contain the data - pub buffer: device::RawBufferHandle, + pub buffer: device::RawBufferHandle, /// Format of the attribute pub format: attrib::Format, } @@ -38,22 +38,23 @@ pub struct Attribute { /// A trait implemented automatically for user vertex structure by /// `#[vertex_format] attribute pub trait VertexFormat { + type Resources: Resources; /// Create the attributes for this type, using the given buffer. - fn generate(Option, buffer: device::RawBufferHandle) -> Vec; + fn generate(Option, buffer: device::RawBufferHandle) -> Vec>; } /// Describes geometry to render. #[derive(Clone, Debug, PartialEq)] -pub struct Mesh { +pub struct Mesh { /// Number of vertices in the mesh. pub num_vertices: device::VertexCount, /// Vertex attributes to use. - pub attributes: Vec, + pub attributes: Vec>, } -impl Mesh { +impl Mesh { /// Create a new mesh, which is a `TriangleList` with no attributes and `nv` vertices. - pub fn new(nv: device::VertexCount) -> Mesh { + pub fn new(nv: device::VertexCount) -> Mesh { Mesh { num_vertices: nv, attributes: Vec::new(), @@ -61,7 +62,9 @@ impl Mesh { } /// Create a new `Mesh` from a struct that implements `VertexFormat` and a buffer. - pub fn from_format(buf: device::BufferHandle, nv: device::VertexCount) -> Mesh { + pub fn from_format(buf: device::BufferHandle, nv: device::VertexCount) -> Mesh where + V: VertexFormat, + { Mesh { num_vertices: nv, attributes: VertexFormat::generate(None::, buf.raw()), @@ -69,9 +72,11 @@ impl Mesh { } /// Create a new intanced `Mesh` given a vertex buffer and an instance buffer. - pub fn from_format_instanced( - buf: device::BufferHandle, nv: device::VertexCount, - inst: device::BufferHandle) -> Mesh { + pub fn from_format_instanced(buf: device::BufferHandle, nv: device::VertexCount, + inst: device::BufferHandle) -> Mesh where + V: VertexFormat, + U: VertexFormat, + { let per_vertex = VertexFormat::generate(None::, buf.raw()); let per_instance = VertexFormat::generate(None::, inst.raw()); @@ -97,7 +102,7 @@ impl Mesh { /// For example, `Point` typed vertex slice can be used to do shape /// blending, while still rendereing it as an indexed `TriangleList`. #[derive(Clone, Copy, Debug, PartialEq)] -pub struct Slice { +pub struct Slice { /// Start index of vertices to draw. pub start: VertexCount, /// End index of vertices to draw. @@ -105,12 +110,12 @@ pub struct Slice { /// Primitive type to render collections of vertices as. pub prim_type: PrimitiveType, /// Source of the vertex ordering when drawing. - pub kind: SliceKind, + pub kind: SliceKind, } /// Source of vertex ordering for a slice #[derive(Clone, Copy, Debug, PartialEq)] -pub enum SliceKind { +pub enum SliceKind { /// Render vertex data directly from the `Mesh`'s buffer. Vertex, /// The `Index*` buffer contains a list of indices into the `Mesh` @@ -122,22 +127,22 @@ pub enum SliceKind { /// the vertices will be identical, wasting space for the duplicated /// attributes. Instead, the `Mesh` can store 4 vertices and an /// `Index8` can be used instead. - Index8(BufferHandle, VertexCount), + Index8(BufferHandle, VertexCount), /// As `Index8` but with `u16` indices - Index16(BufferHandle, VertexCount), + Index16(BufferHandle, VertexCount), /// As `Index8` but with `u32` indices - Index32(BufferHandle, VertexCount), + Index32(BufferHandle, VertexCount), } /// Helper methods for cleanly getting the slice of a type. -pub trait ToSlice { +pub trait ToSlice { /// Get the slice of a type. - fn to_slice(&self, pt: PrimitiveType) -> Slice; + fn to_slice(&self, pt: PrimitiveType) -> Slice; } -impl ToSlice for Mesh { +impl ToSlice for Mesh { /// Return a vertex slice of the whole mesh. - fn to_slice(&self, ty: PrimitiveType) -> Slice { + fn to_slice(&self, ty: PrimitiveType) -> Slice { Slice { start: 0, end: self.num_vertices, @@ -147,9 +152,9 @@ impl ToSlice for Mesh { } } -impl ToSlice for BufferHandle { +impl ToSlice for BufferHandle { /// Return an index slice of the whole buffer. - fn to_slice(&self, ty: PrimitiveType) -> Slice { + fn to_slice(&self, ty: PrimitiveType) -> Slice { Slice { start: 0, end: self.len() as VertexCount, @@ -159,9 +164,9 @@ impl ToSlice for BufferHandle { } } -impl ToSlice for BufferHandle { +impl ToSlice for BufferHandle { /// Return an index slice of the whole buffer. - fn to_slice(&self, ty: PrimitiveType) -> Slice { + fn to_slice(&self, ty: PrimitiveType) -> Slice { Slice { start: 0, end: self.len() as VertexCount, @@ -171,9 +176,9 @@ impl ToSlice for BufferHandle { } } -impl ToSlice for BufferHandle { +impl ToSlice for BufferHandle { /// Return an index slice of the whole buffer. - fn to_slice(&self, ty: PrimitiveType) -> Slice { + fn to_slice(&self, ty: PrimitiveType) -> Slice { Slice { start: 0, end: self.len() as VertexCount,