summaryrefslogtreecommitdiffstats
path: root/glow
diff options
context:
space:
mode:
authorLibravatar Richard <richardsoncusto@gmail.com>2021-11-11 01:10:47 -0300
committerLibravatar Richard <richardsoncusto@gmail.com>2022-01-19 17:40:17 -0300
commite31566d430093fb084da2e7f4f4ed1b66326edef (patch)
tree328c599dd2d62a32e17e95e792c74054d822537e /glow
parentafdf3e799a7610444208c9568a7cf7531d0c2ef3 (diff)
downloadiced-e31566d430093fb084da2e7f4f4ed1b66326edef.tar.gz
iced-e31566d430093fb084da2e7f4f4ed1b66326edef.tar.bz2
iced-e31566d430093fb084da2e7f4f4ed1b66326edef.zip
Improve shader version selection
Diffstat (limited to 'glow')
-rw-r--r--glow/src/backend.rs57
-rw-r--r--glow/src/program.rs5
-rw-r--r--glow/src/quad.rs20
-rw-r--r--glow/src/quad/compatibility.rs25
-rw-r--r--glow/src/quad/core.rs25
-rw-r--r--glow/src/shader/common/triangle.frag18
-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.frag9
-rw-r--r--glow/src/shader/compatibility/quad.vert2
-rw-r--r--glow/src/shader/compatibility/triangle.frag8
-rw-r--r--glow/src/shader/compatibility/triangle.vert13
-rw-r--r--glow/src/shader/core/quad.frag25
-rw-r--r--glow/src/shader/core/quad.vert4
-rw-r--r--glow/src/shader/core/triangle.frag9
-rw-r--r--glow/src/triangle.rs18
-rw-r--r--glow/src/window/compositor.rs2
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);