Skip to content
This repository has been archived by the owner on Jun 20, 2022. It is now read-only.

Commit

Permalink
Merge #57
Browse files Browse the repository at this point in the history
57: Add support for geometry shaders r=jshrake a=jshrake

Closes #48

Co-authored-by: Justin Shrake <justinshrake@gmail.com>
  • Loading branch information
bors[bot] and jshrake committed May 10, 2019
2 parents 576e81b + f8b358e commit 7a91982
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 30 deletions.
1 change: 1 addition & 0 deletions src/config.rs
Expand Up @@ -166,6 +166,7 @@ pub struct PassConfig {
pub draw: DrawConfig,
pub vertex: String,
pub fragment: String,
pub geometry: Option<String>,
#[serde(flatten)]
pub uniform_to_channel: BTreeMap<String, ChannelConfig>,
// render pass settings
Expand Down
56 changes: 45 additions & 11 deletions src/effect.rs
Expand Up @@ -689,15 +689,10 @@ impl<'a> Effect<'a> {
uniform_sampler_strings
};
let vertex_path = &pass_config.vertex;
let fragment_path = &pass_config.fragment;
let vertex_source = self
.shader_cache
.get(vertex_path)
.expect("vertex path not found in shader_cache");
let fragment_source = self
.shader_cache
.get(fragment_path)
.expect("fragment path not found in shader_cache");
let vertex_shader_list = {
let mut list = Vec::new();
list.push(self.version.clone());
Expand All @@ -708,6 +703,17 @@ impl<'a> Effect<'a> {
list.push(vertex_source.clone());
list.join("\n")
};
let vertex_shader =
gl::create_shader(gl, gl::VERTEX_SHADER, &[vertex_shader_list.as_bytes()])
.map_err(|err| Error::glsl_vertex(err, vertex_path.clone()))
.with_context(|_| ErrorKind::GLPass(pass_index))?;
assert!(vertex_shader != 0);

let fragment_path = &pass_config.fragment;
let fragment_source = self
.shader_cache
.get(fragment_path)
.expect("fragment path not found in shader_cache");
let fragment_shader_list = {
let mut list = Vec::new();
list.push(self.version.clone());
Expand All @@ -718,11 +724,6 @@ impl<'a> Effect<'a> {
list.push(fragment_source.clone());
list.join("\n")
};
let vertex_shader =
gl::create_shader(gl, gl::VERTEX_SHADER, &[vertex_shader_list.as_bytes()])
.map_err(|err| Error::glsl_vertex(err, vertex_path.clone()))
.with_context(|_| ErrorKind::GLPass(pass_index))?;
assert!(vertex_shader != 0);
let fragment_shader =
gl::create_shader(gl, gl::FRAGMENT_SHADER, &[fragment_shader_list.as_bytes()])
.map_err(|err| {
Expand All @@ -731,7 +732,40 @@ impl<'a> Effect<'a> {
})
.with_context(|_| ErrorKind::GLPass(pass_index))?;
assert!(fragment_shader != 0);
let program = gl::create_program(gl, vertex_shader, fragment_shader)

let geometry_shader = {
if let Some(geometry_path) = &pass_config.geometry {
let geometry_source = self
.shader_cache
.get(geometry_path)
.expect("fragment path not found in shader_cache");
let geometry_shader_list = {
let mut list = Vec::new();
list.push(self.version.clone());
list.push(include_str!("./shadertoy_uniforms.glsl").to_string());
list.append(&mut uniform_strings.clone());
list.append(&mut uniform_sampler_strings.clone());
list.push("#line 1 0".to_string());
list.push(geometry_source.clone());
list.join("\n")
};
let geometry_shader = gl::create_shader(
gl,
gl::GEOMETRY_SHADER,
&[geometry_shader_list.as_bytes()],
)
.map_err(|err| {
gl.delete_shader(vertex_shader);
gl.delete_shader(fragment_shader);
Error::glsl_fragment(err, geometry_path.clone())
})
.with_context(|_| ErrorKind::GLPass(pass_index))?;
Some(geometry_shader)
} else {
None
}
};
let program = gl::create_program(gl, vertex_shader, fragment_shader, geometry_shader)
.map_err(|err| {
gl.delete_shader(vertex_shader);
gl.delete_shader(fragment_shader);
Expand Down
41 changes: 27 additions & 14 deletions src/effect_player.rs
Expand Up @@ -132,20 +132,33 @@ impl<'a> EffectPlayer<'a> {
// clear and repopulate shader streams
self.shader_streams.clear();
for pass_config in &effect_config.passes {
let vertex_path_str = &pass_config.vertex;
let fragment_path_str = &pass_config.fragment;
let vertex_path = Path::new(vertex_path_str);
let fragment_path = Path::new(fragment_path_str);
let vertex_path =
std::fs::canonicalize(vertex_path).expect("canonicalize failed on vertex path");
let fragment_path = std::fs::canonicalize(fragment_path)
.expect("canonicalize failed on fragment path");
let vertex_stream = FileStream::new(vertex_path.as_path())?;
let fragment_stream = FileStream::new(fragment_path.as_path())?;
self.shader_streams
.insert(vertex_path_str.clone(), vertex_stream);
self.shader_streams
.insert(fragment_path_str.clone(), fragment_stream);
{
let vertex_path_str = &pass_config.vertex;
let vertex_path = Path::new(vertex_path_str);
let vertex_path = std::fs::canonicalize(vertex_path)
.expect("canonicalize failed on vertex path");
let vertex_stream = FileStream::new(vertex_path.as_path())?;
self.shader_streams
.insert(vertex_path_str.clone(), vertex_stream);
}
{
let fragment_path_str = &pass_config.fragment;
let fragment_path = Path::new(fragment_path_str);
let fragment_path = std::fs::canonicalize(fragment_path)
.expect("canonicalize failed on fragment path");
let fragment_stream = FileStream::new(fragment_path.as_path())?;
self.shader_streams
.insert(fragment_path_str.clone(), fragment_stream);
}
if let Some(ref geometry_path_str) = pass_config.geometry {
let geometry_path = Path::new(geometry_path_str);
let geometry_path = std::fs::canonicalize(geometry_path)
.expect("canonicalize failed on geometry path");
let geometry_stream = FileStream::new(geometry_path.as_path())?;
self.shader_streams
.insert(geometry_path_str.clone(), geometry_stream);

}
}
self.effect.stage_config(effect_config)?;
}
Expand Down
14 changes: 9 additions & 5 deletions src/gl.rs
Expand Up @@ -48,26 +48,30 @@ pub fn create_shader(gl: &GLRc, shader_type: GLenum, source: &[&[u8]]) -> Result
}

#[allow(dead_code)]
pub fn create_program(gl: &GLRc, vs: GLuint, fs: GLuint) -> Result<GLuint, String> {
pub fn create_program(gl: &GLRc, vs: GLuint, fs: GLuint, gs: Option<GLuint>) -> Result<GLuint, String> {
let program = gl.create_program();
assert!(program != 0);
gl.attach_shader(program, vs);
if let Some(gs) = gs {
gl.attach_shader(program, gs);
}
gl.attach_shader(program, fs);
gl.link_program(program);
let linked = unsafe {
let mut linked: [i32; 1] = [0];
gl.get_program_iv(program, gl::LINK_STATUS, &mut linked);
linked[0]
};
gl.detach_shader(program, vs);
if let Some(gs) = gs {
gl.detach_shader(program, gs);
}
gl.detach_shader(program, fs);
if linked == 0 {
let log = gl.get_program_info_log(program);
gl.detach_shader(program, vs);
gl.detach_shader(program, fs);
gl.delete_program(program);
return Err(log.trim().to_string());
}
gl.detach_shader(program, vs);
gl.detach_shader(program, fs);
Ok(program)
}

Expand Down

0 comments on commit 7a91982

Please sign in to comment.