1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 21:00:03 -04:00

Partial font texture update (#1149)

This commit is contained in:
Emil Ernerfeldt
2022-01-22 11:23:12 +01:00
committed by GitHub
parent 343f7da564
commit 462f181db3
24 changed files with 393 additions and 255 deletions

View File

@@ -221,8 +221,8 @@ impl AppRunner {
/// Paint the results of the last call to [`Self::logic`].
pub fn paint(&mut self, clipped_meshes: Vec<egui::ClippedMesh>) -> Result<(), JsValue> {
let textures_delta = std::mem::take(&mut self.textures_delta);
for (id, image) in textures_delta.set {
self.painter.set_texture(id, image);
for (id, image_delta) in textures_delta.set {
self.painter.set_texture(id, &image_delta);
}
self.painter.clear(self.app.clear_color());

View File

@@ -40,8 +40,8 @@ impl WrappedGlowPainter {
}
impl crate::Painter for WrappedGlowPainter {
fn set_texture(&mut self, tex_id: egui::TextureId, image: egui::ImageData) {
self.painter.set_texture(&self.glow_ctx, tex_id, &image);
fn set_texture(&mut self, tex_id: egui::TextureId, delta: &egui::epaint::ImageDelta) {
self.painter.set_texture(&self.glow_ctx, tex_id, delta);
}
fn free_texture(&mut self, tex_id: egui::TextureId) {

View File

@@ -1,7 +1,7 @@
use wasm_bindgen::prelude::JsValue;
pub trait Painter {
fn set_texture(&mut self, tex_id: egui::TextureId, image: egui::ImageData);
fn set_texture(&mut self, tex_id: egui::TextureId, delta: &egui::epaint::ImageDelta);
fn free_texture(&mut self, tex_id: egui::TextureId);

View File

@@ -40,13 +40,6 @@ impl WebGlPainter {
// --------------------------------------------------------------------
let egui_texture = gl.create_texture().unwrap();
gl.bind_texture(Gl::TEXTURE_2D, Some(&egui_texture));
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_S, Gl::CLAMP_TO_EDGE as i32);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_T, Gl::CLAMP_TO_EDGE as i32);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MIN_FILTER, Gl::LINEAR as i32);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MAG_FILTER, Gl::LINEAR as i32);
let srgb_supported = matches!(gl.get_extension("EXT_sRGB"), Ok(Some(_)));
let vert_shader = compile_shader(
@@ -222,36 +215,61 @@ impl WebGlPainter {
Ok(())
}
fn set_texture_rgba(&mut self, tex_id: egui::TextureId, size: [usize; 2], pixels: &[u8]) {
fn set_texture_rgba(
&mut self,
tex_id: egui::TextureId,
pos: Option<[usize; 2]>,
[w, h]: [usize; 2],
pixels: &[u8],
) {
let gl = &self.gl;
let gl_texture = gl.create_texture().unwrap();
gl.bind_texture(Gl::TEXTURE_2D, Some(&gl_texture));
let gl_texture = self
.textures
.entry(tex_id)
.or_insert_with(|| gl.create_texture().unwrap());
gl.bind_texture(Gl::TEXTURE_2D, Some(gl_texture));
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_S, Gl::CLAMP_TO_EDGE as _);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_T, Gl::CLAMP_TO_EDGE as _);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MIN_FILTER, Gl::LINEAR as _);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MAG_FILTER, Gl::LINEAR as _);
gl.bind_texture(Gl::TEXTURE_2D, Some(&gl_texture));
let level = 0;
let internal_format = self.texture_format;
let border = 0;
let src_format = self.texture_format;
let src_type = Gl::UNSIGNED_BYTE;
gl.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
Gl::TEXTURE_2D,
level,
internal_format as _,
size[0] as _,
size[1] as _,
border,
src_format,
src_type,
Some(pixels),
)
.unwrap();
self.textures.insert(tex_id, gl_texture);
gl.pixel_storei(Gl::UNPACK_ALIGNMENT, 1);
if let Some([x, y]) = pos {
gl.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_u8_array(
Gl::TEXTURE_2D,
level,
x as _,
y as _,
w as _,
h as _,
src_format,
src_type,
Some(pixels),
)
.unwrap();
} else {
gl.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
Gl::TEXTURE_2D,
level,
internal_format as _,
w as _,
h as _,
border,
src_format,
src_type,
Some(pixels),
)
.unwrap();
}
}
}
@@ -271,8 +289,8 @@ impl epi::NativeTexture for WebGlPainter {
}
impl crate::Painter for WebGlPainter {
fn set_texture(&mut self, tex_id: egui::TextureId, image: egui::ImageData) {
match image {
fn set_texture(&mut self, tex_id: egui::TextureId, delta: &egui::epaint::ImageDelta) {
match &delta.image {
egui::ImageData::Color(image) => {
assert_eq!(
image.width() * image.height(),
@@ -281,7 +299,7 @@ impl crate::Painter for WebGlPainter {
);
let data: &[u8] = bytemuck::cast_slice(image.pixels.as_ref());
self.set_texture_rgba(tex_id, image.size, data);
self.set_texture_rgba(tex_id, delta.pos, image.size, data);
}
egui::ImageData::Alpha(image) => {
let gamma = if self.post_process.is_none() {
@@ -293,7 +311,7 @@ impl crate::Painter for WebGlPainter {
.srgba_pixels(gamma)
.flat_map(|a| a.to_array())
.collect();
self.set_texture_rgba(tex_id, image.size, &data);
self.set_texture_rgba(tex_id, delta.pos, image.size, &data);
}
};
}

View File

@@ -40,13 +40,6 @@ impl WebGl2Painter {
// --------------------------------------------------------------------
let egui_texture = gl.create_texture().unwrap();
gl.bind_texture(Gl::TEXTURE_2D, Some(&egui_texture));
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_S, Gl::CLAMP_TO_EDGE as i32);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_T, Gl::CLAMP_TO_EDGE as i32);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MIN_FILTER, Gl::LINEAR as i32);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MAG_FILTER, Gl::LINEAR as i32);
let vert_shader = compile_shader(
&gl,
Gl::VERTEX_SHADER,
@@ -206,37 +199,61 @@ impl WebGl2Painter {
Ok(())
}
fn set_texture_rgba(&mut self, tex_id: egui::TextureId, size: [usize; 2], pixels: &[u8]) {
fn set_texture_rgba(
&mut self,
tex_id: egui::TextureId,
pos: Option<[usize; 2]>,
[w, h]: [usize; 2],
pixels: &[u8],
) {
let gl = &self.gl;
let gl_texture = gl.create_texture().unwrap();
gl.bind_texture(Gl::TEXTURE_2D, Some(&gl_texture));
let gl_texture = self
.textures
.entry(tex_id)
.or_insert_with(|| gl.create_texture().unwrap());
gl.bind_texture(Gl::TEXTURE_2D, Some(gl_texture));
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_S, Gl::CLAMP_TO_EDGE as _);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_T, Gl::CLAMP_TO_EDGE as _);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MIN_FILTER, Gl::LINEAR as _);
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MAG_FILTER, Gl::LINEAR as _);
gl.bind_texture(Gl::TEXTURE_2D, Some(&gl_texture));
let level = 0;
let internal_format = Gl::SRGB8_ALPHA8;
let border = 0;
let src_format = Gl::RGBA;
let src_type = Gl::UNSIGNED_BYTE;
gl.pixel_storei(Gl::UNPACK_ALIGNMENT, 1);
gl.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
Gl::TEXTURE_2D,
level,
internal_format as i32,
size[0] as i32,
size[1] as i32,
border,
src_format,
src_type,
Some(pixels),
)
.unwrap();
self.textures.insert(tex_id, gl_texture);
gl.pixel_storei(Gl::UNPACK_ALIGNMENT, 1);
if let Some([x, y]) = pos {
gl.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_u8_array(
Gl::TEXTURE_2D,
level,
x as _,
y as _,
w as _,
h as _,
src_format,
src_type,
Some(pixels),
)
.unwrap();
} else {
gl.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
Gl::TEXTURE_2D,
level,
internal_format as _,
w as _,
h as _,
border,
src_format,
src_type,
Some(pixels),
)
.unwrap();
}
}
}
@@ -256,8 +273,8 @@ impl epi::NativeTexture for WebGl2Painter {
}
impl crate::Painter for WebGl2Painter {
fn set_texture(&mut self, tex_id: egui::TextureId, image: egui::ImageData) {
match image {
fn set_texture(&mut self, tex_id: egui::TextureId, delta: &egui::epaint::ImageDelta) {
match &delta.image {
egui::ImageData::Color(image) => {
assert_eq!(
image.width() * image.height(),
@@ -266,7 +283,7 @@ impl crate::Painter for WebGl2Painter {
);
let data: &[u8] = bytemuck::cast_slice(image.pixels.as_ref());
self.set_texture_rgba(tex_id, image.size, data);
self.set_texture_rgba(tex_id, delta.pos, image.size, data);
}
egui::ImageData::Alpha(image) => {
let gamma = 1.0;
@@ -274,7 +291,7 @@ impl crate::Painter for WebGl2Painter {
.srgba_pixels(gamma)
.flat_map(|a| a.to_array())
.collect();
self.set_texture_rgba(tex_id, image.size, &data);
self.set_texture_rgba(tex_id, delta.pos, image.size, &data);
}
};
}