From 40237b213a847cb3fabaa4da0ef2f295e9bf56a9 Mon Sep 17 00:00:00 2001 From: "M. Stoeckl" Date: Mon, 4 Feb 2019 19:03:25 +0000 Subject: [PATCH] Simplify text shader --- Cargo.lock | 12 ----- Cargo.toml | 1 - res/text.f.glsl | 9 ++-- res/text.v.glsl | 58 +++++++++++------------- src/renderer/mod.rs | 107 ++++++++++++-------------------------------- 5 files changed, 60 insertions(+), 127 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc7bddaf..91d29e3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,6 @@ dependencies = [ "arraydeque 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "copypasta 0.0.1", "dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -283,16 +282,6 @@ dependencies = [ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cgmath" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "approx 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "clang-sys" version = "0.22.0" @@ -2749,7 +2738,6 @@ dependencies = [ "checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum cgl 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "55e7ec0b74fe5897894cbc207092c577e87c52f8a59e8ca8d97ef37551f60a49" -"checksum cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "283944cdecc44bf0b8dd010ec9af888d3b4f142844fdbe026c20ef68148d6fe7" "checksum clang-sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "939a1a34310b120d26eba35c29475933128b0ec58e24b43327f8dbe6036fc538" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum clipboard 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b4623b47d8637fc9d47564583d4cc01eb8c8e34e26b2bf348bf4b036acb657" diff --git a/Cargo.toml b/Cargo.toml index cac5ec4d..7935d346 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ name = "alacritty" [dependencies] libc = "0.2" -cgmath = "0.17" notify = "4" bitflags = "1" font = { path = "./font" } diff --git a/res/text.f.glsl b/res/text.f.glsl index 532cf929..70ad3d19 100644 --- a/res/text.f.glsl +++ b/res/text.f.glsl @@ -13,19 +13,18 @@ // limitations under the License. #version 330 core in vec2 TexCoords; -in vec3 fg; -in vec4 bg; -flat in int background; +flat in vec3 fg; +flat in vec4 bg; +uniform int backgroundPass; layout(location = 0, index = 0) out vec4 color; layout(location = 0, index = 1) out vec4 alphaMask; -uniform float bgOpacity; uniform sampler2D mask; void main() { - if (background != 0) { + if (backgroundPass != 0) { if (bg.a == 0.0) discard; diff --git a/res/text.v.glsl b/res/text.v.glsl index 32aee5ac..369e7c7e 100644 --- a/res/text.v.glsl +++ b/res/text.v.glsl @@ -12,67 +12,63 @@ // See the License for the specific language governing permissions and // limitations under the License. #version 330 core -layout (location = 0) in vec2 position; - // Cell properties -layout (location = 1) in vec2 gridCoords; +layout (location = 0) in vec2 gridCoords; // glyph properties -layout (location = 2) in vec4 glyph; +layout (location = 1) in vec4 glyph; // uv mapping -layout (location = 3) in vec4 uv; +layout (location = 2) in vec4 uv; // text fg color -layout (location = 4) in vec3 textColor; +layout (location = 3) in vec3 textColor; // Background color -layout (location = 5) in vec4 backgroundColor; +layout (location = 4) in vec4 backgroundColor; out vec2 TexCoords; -out vec3 fg; -out vec4 bg; +flat out vec3 fg; +flat out vec4 bg; // Terminal properties -uniform vec2 termDim; uniform vec2 cellDim; +uniform vec4 projection; uniform int backgroundPass; -// Orthographic projection -uniform mat4 projection; -flat out int background; void main() { - vec2 glyphOffset = glyph.xy; - vec2 glyphSize = glyph.zw; - vec2 uvOffset = uv.xy; - vec2 uvSize = uv.zw; + vec2 projectionOffset = projection.xy; + vec2 projectionScale = projection.zw; + + // Compute vertex corner position + vec2 position; + position.x = (gl_VertexID == 0 || gl_VertexID == 1) ? 1. : 0; + position.y = (gl_VertexID == 0 || gl_VertexID == 3) ? 0. : 1; // Position of cell from top-left - vec2 cellPosition = (cellDim) * gridCoords; - - // Invert Y since framebuffer origin is bottom-left - cellPosition.y = termDim.y - cellPosition.y - cellDim.y; + vec2 cellPosition = cellDim * gridCoords; if (backgroundPass != 0) { - cellPosition.y = cellPosition.y; - vec2 finalPosition = cellDim * position + cellPosition; - gl_Position = projection * vec4(finalPosition.xy, 0.0, 1.0); + vec2 finalPosition = cellPosition + cellDim * position; + gl_Position = vec4(projectionOffset + projectionScale * finalPosition, 0.0, 1.0); + TexCoords = vec2(0, 0); } else { - // Glyphs are offset within their cell; account for y-flip - vec2 cellOffset = vec2(glyphOffset.x, glyphOffset.y - glyphSize.y); + vec2 glyphSize = glyph.zw; + vec2 glyphOffset = glyph.xy; + glyphOffset.y = cellDim.y - glyphOffset.y; - // position coordinates are normalized on [0, 1] - vec2 finalPosition = glyphSize * position + cellPosition + cellOffset; + vec2 finalPosition = cellPosition + glyphSize * position + glyphOffset; + gl_Position = vec4(projectionOffset + projectionScale * finalPosition, 0.0, 1.0); - gl_Position = projection * vec4(finalPosition.xy, 0.0, 1.0); - TexCoords = uvOffset + vec2(position.x, 1 - position.y) * uvSize; + vec2 uvOffset = uv.xy; + vec2 uvSize = uv.zw; + TexCoords = uvOffset + position * uvSize; } - background = backgroundPass; bg = vec4(backgroundColor.rgb / 255.0, backgroundColor.a); fg = textColor / vec3(255.0, 255.0, 255.0); } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 1446fe3c..e96d35a5 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -21,7 +21,6 @@ use std::ptr; use std::sync::mpsc; use std::time::Duration; -use cgmath; use fnv::FnvHasher; use glutin::dpi::PhysicalSize; use font::{self, FontDesc, FontKey, GlyphKey, Rasterize, RasterizedGlyph, Rasterizer}; @@ -111,12 +110,9 @@ pub struct TextShaderProgram { // Program id id: GLuint, - /// projection matrix uniform + /// projection scale and offset uniform u_projection: GLint, - /// Terminal dimensions (pixels) - u_term_dim: GLint, - /// Cell dimensions (pixels) u_cell_dim: GLint, @@ -486,13 +482,11 @@ const BATCH_MAX: usize = 0x1_0000; const ATLAS_SIZE: i32 = 1024; impl QuadRenderer { - // TODO should probably hand this a transform instead of width/height pub fn new(size: PhysicalSize) -> Result { let program = TextShaderProgram::new(size)?; let rect_program = RectShaderProgram::new()?; let mut vao: GLuint = 0; - let mut vbo: GLuint = 0; let mut ebo: GLuint = 0; let mut vbo_instance: GLuint = 0; @@ -506,42 +500,14 @@ impl QuadRenderer { gl::BlendFunc(gl::SRC1_COLOR, gl::ONE_MINUS_SRC1_COLOR); gl::Enable(gl::MULTISAMPLE); + // Disable depth mask, as the renderer never uses depth tests + gl::DepthMask(gl::FALSE); + gl::GenVertexArrays(1, &mut vao); - gl::GenBuffers(1, &mut vbo); gl::GenBuffers(1, &mut ebo); gl::GenBuffers(1, &mut vbo_instance); gl::BindVertexArray(vao); - // ---------------------------- - // setup vertex position buffer - // ---------------------------- - // Top right, Bottom right, Bottom left, Top left - let vertices = [ - PackedVertex { x: 1.0, y: 1.0 }, - PackedVertex { x: 1.0, y: 0.0 }, - PackedVertex { x: 0.0, y: 0.0 }, - PackedVertex { x: 0.0, y: 1.0 }, - ]; - - gl::BindBuffer(gl::ARRAY_BUFFER, vbo); - - gl::VertexAttribPointer( - 0, - 2, - gl::FLOAT, - gl::FALSE, - size_of::() as i32, - ptr::null(), - ); - gl::EnableVertexAttribArray(0); - - gl::BufferData( - gl::ARRAY_BUFFER, - (size_of::() * vertices.len()) as GLsizeiptr, - vertices.as_ptr() as *const _, - gl::STATIC_DRAW, - ); - // --------------------- // Set up element buffer // --------------------- @@ -567,59 +533,59 @@ impl QuadRenderer { ); // coords gl::VertexAttribPointer( - 1, + 0, 2, gl::FLOAT, gl::FALSE, size_of::() as i32, ptr::null(), ); - gl::EnableVertexAttribArray(1); - gl::VertexAttribDivisor(1, 1); + gl::EnableVertexAttribArray(0); + gl::VertexAttribDivisor(0, 1); // glyphoffset gl::VertexAttribPointer( - 2, + 1, 4, gl::FLOAT, gl::FALSE, size_of::() as i32, (2 * size_of::()) as *const _, ); - gl::EnableVertexAttribArray(2); - gl::VertexAttribDivisor(2, 1); + gl::EnableVertexAttribArray(1); + gl::VertexAttribDivisor(1, 1); // uv gl::VertexAttribPointer( - 3, + 2, 4, gl::FLOAT, gl::FALSE, size_of::() as i32, (6 * size_of::()) as *const _, ); - gl::EnableVertexAttribArray(3); - gl::VertexAttribDivisor(3, 1); + gl::EnableVertexAttribArray(2); + gl::VertexAttribDivisor(2, 1); // color gl::VertexAttribPointer( - 4, + 3, 3, gl::FLOAT, gl::FALSE, size_of::() as i32, (10 * size_of::()) as *const _, ); - gl::EnableVertexAttribArray(4); - gl::VertexAttribDivisor(4, 1); + gl::EnableVertexAttribArray(3); + gl::VertexAttribDivisor(3, 1); // color gl::VertexAttribPointer( - 5, + 4, 4, gl::FLOAT, gl::FALSE, size_of::() as i32, (13 * size_of::()) as *const _, ); - gl::EnableVertexAttribArray(5); - gl::VertexAttribDivisor(5, 1); + gl::EnableVertexAttribArray(4); + gl::VertexAttribDivisor(4, 1); // Rectangle setup gl::GenVertexArrays(1, &mut rect_vao); @@ -1174,21 +1140,19 @@ impl TextShaderProgram { } // get uniform locations - let (projection, term_dim, cell_dim, background) = unsafe { + let (projection, cell_dim, background) = unsafe { ( gl::GetUniformLocation(program, cptr!(b"projection\0")), - gl::GetUniformLocation(program, cptr!(b"termDim\0")), gl::GetUniformLocation(program, cptr!(b"cellDim\0")), gl::GetUniformLocation(program, cptr!(b"backgroundPass\0")), ) }; - assert_uniform_valid!(projection, term_dim, cell_dim); + assert_uniform_valid!(projection, cell_dim, background); let shader = TextShaderProgram { id: program, u_projection: projection, - u_term_dim: term_dim, u_cell_dim: cell_dim, u_background: background, }; @@ -1208,36 +1172,23 @@ impl TextShaderProgram { return; } - // set projection uniform - // - // NB Not sure why padding change only requires changing the vertical - // translation in the projection, but this makes everything work - // correctly. - let ortho = cgmath::ortho( - 0., - width - (2. * padding_x), - 2. * padding_y, - height, - -1., - 1., - ); - let projection: [[f32; 4]; 4] = ortho.into(); + // Compute scale and offset factors, from pixel to ndc space. Y is inverted + // [0, width - 2 * padding_x] to [-1, 1] + // [height - 2 * padding_y, 0] to [-1, 1] + let scale_x = 2. / (width - 2. * padding_x); + let scale_y = -2. / (height - 2. * padding_y); + let offset_x = -1.; + let offset_y = 1.; info!("Width: {}, Height: {}", width, height); unsafe { - gl::UniformMatrix4fv( - self.u_projection, - 1, - gl::FALSE, - projection.as_ptr() as *const _, - ); + gl::Uniform4f(self.u_projection, offset_x, offset_y, scale_x, scale_y); } } fn set_term_uniforms(&self, props: &term::SizeInfo) { unsafe { - gl::Uniform2f(self.u_term_dim, props.width, props.height); gl::Uniform2f(self.u_cell_dim, props.cell_width, props.cell_height); } }