Add Shader and Version
to simplify and constrain `program::create`
This commit is contained in:
parent
230db88fb2
commit
424e1d3fda
6 changed files with 157 additions and 135 deletions
|
|
@ -1,29 +1,118 @@
|
|||
use glow::HasContext;
|
||||
|
||||
/// The [`Version`] of a `Program`.
|
||||
pub struct Version {
|
||||
vertex: String,
|
||||
fragment: String,
|
||||
}
|
||||
|
||||
impl Version {
|
||||
pub fn new(gl: &glow::Context) -> Version {
|
||||
let version = gl.version();
|
||||
|
||||
let (vertex, fragment) = match (
|
||||
version.major,
|
||||
version.minor,
|
||||
version.is_embedded,
|
||||
) {
|
||||
// OpenGL 3.0+
|
||||
(3, 0 | 1 | 2, false) => (
|
||||
format!("#version 1{}0", version.minor + 3),
|
||||
format!(
|
||||
"#version 1{}0\n#define HIGHER_THAN_300 1",
|
||||
version.minor + 3
|
||||
),
|
||||
),
|
||||
// OpenGL 3.3+
|
||||
(3 | 4, _, false) => (
|
||||
format!("#version {}{}0", version.major, version.minor),
|
||||
format!(
|
||||
"#version {}{}0\n#define HIGHER_THAN_300 1",
|
||||
version.major, version.minor
|
||||
),
|
||||
),
|
||||
// OpenGL ES 3.0+
|
||||
(3, _, true) => (
|
||||
format!("#version 3{}0 es", version.minor),
|
||||
format!(
|
||||
"#version 3{}0 es\n#define HIGHER_THAN_300 1",
|
||||
version.minor
|
||||
),
|
||||
),
|
||||
// OpenGL ES 2.0+
|
||||
(2, _, true) => (
|
||||
String::from(
|
||||
"#version 100\n#define in attribute\n#define out varying",
|
||||
),
|
||||
String::from("#version 100\n#define in varying"),
|
||||
),
|
||||
// OpenGL 2.1
|
||||
(2, _, false) => (
|
||||
String::from(
|
||||
"#version 120\n#define in attribute\n#define out varying",
|
||||
),
|
||||
String::from("#version 120\n#define in varying"),
|
||||
),
|
||||
// OpenGL 1.1+
|
||||
_ => panic!("Incompatible context version: {:?}", version),
|
||||
};
|
||||
|
||||
log::info!("Shader directive: {}", vertex.lines().next().unwrap());
|
||||
|
||||
Version { vertex, fragment }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Shader(<glow::Context as HasContext>::Shader);
|
||||
|
||||
impl Shader {
|
||||
fn compile(gl: &glow::Context, stage: u32, content: &str) -> Shader {
|
||||
unsafe {
|
||||
let shader = gl.create_shader(stage).expect("Cannot create shader");
|
||||
|
||||
gl.shader_source(shader, &content);
|
||||
gl.compile_shader(shader);
|
||||
|
||||
if !gl.get_shader_compile_status(shader) {
|
||||
panic!("{}", gl.get_shader_info_log(shader));
|
||||
}
|
||||
|
||||
Shader(shader)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a vertex [`Shader`].
|
||||
pub fn vertex(
|
||||
gl: &glow::Context,
|
||||
version: &Version,
|
||||
content: &'static str,
|
||||
) -> Self {
|
||||
let content = format!("{}\n{}", version.vertex, content);
|
||||
|
||||
Shader::compile(gl, glow::VERTEX_SHADER, &content)
|
||||
}
|
||||
|
||||
/// Creates a fragment [`Shader`].
|
||||
pub fn fragment(
|
||||
gl: &glow::Context,
|
||||
version: &Version,
|
||||
content: &'static str,
|
||||
) -> Self {
|
||||
let content = format!("{}\n{}", version.fragment, content);
|
||||
|
||||
Shader::compile(gl, glow::FRAGMENT_SHADER, &content)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn create(
|
||||
gl: &glow::Context,
|
||||
shader_sources: &[(u32, &str)],
|
||||
shaders: &[Shader],
|
||||
attributes: &[(u32, &str)],
|
||||
) -> <glow::Context as HasContext>::Program {
|
||||
let program = gl.create_program().expect("Cannot create program");
|
||||
|
||||
let mut shaders = Vec::with_capacity(shader_sources.len());
|
||||
|
||||
for (shader_type, shader_source) in shader_sources.iter() {
|
||||
let shader = gl
|
||||
.create_shader(*shader_type)
|
||||
.expect("Cannot create shader");
|
||||
|
||||
gl.shader_source(shader, shader_source);
|
||||
gl.compile_shader(shader);
|
||||
|
||||
if !gl.get_shader_compile_status(shader) {
|
||||
panic!("{}", gl.get_shader_info_log(shader));
|
||||
}
|
||||
|
||||
gl.attach_shader(program, shader);
|
||||
|
||||
shaders.push(shader);
|
||||
for shader in shaders {
|
||||
gl.attach_shader(program, shader.0);
|
||||
}
|
||||
|
||||
for (i, name) in attributes {
|
||||
|
|
@ -36,8 +125,8 @@ pub unsafe fn create(
|
|||
}
|
||||
|
||||
for shader in shaders {
|
||||
gl.detach_shader(program, shader);
|
||||
gl.delete_shader(shader);
|
||||
gl.detach_shader(program, shader.0);
|
||||
gl.delete_shader(shader.0);
|
||||
}
|
||||
|
||||
program
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue