[user texture] change uv to normalized texture coords in 0-1 range
This commit is contained in:
parent
db2afadc76
commit
13060d495b
5 changed files with 39 additions and 54 deletions
|
@ -23,37 +23,40 @@ impl Texture {
|
||||||
let rect = ui.allocate_space(size);
|
let rect = ui.allocate_space(size);
|
||||||
let top_left = Vertex {
|
let top_left = Vertex {
|
||||||
pos: rect.min,
|
pos: rect.min,
|
||||||
uv: (0, 0),
|
uv: pos2(0.0, 0.0),
|
||||||
color: WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let bottom_right = Vertex {
|
let bottom_right = Vertex {
|
||||||
pos: rect.max,
|
pos: rect.max,
|
||||||
uv: (self.width as u16 - 1, self.height as u16 - 1),
|
uv: pos2(1.0, 1.0),
|
||||||
color: WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let mut triangles = Triangles::default();
|
let mut triangles = Triangles::default();
|
||||||
triangles.add_rect(top_left, bottom_right);
|
triangles.add_rect(top_left, bottom_right);
|
||||||
ui.painter().add(PaintCmd::Triangles(triangles));
|
ui.painter().add(PaintCmd::Triangles(triangles));
|
||||||
|
|
||||||
|
let tex_w = self.width as f32;
|
||||||
|
let tex_h = self.height as f32;
|
||||||
|
|
||||||
if ui.hovered(rect) {
|
if ui.hovered(rect) {
|
||||||
show_tooltip(ui.ctx(), |ui| {
|
show_tooltip(ui.ctx(), |ui| {
|
||||||
let pos = ui.top_left();
|
let pos = ui.input().mouse.pos.unwrap_or_else(|| ui.top_left());
|
||||||
let zoom_rect = ui.allocate_space(vec2(128.0, 128.0));
|
let zoom_rect = ui.allocate_space(vec2(128.0, 128.0));
|
||||||
let u = remap_clamp(pos.x, rect.range_x(), 0.0..=self.width as f32 - 1.0).round();
|
let u = remap_clamp(pos.x, rect.range_x(), 0.0..=tex_w);
|
||||||
let v = remap_clamp(pos.y, rect.range_y(), 0.0..=self.height as f32 - 1.0).round();
|
let v = remap_clamp(pos.y, rect.range_y(), 0.0..=tex_h);
|
||||||
|
|
||||||
let texel_radius = 32.0;
|
let texel_radius = 32.0;
|
||||||
let u = u.max(texel_radius);
|
let u = u.max(texel_radius).min(tex_w - texel_radius);
|
||||||
let v = v.max(texel_radius);
|
let v = v.max(texel_radius).min(tex_h - texel_radius);
|
||||||
|
|
||||||
let top_left = Vertex {
|
let top_left = Vertex {
|
||||||
pos: zoom_rect.min,
|
pos: zoom_rect.min,
|
||||||
uv: ((u - texel_radius) as u16, (v - texel_radius) as u16),
|
uv: pos2((u - texel_radius) / tex_w, (v - texel_radius) / tex_h),
|
||||||
color: WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let bottom_right = Vertex {
|
let bottom_right = Vertex {
|
||||||
pos: zoom_rect.max,
|
pos: zoom_rect.max,
|
||||||
uv: ((u + texel_radius) as u16, (v + texel_radius) as u16),
|
uv: pos2((u + texel_radius) / tex_w, (v + texel_radius) / tex_h),
|
||||||
color: WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let mut triangles = Triangles::default();
|
let mut triangles = Triangles::default();
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub struct Pos2 {
|
||||||
// implicit w = 1
|
// implicit w = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pos2(x: f32, y: f32) -> Pos2 {
|
pub const fn pos2(x: f32, y: f32) -> Pos2 {
|
||||||
Pos2 { x, y }
|
Pos2 { x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ impl From<&[f32; 2]> for Pos2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pos2 {
|
impl Pos2 {
|
||||||
pub fn new(x: f32, y: f32) -> Self {
|
pub const fn new(x: f32, y: f32) -> Self {
|
||||||
Self { x, y }
|
Self { x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ use {
|
||||||
/// The default Egui texture has the top-left corner pixel fully white.
|
/// The default Egui texture has the top-left corner pixel fully white.
|
||||||
/// You need need use a clamping texture sampler for this to work
|
/// You need need use a clamping texture sampler for this to work
|
||||||
/// (so it doesn't do bilinear blending with bottom right corner).
|
/// (so it doesn't do bilinear blending with bottom right corner).
|
||||||
pub const WHITE_UV: (u16, u16) = (0, 0);
|
pub const WHITE_UV: Pos2 = pos2(0.0, 0.0);
|
||||||
|
|
||||||
/// The vertex type.
|
/// The vertex type.
|
||||||
///
|
///
|
||||||
|
@ -30,9 +30,10 @@ pub struct Vertex {
|
||||||
/// (0,0) is the top left corner of the screen.
|
/// (0,0) is the top left corner of the screen.
|
||||||
pub pos: Pos2, // 64 bit
|
pub pos: Pos2, // 64 bit
|
||||||
|
|
||||||
/// Texel coordinates in the texture.
|
/// Normalized texture coordinates.
|
||||||
/// (0, 0) is the top left corner of the texture.
|
/// (0, 0) is the top left corner of the texture.
|
||||||
pub uv: (u16, u16), // 32 bit
|
/// (1, 1) is the bottom right corner of the texture.
|
||||||
|
pub uv: Pos2, // 64 bit
|
||||||
|
|
||||||
/// sRGBA with premultiplied alpha
|
/// sRGBA with premultiplied alpha
|
||||||
pub color: Srgba, // 32 bit
|
pub color: Srgba, // 32 bit
|
||||||
|
@ -109,12 +110,12 @@ impl Triangles {
|
||||||
|
|
||||||
let top_right = Vertex {
|
let top_right = Vertex {
|
||||||
pos: pos2(bottom_right.pos.x, top_left.pos.y),
|
pos: pos2(bottom_right.pos.x, top_left.pos.y),
|
||||||
uv: (bottom_right.uv.0, top_left.uv.1),
|
uv: pos2(bottom_right.uv.x, top_left.uv.y),
|
||||||
color: top_left.color,
|
color: top_left.color,
|
||||||
};
|
};
|
||||||
let botom_left = Vertex {
|
let botom_left = Vertex {
|
||||||
pos: pos2(top_left.pos.x, bottom_right.pos.y),
|
pos: pos2(top_left.pos.x, bottom_right.pos.y),
|
||||||
uv: (top_left.uv.0, bottom_right.uv.1),
|
uv: pos2(top_left.uv.x, bottom_right.uv.y),
|
||||||
color: top_left.color,
|
color: top_left.color,
|
||||||
};
|
};
|
||||||
self.vertices.push(top_left);
|
self.vertices.push(top_left);
|
||||||
|
@ -691,6 +692,9 @@ fn tessellate_paint_command(
|
||||||
out.reserve_triangles(num_chars * 2);
|
out.reserve_triangles(num_chars * 2);
|
||||||
out.reserve_vertices(num_chars * 4);
|
out.reserve_vertices(num_chars * 4);
|
||||||
|
|
||||||
|
let tex_w = fonts.texture().width as f32;
|
||||||
|
let tex_h = fonts.texture().height as f32;
|
||||||
|
|
||||||
let text_offset = vec2(0.0, 1.0); // Eye-balled for buttons. TODO: why is this needed?
|
let text_offset = vec2(0.0, 1.0); // Eye-balled for buttons. TODO: why is this needed?
|
||||||
|
|
||||||
let font = &fonts[text_style];
|
let font = &fonts[text_style];
|
||||||
|
@ -701,14 +705,14 @@ fn tessellate_paint_command(
|
||||||
if let Some(glyph) = font.uv_rect(c) {
|
if let Some(glyph) = font.uv_rect(c) {
|
||||||
let mut top_left = Vertex {
|
let mut top_left = Vertex {
|
||||||
pos: pos + glyph.offset + vec2(*x_offset, line.y_min) + text_offset,
|
pos: pos + glyph.offset + vec2(*x_offset, line.y_min) + text_offset,
|
||||||
uv: glyph.min,
|
uv: pos2(glyph.min.0 as f32 / tex_w, glyph.min.1 as f32 / tex_h),
|
||||||
color,
|
color,
|
||||||
};
|
};
|
||||||
top_left.pos.x = font.round_to_pixel(top_left.pos.x); // Pixel-perfection.
|
top_left.pos.x = font.round_to_pixel(top_left.pos.x); // Pixel-perfection.
|
||||||
top_left.pos.y = font.round_to_pixel(top_left.pos.y); // Pixel-perfection.
|
top_left.pos.y = font.round_to_pixel(top_left.pos.y); // Pixel-perfection.
|
||||||
let bottom_right = Vertex {
|
let bottom_right = Vertex {
|
||||||
pos: top_left.pos + glyph.size,
|
pos: top_left.pos + glyph.size,
|
||||||
uv: glyph.max,
|
uv: pos2(glyph.max.0 as f32 / tex_w, glyph.max.1 as f32 / tex_h),
|
||||||
color,
|
color,
|
||||||
};
|
};
|
||||||
out.add_rect(top_left, bottom_right);
|
out.add_rect(top_left, bottom_right);
|
||||||
|
|
|
@ -25,7 +25,6 @@ impl Painter {
|
||||||
vertex: "
|
vertex: "
|
||||||
#version 140
|
#version 140
|
||||||
uniform vec2 u_screen_size;
|
uniform vec2 u_screen_size;
|
||||||
uniform vec2 u_tex_size;
|
|
||||||
in vec2 a_pos;
|
in vec2 a_pos;
|
||||||
in vec4 a_srgba;
|
in vec4 a_srgba;
|
||||||
in vec2 a_tc;
|
in vec2 a_tc;
|
||||||
|
@ -51,7 +50,7 @@ impl Painter {
|
||||||
0.0,
|
0.0,
|
||||||
1.0);
|
1.0);
|
||||||
v_rgba = linear_from_srgba(a_srgba);
|
v_rgba = linear_from_srgba(a_srgba);
|
||||||
v_tc = a_tc / u_tex_size;
|
v_tc = a_tc;
|
||||||
}
|
}
|
||||||
",
|
",
|
||||||
|
|
||||||
|
@ -73,7 +72,6 @@ impl Painter {
|
||||||
vertex: "
|
vertex: "
|
||||||
#version 110
|
#version 110
|
||||||
uniform vec2 u_screen_size;
|
uniform vec2 u_screen_size;
|
||||||
uniform vec2 u_tex_size;
|
|
||||||
attribute vec2 a_pos;
|
attribute vec2 a_pos;
|
||||||
attribute vec4 a_srgba;
|
attribute vec4 a_srgba;
|
||||||
attribute vec2 a_tc;
|
attribute vec2 a_tc;
|
||||||
|
@ -99,7 +97,7 @@ impl Painter {
|
||||||
0.0,
|
0.0,
|
||||||
1.0);
|
1.0);
|
||||||
v_rgba = linear_from_srgba(a_srgba);
|
v_rgba = linear_from_srgba(a_srgba);
|
||||||
v_tc = a_tc / u_tex_size;
|
v_tc = a_tc;
|
||||||
}
|
}
|
||||||
",
|
",
|
||||||
|
|
||||||
|
@ -120,7 +118,6 @@ impl Painter {
|
||||||
vertex: "
|
vertex: "
|
||||||
#version 100
|
#version 100
|
||||||
uniform mediump vec2 u_screen_size;
|
uniform mediump vec2 u_screen_size;
|
||||||
uniform mediump vec2 u_tex_size;
|
|
||||||
attribute mediump vec2 a_pos;
|
attribute mediump vec2 a_pos;
|
||||||
attribute mediump vec4 a_srgba;
|
attribute mediump vec4 a_srgba;
|
||||||
attribute mediump vec2 a_tc;
|
attribute mediump vec2 a_tc;
|
||||||
|
@ -146,7 +143,7 @@ impl Painter {
|
||||||
0.0,
|
0.0,
|
||||||
1.0);
|
1.0);
|
||||||
v_rgba = linear_from_srgba(a_srgba);
|
v_rgba = linear_from_srgba(a_srgba);
|
||||||
v_tc = a_tc / u_tex_size;
|
v_tc = a_tc;
|
||||||
}
|
}
|
||||||
",
|
",
|
||||||
|
|
||||||
|
@ -207,7 +204,7 @@ impl Painter {
|
||||||
let mut target = display.draw();
|
let mut target = display.draw();
|
||||||
target.clear_color(0.0, 0.0, 0.0, 0.0);
|
target.clear_color(0.0, 0.0, 0.0, 0.0);
|
||||||
for (clip_rect, triangles) in jobs {
|
for (clip_rect, triangles) in jobs {
|
||||||
self.paint_job(&mut target, display, clip_rect, &triangles, texture)
|
self.paint_job(&mut target, display, clip_rect, &triangles)
|
||||||
}
|
}
|
||||||
target.finish().unwrap();
|
target.finish().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -219,7 +216,6 @@ impl Painter {
|
||||||
display: &glium::Display,
|
display: &glium::Display,
|
||||||
clip_rect: Rect,
|
clip_rect: Rect,
|
||||||
triangles: &Triangles,
|
triangles: &Triangles,
|
||||||
texture: &egui::Texture,
|
|
||||||
) {
|
) {
|
||||||
debug_assert!(triangles.is_valid());
|
debug_assert!(triangles.is_valid());
|
||||||
|
|
||||||
|
@ -227,18 +223,18 @@ impl Painter {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
a_pos: [f32; 2],
|
a_pos: [f32; 2],
|
||||||
|
a_tc: [f32; 2],
|
||||||
a_srgba: [u8; 4],
|
a_srgba: [u8; 4],
|
||||||
a_tc: [u16; 2],
|
|
||||||
}
|
}
|
||||||
implement_vertex!(Vertex, a_pos, a_srgba, a_tc);
|
implement_vertex!(Vertex, a_pos, a_tc, a_srgba);
|
||||||
|
|
||||||
let vertices: Vec<Vertex> = triangles
|
let vertices: Vec<Vertex> = triangles
|
||||||
.vertices
|
.vertices
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| Vertex {
|
.map(|v| Vertex {
|
||||||
a_pos: [v.pos.x, v.pos.y],
|
a_pos: [v.pos.x, v.pos.y],
|
||||||
|
a_tc: [v.uv.x, v.uv.y],
|
||||||
a_srgba: v.color.0,
|
a_srgba: v.color.0,
|
||||||
a_tc: [v.uv.0, v.uv.1],
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -257,7 +253,6 @@ impl Painter {
|
||||||
|
|
||||||
let uniforms = uniform! {
|
let uniforms = uniform! {
|
||||||
u_screen_size: [width_points, height_points],
|
u_screen_size: [width_points, height_points],
|
||||||
u_tex_size: [texture.width as f32, texture.height as f32],
|
|
||||||
u_sampler: self.texture.sampled().wrap_function(SamplerWrapFunction::Clamp),
|
u_sampler: self.texture.sampled().wrap_function(SamplerWrapFunction::Clamp),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,6 @@ impl Painter {
|
||||||
r#"
|
r#"
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
uniform vec2 u_screen_size;
|
uniform vec2 u_screen_size;
|
||||||
uniform vec2 u_tex_size;
|
|
||||||
attribute vec2 a_pos;
|
attribute vec2 a_pos;
|
||||||
attribute vec2 a_tc;
|
attribute vec2 a_tc;
|
||||||
attribute vec4 a_srgba;
|
attribute vec4 a_srgba;
|
||||||
|
@ -89,7 +88,7 @@ impl Painter {
|
||||||
0.0,
|
0.0,
|
||||||
1.0);
|
1.0);
|
||||||
v_rgba = linear_from_srgba(a_srgba);
|
v_rgba = linear_from_srgba(a_srgba);
|
||||||
v_tc = a_tc / u_tex_size;
|
v_tc = a_tc;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
)?;
|
)?;
|
||||||
|
@ -206,15 +205,6 @@ impl Painter {
|
||||||
screen_size_points.y,
|
screen_size_points.y,
|
||||||
);
|
);
|
||||||
|
|
||||||
let u_tex_size_loc = gl
|
|
||||||
.get_uniform_location(&self.program, "u_tex_size")
|
|
||||||
.unwrap();
|
|
||||||
gl.uniform2f(
|
|
||||||
Some(&u_tex_size_loc),
|
|
||||||
f32::from(self.tex_size.0),
|
|
||||||
f32::from(self.tex_size.1),
|
|
||||||
);
|
|
||||||
|
|
||||||
let u_sampler_loc = gl.get_uniform_location(&self.program, "u_sampler").unwrap();
|
let u_sampler_loc = gl.get_uniform_location(&self.program, "u_sampler").unwrap();
|
||||||
gl.uniform1i(Some(&u_sampler_loc), 0);
|
gl.uniform1i(Some(&u_sampler_loc), 0);
|
||||||
|
|
||||||
|
@ -267,12 +257,12 @@ impl Painter {
|
||||||
let indices: Vec<u16> = triangles.indices.iter().map(|idx| *idx as u16).collect();
|
let indices: Vec<u16> = triangles.indices.iter().map(|idx| *idx as u16).collect();
|
||||||
|
|
||||||
let mut positions: Vec<f32> = Vec::with_capacity(2 * triangles.vertices.len());
|
let mut positions: Vec<f32> = Vec::with_capacity(2 * triangles.vertices.len());
|
||||||
let mut tex_coords: Vec<u16> = Vec::with_capacity(2 * triangles.vertices.len());
|
let mut tex_coords: Vec<f32> = Vec::with_capacity(2 * triangles.vertices.len());
|
||||||
for v in &triangles.vertices {
|
for v in &triangles.vertices {
|
||||||
positions.push(v.pos.x);
|
positions.push(v.pos.x);
|
||||||
positions.push(v.pos.y);
|
positions.push(v.pos.y);
|
||||||
tex_coords.push(v.uv.0);
|
tex_coords.push(v.uv.x);
|
||||||
tex_coords.push(v.uv.1);
|
tex_coords.push(v.uv.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut colors: Vec<u8> = Vec::with_capacity(4 * triangles.vertices.len());
|
let mut colors: Vec<u8> = Vec::with_capacity(4 * triangles.vertices.len());
|
||||||
|
@ -328,8 +318,8 @@ impl Painter {
|
||||||
let tc_memory_buffer = wasm_bindgen::memory()
|
let tc_memory_buffer = wasm_bindgen::memory()
|
||||||
.dyn_into::<WebAssembly::Memory>()?
|
.dyn_into::<WebAssembly::Memory>()?
|
||||||
.buffer();
|
.buffer();
|
||||||
let tc_ptr = tex_coords.as_ptr() as u32 / 2;
|
let tc_ptr = tex_coords.as_ptr() as u32 / 4;
|
||||||
let tc_array = js_sys::Uint16Array::new(&tc_memory_buffer)
|
let tc_array = js_sys::Float32Array::new(&tc_memory_buffer)
|
||||||
.subarray(tc_ptr, tc_ptr + tex_coords.len() as u32);
|
.subarray(tc_ptr, tc_ptr + tex_coords.len() as u32);
|
||||||
|
|
||||||
gl.bind_buffer(Gl::ARRAY_BUFFER, Some(&self.tc_buffer));
|
gl.bind_buffer(Gl::ARRAY_BUFFER, Some(&self.tc_buffer));
|
||||||
|
@ -342,14 +332,7 @@ impl Painter {
|
||||||
let normalize = false;
|
let normalize = false;
|
||||||
let stride = 0;
|
let stride = 0;
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
gl.vertex_attrib_pointer_with_i32(
|
gl.vertex_attrib_pointer_with_i32(a_tc_loc, 2, Gl::FLOAT, normalize, stride, offset);
|
||||||
a_tc_loc,
|
|
||||||
2,
|
|
||||||
Gl::UNSIGNED_SHORT,
|
|
||||||
normalize,
|
|
||||||
stride,
|
|
||||||
offset,
|
|
||||||
);
|
|
||||||
gl.enable_vertex_attrib_array(a_tc_loc);
|
gl.enable_vertex_attrib_array(a_tc_loc);
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue