Make compatible with GLES 2.0 (GLSL 1.20)
This commit is contained in:
parent
2f47858662
commit
6472746bd2
|
@ -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]
|
||||
|
|
|
@ -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 {
|
||||
|
|
115
src/pipeline.rs
115
src/pipeline.rs
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue