Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mesh-Program attribute matching on bind #37

Merged
merged 2 commits into from
Jun 30, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/examples/triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn main() {
stencil: None,
};
renderer.clear(cdata, None);
renderer.draw(mesh.clone(), gfx::VertexSlice(0, 3), None, program);
renderer.draw(mesh, gfx::VertexSlice(0, 3), None, program);
renderer.end_frame();
}
});
Expand Down
8 changes: 4 additions & 4 deletions src/gfx/device/gl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,18 @@ impl Device {

/// Shader Object

pub fn create_shader(&self, stage: super::shade::Stage, data: &[u8]) -> Shader {
pub fn create_shader(&self, stage: super::shade::Stage, data: &[u8]) -> Result<Shader, ()> {
let (name, info) = shade::create_shader(stage, data);
info.map(|info| warn!("\tShader compile log: {}", info));
name.unwrap_or(0)
name
}

/// Shader Program

pub fn create_program(&self, shaders: &[Shader]) -> Program {
pub fn create_program(&self, shaders: &[Shader]) -> Result<super::shade::ProgramMeta, ()> {
let (meta, info) = shade::create_program(shaders);
info.map(|info| warn!("\tProgram link log: {}", info));
match meta { Ok(meta) => meta.name, Err(_) => 0 }
meta
}

pub fn bind_program(&self, program: Program) {
Expand Down
9 changes: 7 additions & 2 deletions src/gfx/device/gl/shade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ fn query_attributes(prog: super::Program) -> Vec<s::Attribute> {
let real_name = name.as_slice().slice_to(length as uint).to_string();
let (base, container) = match StorageType::new(storage) {
Var(b, c) => (b, c),
_ => fail!("Unrecognized attribute storage: {}", storage)
_ => {
error!("Unrecognized attribute storage: {}", storage);
(s::BaseF32, s::Single)
}
};
info!("\t\tAttrib[{}] = '{}'\t{}\t{}", loc, real_name, base, container);
s::Attribute {
Expand Down Expand Up @@ -245,7 +248,9 @@ fn query_parameters(prog: super::Program) -> (Vec<s::UniformVar>, Vec<s::Sampler
active_slot: Cell::new(0),
});
},
Unknown => fail!("Unrecognized uniform storage: {}", storage)
Unknown => {
error!("Unrecognized uniform storage: {}", storage);
},
}
}
(uniforms, textures)
Expand Down
8 changes: 4 additions & 4 deletions src/gfx/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ pub enum Request {
pub enum Reply {
ReplyNewBuffer(dev::Buffer),
ReplyNewArrayBuffer(dev::ArrayBuffer),
ReplyNewShader(dev::Shader),
ReplyNewProgram(dev::Program),
ReplyNewShader(Result<dev::Shader, ()>),
ReplyNewProgram(Result<shade::ProgramMeta, ()>),
}

pub struct Client {
Expand Down Expand Up @@ -97,15 +97,15 @@ impl Client {
self.stream.send(CastSwapBuffers);
}

pub fn new_shader(&self, stage: shade::Stage, code: Vec<u8>) -> dev::Shader {
pub fn new_shader(&self, stage: shade::Stage, code: Vec<u8>) -> Result<dev::Shader, ()> {
self.stream.send(CallNewShader(stage, code));
match self.stream.recv() {
ReplyNewShader(name) => name,
_ => fail!("unexpected device reply")
}
}

pub fn new_program(&self, shaders: Vec<dev::Shader>) -> dev::Program {
pub fn new_program(&self, shaders: Vec<dev::Shader>) -> Result<shade::ProgramMeta, ()> {
self.stream.send(CallNewProgram(shaders));
match self.stream.recv() {
ReplyNewProgram(name) => name,
Expand Down
59 changes: 46 additions & 13 deletions src/gfx/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ use std::kinds::marker;

use device;

use device::shade::{Vertex, Fragment};
use device::shade::{ProgramMeta, Vertex, Fragment};
pub use BufferHandle = device::dev::Buffer;
pub use ProgramHandle = device::dev::Program;
pub use MeshHandle = self::mesh::Mesh;
pub type ProgramHandle = uint;
pub type MeshHandle = uint;
pub type Environment = (); // placeholder

pub mod mesh;
Expand Down Expand Up @@ -96,6 +96,12 @@ impl Client {
}


/// Temporary cache system before we get the handle manager
struct Cache {
pub meshes: Vec<mesh::Mesh>,
pub programs: Vec<ProgramMeta>,
}

struct Server {
no_send: marker::NoSend,
no_share: marker::NoShare,
Expand All @@ -105,6 +111,8 @@ struct Server {
common_array_buffer: device::dev::ArrayBuffer,
/// the default FBO for drawing
default_frame_buffer: device::dev::FrameBuffer,
/// cached meta-data for meshes and programs
cache: Cache,
}

impl Server {
Expand All @@ -117,6 +125,10 @@ impl Server {
device: device,
common_array_buffer: abuf,
default_frame_buffer: 0,
cache: Cache {
meshes: Vec::new(),
programs: Vec::new(),
},
}
}

Expand All @@ -133,6 +145,17 @@ impl Server {
}
}

fn bind_mesh(device: &mut device::Client, mesh: &mesh::Mesh, prog: &ProgramMeta) -> Result<(),()> {
for sat in prog.attributes.iter() {
match mesh.attributes.iter().find(|a| a.name.as_slice() == sat.name.as_slice()) {
Some(vat) => device.bind_attribute(sat.location as u8,
vat.buffer, vat.size as u32, vat.offset as u32, vat.stride as u32),
None => return Err(())
}
}
Ok(())
}

pub fn update(&mut self) -> bool {
loop {
match self.stream.try_recv() {
Expand All @@ -149,14 +172,15 @@ impl Server {
None => unimplemented!()
}
},
Ok(CastDraw(mesh, slice, frame, program)) => {
Ok(CastDraw(mesh_handle, slice, frame, prog_handle)) => {
// bind resources
self.bind_frame(&frame);
self.device.bind_program(program);
self.device.bind_array_buffer(self.common_array_buffer);
for (i, at) in mesh.attributes.iter().enumerate().filter(|&(_,at)| at.buffer!=0) {
self.device.bind_attribute(i as u8, at.buffer,
at.size as u32, at.offset as u32, at.stride as u32);
}
let mesh = self.cache.meshes.get(mesh_handle);
let program = self.cache.programs.get(prog_handle);
Server::bind_mesh(&mut self.device, mesh, program).unwrap();
self.device.bind_program(program.name);
// draw
match slice {
mesh::VertexSlice(start, end) => {
self.device.draw(start, end);
Expand All @@ -171,14 +195,21 @@ impl Server {
self.device.end_frame();
},
Ok(CallNewProgram(vs, fs)) => {
let h_vs = self.device.new_shader(Vertex, vs);
let h_fs = self.device.new_shader(Fragment, fs);
let h_vs = self.device.new_shader(Vertex, vs).unwrap_or(0);
let h_fs = self.device.new_shader(Fragment, fs).unwrap_or(0);
let prog = self.device.new_program(vec!(h_vs, h_fs));
let prog = match prog {
Ok(prog) => {
self.cache.programs.push(prog);
self.cache.programs.len() - 1
},
Err(_) => 0,
};
self.stream.send(ReplyProgram(prog));
},
Ok(CallNewMesh(num_vert, data, count, stride)) => {
let buffer = self.device.new_vertex_buffer(data);
let mut mesh = MeshHandle::new(num_vert);
let mut mesh = mesh::Mesh::new(num_vert);
mesh.attributes.push(mesh::Attribute {
buffer: buffer,
size: count,
Expand All @@ -188,7 +219,9 @@ impl Server {
is_interpolated: false,
name: "a_Pos".to_string(),
});
self.stream.send(ReplyMesh(mesh));
let handle = self.cache.meshes.len();
self.cache.meshes.push(mesh);
self.stream.send(ReplyMesh(handle));
},
Ok(CallNewIndexBuffer(data)) => {
let buffer = self.device.new_index_buffer(data);
Expand Down