diff options
| author | 2022-01-19 22:04:53 -0300 | |
|---|---|---|
| committer | 2022-01-19 22:08:41 -0300 | |
| commit | 424e1d3fda3c9e1764b567a3b05d33a9ed589fda (patch) | |
| tree | 6677a55a918e75a6982e2a81e36051d704d87300 /glow/src | |
| 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 '')
| -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")],              )          }; | 
