diff options
author | 2021-11-11 01:10:47 -0300 | |
---|---|---|
committer | 2022-01-19 17:40:17 -0300 | |
commit | e31566d430093fb084da2e7f4f4ed1b66326edef (patch) | |
tree | 328c599dd2d62a32e17e95e792c74054d822537e /glow | |
parent | afdf3e799a7610444208c9568a7cf7531d0c2ef3 (diff) | |
download | iced-e31566d430093fb084da2e7f4f4ed1b66326edef.tar.gz iced-e31566d430093fb084da2e7f4f4ed1b66326edef.tar.bz2 iced-e31566d430093fb084da2e7f4f4ed1b66326edef.zip |
Improve shader version selection
Diffstat (limited to 'glow')
-rw-r--r-- | glow/src/backend.rs | 57 | ||||
-rw-r--r-- | glow/src/program.rs | 5 | ||||
-rw-r--r-- | glow/src/quad.rs | 20 | ||||
-rw-r--r-- | glow/src/quad/compatibility.rs | 25 | ||||
-rw-r--r-- | glow/src/quad/core.rs | 25 | ||||
-rw-r--r-- | glow/src/shader/common/triangle.frag | 18 | ||||
-rw-r--r-- | glow/src/shader/common/triangle.vert (renamed from glow/src/shader/core/triangle.vert) | 4 | ||||
-rw-r--r-- | glow/src/shader/compatibility/quad.frag | 9 | ||||
-rw-r--r-- | glow/src/shader/compatibility/quad.vert | 2 | ||||
-rw-r--r-- | glow/src/shader/compatibility/triangle.frag | 8 | ||||
-rw-r--r-- | glow/src/shader/compatibility/triangle.vert | 13 | ||||
-rw-r--r-- | glow/src/shader/core/quad.frag | 25 | ||||
-rw-r--r-- | glow/src/shader/core/quad.vert | 4 | ||||
-rw-r--r-- | glow/src/shader/core/triangle.frag | 9 | ||||
-rw-r--r-- | glow/src/triangle.rs | 18 | ||||
-rw-r--r-- | glow/src/window/compositor.rs | 2 |
16 files changed, 178 insertions, 66 deletions
diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 5ab7f922..69d04168 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -3,6 +3,7 @@ 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}; @@ -30,8 +31,60 @@ impl Backend { settings.text_multithreading, ); - let quad_pipeline = quad::Pipeline::new(gl); - let triangle_pipeline = triangle::Pipeline::new(gl); + 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 quad_pipeline = quad::Pipeline::new(gl, &shader_version); + let triangle_pipeline = triangle::Pipeline::new(gl, &shader_version); Self { quad_pipeline, diff --git a/glow/src/program.rs b/glow/src/program.rs index 601f9ce6..13676c70 100644 --- a/glow/src/program.rs +++ b/glow/src/program.rs @@ -3,6 +3,7 @@ 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"); @@ -25,6 +26,10 @@ pub unsafe fn create( shaders.push(shader); } + for (i, name) in attributes { + gl.bind_attrib_location(program, *i, name); + } + gl.link_program(program); if !gl.get_program_link_status(program) { panic!("{}", gl.get_program_info_log(program)); diff --git a/glow/src/quad.rs b/glow/src/quad.rs index 75740c7e..e965f3c9 100644 --- a/glow/src/quad.rs +++ b/glow/src/quad.rs @@ -13,14 +13,22 @@ pub enum Pipeline { } impl Pipeline { - pub fn new(gl: &glow::Context) -> Pipeline { + pub fn new( + gl: &glow::Context, + shader_version: &(String, String), + ) -> Pipeline { let version = gl.version(); - if version.is_embedded || version.major == 2 { - log::info!("Mode: compatibility"); - Pipeline::Compatibility(compatibility::Pipeline::new(gl)) - } else { + + // OpenGL 3.0+ and OpenGL ES 3.0+ have instancing (which is what separates `core` from `compatibility`) + if version.major >= 3 { log::info!("Mode: core"); - Pipeline::Core(core::Pipeline::new(gl)) + Pipeline::Core(core::Pipeline::new(gl, shader_version)) + } else { + log::info!("Mode: compatibility"); + Pipeline::Compatibility(compatibility::Pipeline::new( + gl, + shader_version, + )) } } diff --git a/glow/src/quad/compatibility.rs b/glow/src/quad/compatibility.rs index e083dcf1..28ad214d 100644 --- a/glow/src/quad/compatibility.rs +++ b/glow/src/quad/compatibility.rs @@ -25,20 +25,39 @@ pub struct Pipeline { } impl Pipeline { - pub fn new(gl: &glow::Context) -> Pipeline { + pub fn new( + gl: &glow::Context, + (vertex_version, fragment_version): &(String, String), + ) -> Pipeline { let program = unsafe { program::create( gl, &[ ( glow::VERTEX_SHADER, - include_str!("../shader/compatibility/quad.vert"), + &format!( + "{}\n{}", + vertex_version, + include_str!("../shader/compatibility/quad.vert") + ), ), ( glow::FRAGMENT_SHADER, - include_str!("../shader/compatibility/quad.frag"), + &format!( + "{}\n{}", + fragment_version, + include_str!("../shader/compatibility/quad.frag") + ), ), ], + &[ + (0, "i_Pos"), + (1, "i_Scale"), + (2, "i_Color"), + (3, "i_BorderColor"), + (4, "i_BorderRadius"), + (5, "i_BorderWidth"), + ], ) }; diff --git a/glow/src/quad/core.rs b/glow/src/quad/core.rs index c843e8c7..274ade67 100644 --- a/glow/src/quad/core.rs +++ b/glow/src/quad/core.rs @@ -20,20 +20,39 @@ pub struct Pipeline { } impl Pipeline { - pub fn new(gl: &glow::Context) -> Pipeline { + pub fn new( + gl: &glow::Context, + (vertex_version, fragment_version): &(String, String), + ) -> Pipeline { let program = unsafe { program::create( gl, &[ ( glow::VERTEX_SHADER, - include_str!("../shader/core/quad.vert"), + &format!( + "{}\n{}", + vertex_version, + include_str!("../shader/core/quad.vert") + ), ), ( glow::FRAGMENT_SHADER, - include_str!("../shader/core/quad.frag"), + &format!( + "{}\n{}", + fragment_version, + include_str!("../shader/core/quad.frag") + ), ), ], + &[ + (0, "i_Pos"), + (1, "i_Scale"), + (2, "i_Color"), + (3, "i_BorderColor"), + (4, "i_BorderRadius"), + (5, "i_BorderWidth"), + ], ) }; diff --git a/glow/src/shader/common/triangle.frag b/glow/src/shader/common/triangle.frag new file mode 100644 index 00000000..e8689f2e --- /dev/null +++ b/glow/src/shader/common/triangle.frag @@ -0,0 +1,18 @@ +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif + +#ifdef HIGHER_THAN_300 +out vec4 fragColor; +#define gl_FragColor fragColor +#endif + +in vec4 v_Color; + +void main() { + gl_FragColor = v_Color; +}
\ No newline at end of file diff --git a/glow/src/shader/core/triangle.vert b/glow/src/shader/common/triangle.vert index 895652ea..d0494a5f 100644 --- a/glow/src/shader/core/triangle.vert +++ b/glow/src/shader/common/triangle.vert @@ -1,5 +1,3 @@ -#version 130 - uniform mat4 u_Transform; in vec2 i_Position; @@ -10,4 +8,4 @@ out vec4 v_Color; void main() { gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); v_Color = i_Color; -} +}
\ No newline at end of file diff --git a/glow/src/shader/compatibility/quad.frag b/glow/src/shader/compatibility/quad.frag index c2634c65..8ea5693d 100644 --- a/glow/src/shader/compatibility/quad.frag +++ b/glow/src/shader/compatibility/quad.frag @@ -1,5 +1,10 @@ -#version 100 +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else precision mediump float; +#endif +#endif uniform float u_ScreenHeight; @@ -10,7 +15,7 @@ varying vec2 v_Scale; varying float v_BorderRadius; varying float v_BorderWidth; -float _distance(in vec2 frag_coord, in vec2 position, in vec2 size, float radius) +float _distance(vec2 frag_coord, vec2 position, vec2 size, float radius) { // TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN vec2 inner_size = size - vec2(radius, radius) * 2.0; diff --git a/glow/src/shader/compatibility/quad.vert b/glow/src/shader/compatibility/quad.vert index 0d02e9d0..abe70c0e 100644 --- a/glow/src/shader/compatibility/quad.vert +++ b/glow/src/shader/compatibility/quad.vert @@ -1,5 +1,3 @@ -#version 100 - uniform mat4 u_Transform; uniform float u_Scale; diff --git a/glow/src/shader/compatibility/triangle.frag b/glow/src/shader/compatibility/triangle.frag deleted file mode 100644 index 58fca553..00000000 --- a/glow/src/shader/compatibility/triangle.frag +++ /dev/null @@ -1,8 +0,0 @@ -#version 100 -precision mediump float; - -varying vec4 v_Color; - -void main() { - gl_FragColor = v_Color; -} diff --git a/glow/src/shader/compatibility/triangle.vert b/glow/src/shader/compatibility/triangle.vert deleted file mode 100644 index 975c9781..00000000 --- a/glow/src/shader/compatibility/triangle.vert +++ /dev/null @@ -1,13 +0,0 @@ -#version 100 - -uniform mat4 u_Transform; - -attribute vec2 i_Position; -attribute vec4 i_Color; - -varying vec4 v_Color; - -void main() { - v_Color = i_Color; - gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); -} diff --git a/glow/src/shader/core/quad.frag b/glow/src/shader/core/quad.frag index 18fd5baa..57e2e8e7 100644 --- a/glow/src/shader/core/quad.frag +++ b/glow/src/shader/core/quad.frag @@ -1,4 +1,15 @@ -#version 130 +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif + +#ifdef HIGHER_THAN_300 +out vec4 fragColor; +#define gl_FragColor fragColor +#endif uniform float u_ScreenHeight; @@ -9,9 +20,7 @@ in vec2 v_Scale; in float v_BorderRadius; in float v_BorderWidth; -out vec4 o_Color; - -float distance(in vec2 frag_coord, in vec2 position, in vec2 size, float radius) +float fDistance(vec2 frag_coord, vec2 position, vec2 size, float radius) { // TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN vec2 inner_size = size - vec2(radius, radius) * 2.0; @@ -35,10 +44,10 @@ void main() { vec2 fragCoord = vec2(gl_FragCoord.x, u_ScreenHeight - gl_FragCoord.y); // TODO: Remove branching (?) - if(v_BorderWidth > 0) { + if(v_BorderWidth > 0.0) { float internal_border = max(v_BorderRadius - v_BorderWidth, 0.0); - float internal_distance = distance( + float internal_distance = fDistance( fragCoord, v_Pos + vec2(v_BorderWidth), v_Scale - vec2(v_BorderWidth * 2.0), @@ -56,7 +65,7 @@ void main() { mixed_color = v_Color; } - float d = distance( + float d = fDistance( fragCoord, v_Pos, v_Scale, @@ -66,5 +75,5 @@ void main() { float radius_alpha = 1.0 - smoothstep(max(v_BorderRadius - 0.5, 0.0), v_BorderRadius + 0.5, d); - o_Color = vec4(mixed_color.xyz, mixed_color.w * radius_alpha); + gl_FragColor = vec4(mixed_color.xyz, mixed_color.w * radius_alpha); } diff --git a/glow/src/shader/core/quad.vert b/glow/src/shader/core/quad.vert index 30f28d52..b1fb2365 100644 --- a/glow/src/shader/core/quad.vert +++ b/glow/src/shader/core/quad.vert @@ -1,5 +1,3 @@ -#version 130 - uniform mat4 u_Transform; uniform float u_Scale; @@ -17,7 +15,7 @@ out vec2 v_Scale; out float v_BorderRadius; out float v_BorderWidth; -const vec2 positions[4] = vec2[]( +vec2 positions[4] = vec2[]( vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 0.0), diff --git a/glow/src/shader/core/triangle.frag b/glow/src/shader/core/triangle.frag deleted file mode 100644 index 39c2ff6f..00000000 --- a/glow/src/shader/core/triangle.frag +++ /dev/null @@ -1,9 +0,0 @@ -#version 130 - -in vec4 v_Color; - -out vec4 o_Color; - -void main() { - o_Color = v_Color; -} diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index d0a05be6..91bb96ba 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -21,20 +21,32 @@ pub(crate) struct Pipeline { } impl Pipeline { - pub fn new(gl: &glow::Context) -> Pipeline { + pub fn new( + gl: &glow::Context, + (vertex_version, fragment_version): &(String, String), + ) -> Pipeline { let program = unsafe { program::create( gl, &[ ( glow::VERTEX_SHADER, - include_str!("shader/compatibility/triangle.vert"), + &format!( + "{}\n{}", + vertex_version, + include_str!("shader/common/triangle.vert") + ), ), ( glow::FRAGMENT_SHADER, - include_str!("shader/compatibility/triangle.frag"), + &format!( + "{}\n{}", + fragment_version, + include_str!("shader/common/triangle.frag") + ), ), ], + &[(0, "i_Position"), (1, "i_Color")], ) }; diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs index 8d7d21d3..44019fb2 100644 --- a/glow/src/window/compositor.rs +++ b/glow/src/window/compositor.rs @@ -23,7 +23,7 @@ impl iced_graphics::window::GLCompositor for Compositor { let version = gl.version(); log::info!("Version: {:?}", version); log::info!("Embedded: {}", version.is_embedded); - + let renderer = gl.get_parameter_string(glow::RENDERER); log::info!("Renderer: {}", renderer); |