From 13060d495bb00da1088cf43b505292e7d7dec547 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 9 Sep 2020 17:14:42 +0200 Subject: [PATCH] [user texture] change uv to normalized texture coords in 0-1 range --- egui/src/introspection.rs | 21 ++++++++++++--------- egui/src/math/pos2.rs | 4 ++-- egui/src/paint/tessellator.rs | 18 +++++++++++------- egui_glium/src/painter.rs | 19 +++++++------------ egui_web/src/webgl.rs | 31 +++++++------------------------ 5 files changed, 39 insertions(+), 54 deletions(-) diff --git a/egui/src/introspection.rs b/egui/src/introspection.rs index 99de597d..2edc381c 100644 --- a/egui/src/introspection.rs +++ b/egui/src/introspection.rs @@ -23,37 +23,40 @@ impl Texture { let rect = ui.allocate_space(size); let top_left = Vertex { pos: rect.min, - uv: (0, 0), + uv: pos2(0.0, 0.0), color: WHITE, }; let bottom_right = Vertex { pos: rect.max, - uv: (self.width as u16 - 1, self.height as u16 - 1), + uv: pos2(1.0, 1.0), color: WHITE, }; let mut triangles = Triangles::default(); triangles.add_rect(top_left, bottom_right); ui.painter().add(PaintCmd::Triangles(triangles)); + let tex_w = self.width as f32; + let tex_h = self.height as f32; + if ui.hovered(rect) { 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 u = remap_clamp(pos.x, rect.range_x(), 0.0..=self.width as f32 - 1.0).round(); - let v = remap_clamp(pos.y, rect.range_y(), 0.0..=self.height 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..=tex_h); let texel_radius = 32.0; - let u = u.max(texel_radius); - let v = v.max(texel_radius); + let u = u.max(texel_radius).min(tex_w - texel_radius); + let v = v.max(texel_radius).min(tex_h - texel_radius); let top_left = Vertex { 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, }; let bottom_right = Vertex { 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, }; let mut triangles = Triangles::default(); diff --git a/egui/src/math/pos2.rs b/egui/src/math/pos2.rs index ff6124d6..91e4c7f6 100644 --- a/egui/src/math/pos2.rs +++ b/egui/src/math/pos2.rs @@ -14,7 +14,7 @@ pub struct Pos2 { // implicit w = 1 } -pub fn pos2(x: f32, y: f32) -> Pos2 { +pub const fn pos2(x: f32, y: f32) -> Pos2 { Pos2 { x, y } } @@ -31,7 +31,7 @@ impl From<&[f32; 2]> for Pos2 { } impl Pos2 { - pub fn new(x: f32, y: f32) -> Self { + pub const fn new(x: f32, y: f32) -> Self { Self { x, y } } diff --git a/egui/src/paint/tessellator.rs b/egui/src/paint/tessellator.rs index dd4ff57c..fd15c491 100644 --- a/egui/src/paint/tessellator.rs +++ b/egui/src/paint/tessellator.rs @@ -18,7 +18,7 @@ use { /// The default Egui texture has the top-left corner pixel fully white. /// You need need use a clamping texture sampler for this to work /// (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. /// @@ -30,9 +30,10 @@ pub struct Vertex { /// (0,0) is the top left corner of the screen. pub pos: Pos2, // 64 bit - /// Texel coordinates in the texture. + /// Normalized texture coordinates. /// (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 pub color: Srgba, // 32 bit @@ -109,12 +110,12 @@ impl Triangles { let top_right = Vertex { 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, }; let botom_left = Vertex { 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, }; self.vertices.push(top_left); @@ -691,6 +692,9 @@ fn tessellate_paint_command( out.reserve_triangles(num_chars * 2); 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 font = &fonts[text_style]; @@ -701,14 +705,14 @@ fn tessellate_paint_command( if let Some(glyph) = font.uv_rect(c) { let mut top_left = Vertex { 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, }; 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. let bottom_right = Vertex { 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, }; out.add_rect(top_left, bottom_right); diff --git a/egui_glium/src/painter.rs b/egui_glium/src/painter.rs index 337a988c..2901e593 100644 --- a/egui_glium/src/painter.rs +++ b/egui_glium/src/painter.rs @@ -25,7 +25,6 @@ impl Painter { vertex: " #version 140 uniform vec2 u_screen_size; - uniform vec2 u_tex_size; in vec2 a_pos; in vec4 a_srgba; in vec2 a_tc; @@ -51,7 +50,7 @@ impl Painter { 0.0, 1.0); 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: " #version 110 uniform vec2 u_screen_size; - uniform vec2 u_tex_size; attribute vec2 a_pos; attribute vec4 a_srgba; attribute vec2 a_tc; @@ -99,7 +97,7 @@ impl Painter { 0.0, 1.0); 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: " #version 100 uniform mediump vec2 u_screen_size; - uniform mediump vec2 u_tex_size; attribute mediump vec2 a_pos; attribute mediump vec4 a_srgba; attribute mediump vec2 a_tc; @@ -146,7 +143,7 @@ impl Painter { 0.0, 1.0); 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(); target.clear_color(0.0, 0.0, 0.0, 0.0); 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(); } @@ -219,7 +216,6 @@ impl Painter { display: &glium::Display, clip_rect: Rect, triangles: &Triangles, - texture: &egui::Texture, ) { debug_assert!(triangles.is_valid()); @@ -227,18 +223,18 @@ impl Painter { #[derive(Copy, Clone)] struct Vertex { a_pos: [f32; 2], + a_tc: [f32; 2], 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 = triangles .vertices .iter() .map(|v| Vertex { a_pos: [v.pos.x, v.pos.y], + a_tc: [v.uv.x, v.uv.y], a_srgba: v.color.0, - a_tc: [v.uv.0, v.uv.1], }) .collect(); @@ -257,7 +253,6 @@ impl Painter { let uniforms = uniform! { 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), }; diff --git a/egui_web/src/webgl.rs b/egui_web/src/webgl.rs index 7e5f06b7..26183be4 100644 --- a/egui_web/src/webgl.rs +++ b/egui_web/src/webgl.rs @@ -63,7 +63,6 @@ impl Painter { r#" precision mediump float; uniform vec2 u_screen_size; - uniform vec2 u_tex_size; attribute vec2 a_pos; attribute vec2 a_tc; attribute vec4 a_srgba; @@ -89,7 +88,7 @@ impl Painter { 0.0, 1.0); 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, ); - 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(); gl.uniform1i(Some(&u_sampler_loc), 0); @@ -267,12 +257,12 @@ impl Painter { let indices: Vec = triangles.indices.iter().map(|idx| *idx as u16).collect(); let mut positions: Vec = Vec::with_capacity(2 * triangles.vertices.len()); - let mut tex_coords: Vec = Vec::with_capacity(2 * triangles.vertices.len()); + let mut tex_coords: Vec = Vec::with_capacity(2 * triangles.vertices.len()); for v in &triangles.vertices { positions.push(v.pos.x); positions.push(v.pos.y); - tex_coords.push(v.uv.0); - tex_coords.push(v.uv.1); + tex_coords.push(v.uv.x); + tex_coords.push(v.uv.y); } let mut colors: Vec = Vec::with_capacity(4 * triangles.vertices.len()); @@ -328,8 +318,8 @@ impl Painter { let tc_memory_buffer = wasm_bindgen::memory() .dyn_into::()? .buffer(); - let tc_ptr = tex_coords.as_ptr() as u32 / 2; - let tc_array = js_sys::Uint16Array::new(&tc_memory_buffer) + let tc_ptr = tex_coords.as_ptr() as u32 / 4; + let tc_array = js_sys::Float32Array::new(&tc_memory_buffer) .subarray(tc_ptr, tc_ptr + tex_coords.len() as u32); gl.bind_buffer(Gl::ARRAY_BUFFER, Some(&self.tc_buffer)); @@ -342,14 +332,7 @@ impl Painter { let normalize = false; let stride = 0; let offset = 0; - gl.vertex_attrib_pointer_with_i32( - a_tc_loc, - 2, - Gl::UNSIGNED_SHORT, - normalize, - stride, - offset, - ); + gl.vertex_attrib_pointer_with_i32(a_tc_loc, 2, Gl::FLOAT, normalize, stride, offset); gl.enable_vertex_attrib_array(a_tc_loc); // --------------------------------------------------------------------