diff options
author | 2022-01-19 22:04:53 -0300 | |
---|---|---|
committer | 2022-01-19 22:08:41 -0300 | |
commit | 424e1d3fda3c9e1764b567a3b05d33a9ed589fda (patch) | |
tree | 6677a55a918e75a6982e2a81e36051d704d87300 /glow | |
parent | 230db88fb2d9454eb13bc4e260723f57f6c4dabe (diff) | |
download | iced-424e1d3fda3c9e1764b567a3b05d33a9ed589fda.tar.gz iced-424e1d3fda3c9e1764b567a3b05d33a9ed589fda.tar.bz2 iced-424e1d3fda3c9e1764b567a3b05d33a9ed589fda.zip |
Add `Shader` and `Version`
to simplify and constrain `program::create`
Diffstat (limited to 'glow')
-rw-r--r-- | glow/src/backend.rs | 54 | ||||
-rw-r--r-- | glow/src/program.rs | 127 | ||||
-rw-r--r-- | glow/src/quad.rs | 7 | ||||
-rw-r--r-- | glow/src/quad/compatibility.rs | 34 | ||||
-rw-r--r-- | glow/src/quad/core.rs | 34 | ||||
-rw-r--r-- | glow/src/triangle.rs | 34 |
6 files changed, 156 insertions, 134 deletions
diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 69d04168..89dc1aaa 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -1,9 +1,9 @@ +use crate::program; use crate::quad; use crate::text; use crate::triangle; use crate::{Settings, Transformation, Viewport}; -use glow::HasContext; use iced_graphics::backend; use iced_graphics::font; use iced_graphics::{Layer, Primitive}; @@ -31,57 +31,7 @@ impl Backend { settings.text_multithreading, ); - let version = gl.version(); - let shader_version = 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: {}", - shader_version.0.lines().next().unwrap() - ); + let shader_version = program::Version::new(gl); let quad_pipeline = quad::Pipeline::new(gl, &shader_version); let triangle_pipeline = triangle::Pipeline::new(gl, &shader_version); diff --git a/glow/src/program.rs b/glow/src/program.rs index 13676c70..9a02d578 100644 --- a/glow/src/program.rs +++ b/glow/src/program.rs @@ -1,29 +1,118 @@ use glow::HasContext; -pub unsafe fn create( - gl: &glow::Context, - shader_sources: &[(u32, &str)], - attributes: &[(u32, &str)], -) -> <glow::Context as HasContext>::Program { - let program = gl.create_program().expect("Cannot create program"); +/// 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 mut shaders = Vec::with_capacity(shader_sources.len()); + 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), + }; - for (shader_type, shader_source) in shader_sources.iter() { - let shader = gl - .create_shader(*shader_type) - .expect("Cannot create shader"); + log::info!("Shader directive: {}", vertex.lines().next().unwrap()); - gl.shader_source(shader, shader_source); - gl.compile_shader(shader); + 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"); - if !gl.get_shader_compile_status(shader) { - panic!("{}", gl.get_shader_info_log(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) } + } - gl.attach_shader(program, shader); + /// Creates a vertex [`Shader`]. + pub fn vertex( + gl: &glow::Context, + version: &Version, + content: &'static str, + ) -> Self { + let content = format!("{}\n{}", version.vertex, content); - shaders.push(shader); + 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, + shaders: &[Shader], + attributes: &[(u32, &str)], +) -> <glow::Context as HasContext>::Program { + let program = gl.create_program().expect("Cannot create program"); + + 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 diff --git a/glow/src/quad.rs b/glow/src/quad.rs index e965f3c9..d9f1c6ae 100644 --- a/glow/src/quad.rs +++ b/glow/src/quad.rs @@ -1,6 +1,7 @@ mod compatibility; mod core; +use crate::program; use crate::Transformation; use glow::HasContext; use iced_graphics::layer; @@ -15,12 +16,12 @@ pub enum Pipeline { impl Pipeline { pub fn new( gl: &glow::Context, - shader_version: &(String, String), + shader_version: &program::Version, ) -> Pipeline { - let version = gl.version(); + let gl_version = gl.version(); // OpenGL 3.0+ and OpenGL ES 3.0+ have instancing (which is what separates `core` from `compatibility`) - if version.major >= 3 { + if gl_version.major >= 3 { log::info!("Mode: core"); Pipeline::Core(core::Pipeline::new(gl, shader_version)) } else { diff --git a/glow/src/quad/compatibility.rs b/glow/src/quad/compatibility.rs index 28ad214d..76f98ab7 100644 --- a/glow/src/quad/compatibility.rs +++ b/glow/src/quad/compatibility.rs @@ -1,4 +1,4 @@ -use crate::program; +use crate::program::{self, Shader}; use crate::Transformation; use glow::HasContext; use iced_graphics::layer; @@ -27,29 +27,23 @@ pub struct Pipeline { impl Pipeline { pub fn new( gl: &glow::Context, - (vertex_version, fragment_version): &(String, String), + shader_version: &program::Version, ) -> Pipeline { let program = unsafe { + let vertex_shader = Shader::vertex( + gl, + shader_version, + include_str!("../shader/compatibility/quad.vert"), + ); + let fragment_shader = Shader::fragment( + gl, + shader_version, + include_str!("../shader/compatibility/quad.frag"), + ); + program::create( gl, - &[ - ( - glow::VERTEX_SHADER, - &format!( - "{}\n{}", - vertex_version, - include_str!("../shader/compatibility/quad.vert") - ), - ), - ( - glow::FRAGMENT_SHADER, - &format!( - "{}\n{}", - fragment_version, - include_str!("../shader/compatibility/quad.frag") - ), - ), - ], + &[vertex_shader, fragment_shader], &[ (0, "i_Pos"), (1, "i_Scale"), diff --git a/glow/src/quad/core.rs b/glow/src/quad/core.rs index 274ade67..f37300f6 100644 --- a/glow/src/quad/core.rs +++ b/glow/src/quad/core.rs @@ -1,4 +1,4 @@ -use crate::program; +use crate::program::{self, Shader}; use crate::Transformation; use glow::HasContext; use iced_graphics::layer; @@ -22,29 +22,23 @@ pub struct Pipeline { impl Pipeline { pub fn new( gl: &glow::Context, - (vertex_version, fragment_version): &(String, String), + shader_version: &program::Version, ) -> Pipeline { let program = unsafe { + let vertex_shader = Shader::vertex( + gl, + shader_version, + include_str!("../shader/core/quad.vert"), + ); + let fragment_shader = Shader::fragment( + gl, + shader_version, + include_str!("../shader/core/quad.frag"), + ); + program::create( gl, - &[ - ( - glow::VERTEX_SHADER, - &format!( - "{}\n{}", - vertex_version, - include_str!("../shader/core/quad.vert") - ), - ), - ( - glow::FRAGMENT_SHADER, - &format!( - "{}\n{}", - fragment_version, - include_str!("../shader/core/quad.frag") - ), - ), - ], + &[vertex_shader, fragment_shader], &[ (0, "i_Pos"), (1, "i_Scale"), diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 91bb96ba..ae4f83ef 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -1,5 +1,5 @@ //! Draw meshes of triangles. -use crate::program; +use crate::program::{self, Shader}; use crate::Transformation; use glow::HasContext; use iced_graphics::layer; @@ -23,29 +23,23 @@ pub(crate) struct Pipeline { impl Pipeline { pub fn new( gl: &glow::Context, - (vertex_version, fragment_version): &(String, String), + shader_version: &program::Version, ) -> Pipeline { let program = unsafe { + let vertex_shader = Shader::vertex( + gl, + shader_version, + include_str!("shader/common/triangle.vert"), + ); + let fragment_shader = Shader::fragment( + gl, + shader_version, + include_str!("shader/common/triangle.frag"), + ); + program::create( gl, - &[ - ( - glow::VERTEX_SHADER, - &format!( - "{}\n{}", - vertex_version, - include_str!("shader/common/triangle.vert") - ), - ), - ( - glow::FRAGMENT_SHADER, - &format!( - "{}\n{}", - fragment_version, - include_str!("shader/common/triangle.frag") - ), - ), - ], + &[vertex_shader, fragment_shader], &[(0, "i_Position"), (1, "i_Color")], ) }; |