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:
@@ -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());
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user