summaryrefslogtreecommitdiffstats
path: root/glow
diff options
context:
space:
mode:
authorLibravatar Richard <richardsoncusto@gmail.com>2022-01-19 22:04:53 -0300
committerLibravatar Richard <richardsoncusto@gmail.com>2022-01-19 22:08:41 -0300
commit424e1d3fda3c9e1764b567a3b05d33a9ed589fda (patch)
tree6677a55a918e75a6982e2a81e36051d704d87300 /glow
parent230db88fb2d9454eb13bc4e260723f57f6c4dabe (diff)
downloadiced-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.rs54
-rw-r--r--glow/src/program.rs127
-rw-r--r--glow/src/quad.rs7
-rw-r--r--glow/src/quad/compatibility.rs34
-rw-r--r--glow/src/quad/core.rs34
-rw-r--r--glow/src/triangle.rs34
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")],
)
};