Make compatible with GLES 2.0 (GLSL 1.20)

This commit is contained in:
Olivier 'reivilibre' 2021-06-26 19:15:19 +01:00
parent 2f47858662
commit 6472746bd2
5 changed files with 86 additions and 98 deletions

View File

@ -1,13 +1,14 @@
[package]
name = "glow_glyph"
version = "0.4.0"
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
# Héctor is the author of glow_glyph and is otherwise unaffiliated
authors = ["Olivier 'reivilibre' <olivier@librepush.net>", "Héctor Ramón Jiménez <hector0193@gmail.com>"]
edition = "2018"
description = "A fast text renderer for glow, powered by glyph_brush"
description = "A fork (supporting old GLES 2.0) of a fast text renderer for glow, powered by glyph_brush"
license = "MIT"
keywords = ["font", "ttf", "truetype", "glow", "text"]
repository = "https://github.com/hecrj/glow_glyph"
documentation = "https://docs.rs/glow_glyph"
repository = "https://bics.ga/reivilibre/glow_glyph_compat"
documentation = "https://docs.rs/glow_glyph_compat"
readme = "README.md"
[dependencies]

View File

@ -9,7 +9,7 @@ mod region;
pub use region::Region;
use pipeline::{Instance, Pipeline};
use pipeline::{Vertex, Pipeline};
pub use builder::GlyphBrushBuilder;
pub use glyph_brush::ab_glyph;
@ -26,6 +26,7 @@ use std::borrow::Cow;
use glyph_brush::{BrushAction, BrushError, DefaultSectionHasher};
use log::{log_enabled, warn};
use crate::pipeline::VertexGroup;
/// Object allowing glyph drawing, containing cache state. Manages glyph positioning cacheing,
/// glyph draw caching & efficient GPU texture cache updating and re-sizing on demand.
@ -33,7 +34,7 @@ use log::{log_enabled, warn};
/// Build using a [`GlyphBrushBuilder`](struct.GlyphBrushBuilder.html).
pub struct GlyphBrush<F = FontArc, H = DefaultSectionHasher> {
pipeline: Pipeline,
glyph_brush: glyph_brush::GlyphBrush<Instance, Extra, F, H>,
glyph_brush: glyph_brush::GlyphBrush<VertexGroup, Extra, F, H>,
}
impl<F: Font, H: BuildHasher> GlyphBrush<F, H> {
@ -209,7 +210,7 @@ impl<F: Font + Sync, H: BuildHasher> GlyphBrush<F, H> {
pipeline.update_cache(context, offset, size, tex_data);
},
Instance::from_vertex,
Vertex::from_vertex,
);
match brush_action {

View File

@ -39,7 +39,7 @@ impl Pipeline {
};
let (vertex_array, instances) =
unsafe { create_instance_buffer(gl, Instance::INITIAL_AMOUNT) };
unsafe { create_instance_buffer(gl, Vertex::INITIAL_AMOUNT) };
let transform = unsafe {
gl.get_uniform_location(program, "transform")
@ -72,7 +72,7 @@ impl Pipeline {
instances,
transform,
current_instances: 0,
supported_instances: Instance::INITIAL_AMOUNT,
supported_instances: Vertex::INITIAL_AMOUNT,
current_transform: IDENTITY_MATRIX,
}
}
@ -115,12 +115,20 @@ impl Pipeline {
gl.bind_vertex_array(Some(self.vertex_array));
gl.draw_arrays_instanced(
glow::TRIANGLE_STRIP,
0,
4,
self.current_instances as i32,
);
// gl.draw_arrays_instanced(
// glow::TRIANGLE_STRIP,
// 0,
// 4,
// self.current_instances as i32,
// );
let num = self.current_instances as i32;
for i in 0..num {
gl.draw_arrays(glow::TRIANGLE_STRIP,
i * 4,
4);
}
gl.bind_vertex_array(None);
gl.bind_texture(glow::TEXTURE_2D, None);
@ -154,7 +162,7 @@ impl Pipeline {
}
}
pub fn upload(&mut self, gl: &glow::Context, instances: &[Instance]) {
pub fn upload(&mut self, gl: &glow::Context, instances: &[VertexGroup]) {
if instances.is_empty() {
self.current_instances = 0;
return;
@ -199,18 +207,23 @@ const IDENTITY_MATRIX: [f32; 16] = [
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Instance {
left_top: [f32; 3],
right_bottom: [f32; 2],
tex_left_top: [f32; 2],
tex_right_bottom: [f32; 2],
pub struct Vertex {
tex_pos: [f32; 2],
pos: [f32; 3],
color: [f32; 4],
}
unsafe impl bytemuck::Zeroable for Instance {}
unsafe impl bytemuck::Pod for Instance {}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct VertexGroup(Vertex, Vertex, Vertex, Vertex);
impl Instance {
unsafe impl bytemuck::Zeroable for Vertex {}
unsafe impl bytemuck::Pod for Vertex {}
unsafe impl bytemuck::Zeroable for VertexGroup {}
unsafe impl bytemuck::Pod for VertexGroup {}
impl Vertex {
const INITIAL_AMOUNT: usize = 50_000;
pub fn from_vertex(
@ -220,7 +233,7 @@ impl Instance {
bounds,
extra,
}: glyph_brush::GlyphVertex,
) -> Instance {
) -> VertexGroup {
let gl_bounds = bounds;
let mut gl_rect = Rect {
@ -257,13 +270,33 @@ impl Instance {
- tex_coords.height() * gl_rect.height() / old_height;
}
Instance {
left_top: [gl_rect.min.x, gl_rect.max.y, extra.z],
right_bottom: [gl_rect.max.x, gl_rect.min.y],
tex_left_top: [tex_coords.min.x, tex_coords.max.y],
tex_right_bottom: [tex_coords.max.x, tex_coords.min.y],
color: extra.color,
}
let left = gl_rect.min.x;
let right = gl_rect.max.x;
let top = gl_rect.max.y;
let bottom = gl_rect.min.y;
let vert0 = Vertex {
tex_pos: [tex_coords.min.x, tex_coords.max.y],
pos: [left, top, extra.z],
color: extra.color
};
let vert1 = Vertex {
tex_pos: [tex_coords.max.x, tex_coords.max.y],
pos: [right, top, extra.z],
color: extra.color
};
let vert2 = Vertex {
tex_pos: [tex_coords.min.x, tex_coords.min.y],
pos: [left, bottom, extra.z],
color: extra.color
};
let vert3 = Vertex {
tex_pos: [tex_coords.max.x, tex_coords.min.y],
pos: [right, bottom, extra.z],
color: extra.color
};
VertexGroup(vert0, vert1, vert2, vert3)
}
}
@ -284,7 +317,7 @@ unsafe fn create_program(
gl.compile_shader(shader);
if !gl.get_shader_compile_status(shader) {
panic!(gl.get_shader_info_log(shader));
panic!("{}", gl.get_shader_info_log(shader));
}
gl.attach_shader(program, shader);
@ -294,7 +327,7 @@ unsafe fn create_program(
gl.link_program(program);
if !gl.get_program_link_status(program) {
panic!(gl.get_program_info_log(program));
panic!("{}", gl.get_program_info_log(program));
}
for shader in shaders {
@ -319,45 +352,27 @@ unsafe fn create_instance_buffer(
gl.bind_buffer(glow::ARRAY_BUFFER, Some(buffer));
gl.buffer_data_size(
glow::ARRAY_BUFFER,
(size * std::mem::size_of::<Instance>()) as i32,
(size * std::mem::size_of::<Vertex>()) as i32,
glow::DYNAMIC_DRAW,
);
let stride = std::mem::size_of::<Instance>() as i32;
let stride = std::mem::size_of::<Vertex>() as i32;
gl.enable_vertex_attrib_array(0);
gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, stride, 0);
gl.vertex_attrib_divisor(0, 1);
gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, stride, 0);
gl.enable_vertex_attrib_array(1);
gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, stride, 4 * 3);
gl.vertex_attrib_divisor(1, 1);
gl.vertex_attrib_pointer_f32(1, 3, glow::FLOAT, false, stride, 4 * 2);
gl.enable_vertex_attrib_array(2);
gl.vertex_attrib_pointer_f32(2, 2, glow::FLOAT, false, stride, 4 * (3 + 2));
gl.vertex_attrib_divisor(2, 1);
gl.enable_vertex_attrib_array(3);
gl.vertex_attrib_pointer_f32(
3,
2,
glow::FLOAT,
false,
stride,
4 * (3 + 2 + 2),
);
gl.vertex_attrib_divisor(3, 1);
gl.enable_vertex_attrib_array(4);
gl.vertex_attrib_pointer_f32(
4,
4,
glow::FLOAT,
false,
stride,
4 * (3 + 2 + 2 + 2),
4 * (2 + 3),
);
gl.vertex_attrib_divisor(4, 1);
gl.bind_vertex_array(None);
gl.bind_buffer(glow::ARRAY_BUFFER, None);

View File

@ -1,14 +1,14 @@
#version 330
#version 120
uniform sampler2D font_sampler;
in vec2 f_tex_pos;
in vec4 f_color;
out vec4 Target0;
varying out vec4 Target0;
void main() {
float alpha = texture(font_sampler, f_tex_pos).r;
float alpha = texture2D(font_sampler, f_tex_pos).r;
if (alpha <= 0.0) {
discard;

View File

@ -1,46 +1,17 @@
#version 330
#version 120
uniform mat4 transform;
layout(location = 0) in vec3 left_top;
layout(location = 1) in vec2 right_bottom;
layout(location = 2) in vec2 tex_left_top;
layout(location = 3) in vec2 tex_right_bottom;
layout(location = 4) in vec4 color;
in vec2 tex_pos;
in vec3 pos;
in vec4 color;
out vec2 f_tex_pos;
out vec4 f_color;
varying out vec2 f_tex_pos;
varying out vec4 f_color;
// generate positional data based on vertex ID
// pass through positional data based
void main() {
vec2 pos = vec2(0.0);
float left = left_top.x;
float right = right_bottom.x;
float top = left_top.y;
float bottom = right_bottom.y;
switch (gl_VertexID) {
case 0:
pos = vec2(left, top);
f_tex_pos = tex_left_top;
break;
case 1:
pos = vec2(right, top);
f_tex_pos = vec2(tex_right_bottom.x, tex_left_top.y);
break;
case 2:
pos = vec2(left, bottom);
f_tex_pos = vec2(tex_left_top.x, tex_right_bottom.y);
break;
case 3:
pos = vec2(right, bottom);
f_tex_pos = tex_right_bottom;
break;
}
f_color = color;
gl_Position = transform * vec4(pos, left_top.z, 1.0);
f_tex_pos = tex_pos;
gl_Position = transform * vec4(pos, 1.0);
}