Improve shader version selection
This commit is contained in:
parent
afdf3e799a
commit
e31566d430
17 changed files with 179 additions and 69 deletions
|
|
@ -18,9 +18,7 @@ use preset::Preset;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
pub fn main() -> iced::Result {
|
pub fn main() -> iced::Result {
|
||||||
env_logger::builder()
|
env_logger::builder().format_timestamp(None).init();
|
||||||
.format_timestamp(None)
|
|
||||||
.init();
|
|
||||||
|
|
||||||
GameOfLife::run(Settings {
|
GameOfLife::run(Settings {
|
||||||
antialiasing: true,
|
antialiasing: true,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use crate::text;
|
||||||
use crate::triangle;
|
use crate::triangle;
|
||||||
use crate::{Settings, Transformation, Viewport};
|
use crate::{Settings, Transformation, Viewport};
|
||||||
|
|
||||||
|
use glow::HasContext;
|
||||||
use iced_graphics::backend;
|
use iced_graphics::backend;
|
||||||
use iced_graphics::font;
|
use iced_graphics::font;
|
||||||
use iced_graphics::{Layer, Primitive};
|
use iced_graphics::{Layer, Primitive};
|
||||||
|
|
@ -30,8 +31,60 @@ impl Backend {
|
||||||
settings.text_multithreading,
|
settings.text_multithreading,
|
||||||
);
|
);
|
||||||
|
|
||||||
let quad_pipeline = quad::Pipeline::new(gl);
|
let version = gl.version();
|
||||||
let triangle_pipeline = triangle::Pipeline::new(gl);
|
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 {
|
Self {
|
||||||
quad_pipeline,
|
quad_pipeline,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use glow::HasContext;
|
||||||
pub unsafe fn create(
|
pub unsafe fn create(
|
||||||
gl: &glow::Context,
|
gl: &glow::Context,
|
||||||
shader_sources: &[(u32, &str)],
|
shader_sources: &[(u32, &str)],
|
||||||
|
attributes: &[(u32, &str)],
|
||||||
) -> <glow::Context as HasContext>::Program {
|
) -> <glow::Context as HasContext>::Program {
|
||||||
let program = gl.create_program().expect("Cannot create program");
|
let program = gl.create_program().expect("Cannot create program");
|
||||||
|
|
||||||
|
|
@ -25,6 +26,10 @@ pub unsafe fn create(
|
||||||
shaders.push(shader);
|
shaders.push(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i, name) in attributes {
|
||||||
|
gl.bind_attrib_location(program, *i, name);
|
||||||
|
}
|
||||||
|
|
||||||
gl.link_program(program);
|
gl.link_program(program);
|
||||||
if !gl.get_program_link_status(program) {
|
if !gl.get_program_link_status(program) {
|
||||||
panic!("{}", gl.get_program_info_log(program));
|
panic!("{}", gl.get_program_info_log(program));
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,22 @@ pub enum Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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();
|
let version = gl.version();
|
||||||
if version.is_embedded || version.major == 2 {
|
|
||||||
log::info!("Mode: compatibility");
|
// OpenGL 3.0+ and OpenGL ES 3.0+ have instancing (which is what separates `core` from `compatibility`)
|
||||||
Pipeline::Compatibility(compatibility::Pipeline::new(gl))
|
if version.major >= 3 {
|
||||||
} else {
|
|
||||||
log::info!("Mode: core");
|
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,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,20 +25,39 @@ pub struct Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
let program = unsafe {
|
||||||
program::create(
|
program::create(
|
||||||
gl,
|
gl,
|
||||||
&[
|
&[
|
||||||
(
|
(
|
||||||
glow::VERTEX_SHADER,
|
glow::VERTEX_SHADER,
|
||||||
include_str!("../shader/compatibility/quad.vert"),
|
&format!(
|
||||||
|
"{}\n{}",
|
||||||
|
vertex_version,
|
||||||
|
include_str!("../shader/compatibility/quad.vert")
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
glow::FRAGMENT_SHADER,
|
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"),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,20 +20,39 @@ pub struct Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
let program = unsafe {
|
||||||
program::create(
|
program::create(
|
||||||
gl,
|
gl,
|
||||||
&[
|
&[
|
||||||
(
|
(
|
||||||
glow::VERTEX_SHADER,
|
glow::VERTEX_SHADER,
|
||||||
include_str!("../shader/core/quad.vert"),
|
&format!(
|
||||||
|
"{}\n{}",
|
||||||
|
vertex_version,
|
||||||
|
include_str!("../shader/core/quad.vert")
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
glow::FRAGMENT_SHADER,
|
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"),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
18
glow/src/shader/common/triangle.frag
Normal file
18
glow/src/shader/common/triangle.frag
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#version 130
|
|
||||||
|
|
||||||
uniform mat4 u_Transform;
|
uniform mat4 u_Transform;
|
||||||
|
|
||||||
in vec2 i_Position;
|
in vec2 i_Position;
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
#version 100
|
#ifdef GL_ES
|
||||||
|
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||||
|
precision highp float;
|
||||||
|
#else
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
uniform float u_ScreenHeight;
|
uniform float u_ScreenHeight;
|
||||||
|
|
||||||
|
|
@ -10,7 +15,7 @@ varying vec2 v_Scale;
|
||||||
varying float v_BorderRadius;
|
varying float v_BorderRadius;
|
||||||
varying float v_BorderWidth;
|
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
|
// TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN
|
||||||
vec2 inner_size = size - vec2(radius, radius) * 2.0;
|
vec2 inner_size = size - vec2(radius, radius) * 2.0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#version 100
|
|
||||||
|
|
||||||
uniform mat4 u_Transform;
|
uniform mat4 u_Transform;
|
||||||
uniform float u_Scale;
|
uniform float u_Scale;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#version 100
|
|
||||||
precision mediump float;
|
|
||||||
|
|
||||||
varying vec4 v_Color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_FragColor = v_Color;
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
uniform float u_ScreenHeight;
|
||||||
|
|
||||||
|
|
@ -9,9 +20,7 @@ in vec2 v_Scale;
|
||||||
in float v_BorderRadius;
|
in float v_BorderRadius;
|
||||||
in float v_BorderWidth;
|
in float v_BorderWidth;
|
||||||
|
|
||||||
out vec4 o_Color;
|
float fDistance(vec2 frag_coord, vec2 position, vec2 size, float radius)
|
||||||
|
|
||||||
float distance(in vec2 frag_coord, in vec2 position, in vec2 size, float radius)
|
|
||||||
{
|
{
|
||||||
// TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN
|
// TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN
|
||||||
vec2 inner_size = size - vec2(radius, radius) * 2.0;
|
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);
|
vec2 fragCoord = vec2(gl_FragCoord.x, u_ScreenHeight - gl_FragCoord.y);
|
||||||
|
|
||||||
// TODO: Remove branching (?)
|
// TODO: Remove branching (?)
|
||||||
if(v_BorderWidth > 0) {
|
if(v_BorderWidth > 0.0) {
|
||||||
float internal_border = max(v_BorderRadius - v_BorderWidth, 0.0);
|
float internal_border = max(v_BorderRadius - v_BorderWidth, 0.0);
|
||||||
|
|
||||||
float internal_distance = distance(
|
float internal_distance = fDistance(
|
||||||
fragCoord,
|
fragCoord,
|
||||||
v_Pos + vec2(v_BorderWidth),
|
v_Pos + vec2(v_BorderWidth),
|
||||||
v_Scale - vec2(v_BorderWidth * 2.0),
|
v_Scale - vec2(v_BorderWidth * 2.0),
|
||||||
|
|
@ -56,7 +65,7 @@ void main() {
|
||||||
mixed_color = v_Color;
|
mixed_color = v_Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
float d = distance(
|
float d = fDistance(
|
||||||
fragCoord,
|
fragCoord,
|
||||||
v_Pos,
|
v_Pos,
|
||||||
v_Scale,
|
v_Scale,
|
||||||
|
|
@ -66,5 +75,5 @@ void main() {
|
||||||
float radius_alpha =
|
float radius_alpha =
|
||||||
1.0 - smoothstep(max(v_BorderRadius - 0.5, 0.0), v_BorderRadius + 0.5, d);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#version 130
|
|
||||||
|
|
||||||
uniform mat4 u_Transform;
|
uniform mat4 u_Transform;
|
||||||
uniform float u_Scale;
|
uniform float u_Scale;
|
||||||
|
|
||||||
|
|
@ -17,7 +15,7 @@ out vec2 v_Scale;
|
||||||
out float v_BorderRadius;
|
out float v_BorderRadius;
|
||||||
out float v_BorderWidth;
|
out float v_BorderWidth;
|
||||||
|
|
||||||
const vec2 positions[4] = vec2[](
|
vec2 positions[4] = vec2[](
|
||||||
vec2(0.0, 0.0),
|
vec2(0.0, 0.0),
|
||||||
vec2(0.0, 1.0),
|
vec2(0.0, 1.0),
|
||||||
vec2(1.0, 0.0),
|
vec2(1.0, 0.0),
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#version 130
|
|
||||||
|
|
||||||
in vec4 v_Color;
|
|
||||||
|
|
||||||
out vec4 o_Color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
o_Color = v_Color;
|
|
||||||
}
|
|
||||||
|
|
@ -21,20 +21,32 @@ pub(crate) struct Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
let program = unsafe {
|
||||||
program::create(
|
program::create(
|
||||||
gl,
|
gl,
|
||||||
&[
|
&[
|
||||||
(
|
(
|
||||||
glow::VERTEX_SHADER,
|
glow::VERTEX_SHADER,
|
||||||
include_str!("shader/compatibility/triangle.vert"),
|
&format!(
|
||||||
|
"{}\n{}",
|
||||||
|
vertex_version,
|
||||||
|
include_str!("shader/common/triangle.vert")
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
glow::FRAGMENT_SHADER,
|
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")],
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue