WGPU PaintCallback Fixes (#1704)
* Expose egui WGPU Textures and Limit Exposed API This allows paint callbacks to access textures allocated by egui, and also hides the functions on the `RenderPass` that users should not need to call. * Fix WGPU Rendering Bug When Using Paint Callbacks Depending on the order custom paint callbacks were rendered, some of the egui meshes would previously not be rendered at all in a seemingly random fashion. * Make egui_wgpu::Renderer Functions Public Again
This commit is contained in:
parent
083e20474b
commit
218d4d4eea
1 changed files with 30 additions and 18 deletions
|
@ -339,19 +339,13 @@ impl RenderPass {
|
||||||
// run.
|
// run.
|
||||||
let mut needs_reset = true;
|
let mut needs_reset = true;
|
||||||
|
|
||||||
for (
|
let mut index_buffers = self.index_buffers.iter();
|
||||||
(
|
let mut vertex_buffers = self.vertex_buffers.iter();
|
||||||
egui::ClippedPrimitive {
|
|
||||||
clip_rect,
|
for egui::ClippedPrimitive {
|
||||||
primitive,
|
clip_rect,
|
||||||
},
|
primitive,
|
||||||
vertex_buffer,
|
} in paint_jobs
|
||||||
),
|
|
||||||
index_buffer,
|
|
||||||
) in paint_jobs
|
|
||||||
.iter()
|
|
||||||
.zip(&self.vertex_buffers)
|
|
||||||
.zip(&self.index_buffers)
|
|
||||||
{
|
{
|
||||||
if needs_reset {
|
if needs_reset {
|
||||||
rpass.set_viewport(
|
rpass.set_viewport(
|
||||||
|
@ -384,6 +378,9 @@ impl RenderPass {
|
||||||
match primitive {
|
match primitive {
|
||||||
Primitive::Mesh(mesh) => {
|
Primitive::Mesh(mesh) => {
|
||||||
if let Some((_texture, bind_group)) = self.textures.get(&mesh.texture_id) {
|
if let Some((_texture, bind_group)) = self.textures.get(&mesh.texture_id) {
|
||||||
|
let index_buffer = index_buffers.next().unwrap();
|
||||||
|
let vertex_buffer = vertex_buffers.next().unwrap();
|
||||||
|
|
||||||
rpass.set_bind_group(1, bind_group, &[]);
|
rpass.set_bind_group(1, bind_group, &[]);
|
||||||
rpass.set_index_buffer(
|
rpass.set_index_buffer(
|
||||||
index_buffer.buffer.slice(..),
|
index_buffer.buffer.slice(..),
|
||||||
|
@ -568,6 +565,18 @@ impl RenderPass {
|
||||||
self.textures.remove(id);
|
self.textures.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the WGPU texture and bind group associated to a texture that has been allocated by egui.
|
||||||
|
///
|
||||||
|
/// This could be used by custom paint hooks to render images that have been added through with
|
||||||
|
/// [`egui_extras::RetainedImage`](https://docs.rs/egui_extras/latest/egui_extras/image/struct.RetainedImage.html)
|
||||||
|
/// or [`egui::Context::load_texture`].
|
||||||
|
pub fn get_texture(
|
||||||
|
&self,
|
||||||
|
id: &egui::TextureId,
|
||||||
|
) -> Option<&(Option<wgpu::Texture>, wgpu::BindGroup)> {
|
||||||
|
self.textures.get(id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Registers a `wgpu::Texture` with a `egui::TextureId`.
|
/// Registers a `wgpu::Texture` with a `egui::TextureId`.
|
||||||
///
|
///
|
||||||
/// This enables the application to reference the texture inside an image ui element.
|
/// This enables the application to reference the texture inside an image ui element.
|
||||||
|
@ -669,12 +678,13 @@ impl RenderPass {
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (i, egui::ClippedPrimitive { primitive, .. }) in paint_jobs.iter().enumerate() {
|
let mut mesh_idx = 0;
|
||||||
|
for egui::ClippedPrimitive { primitive, .. } in paint_jobs.iter() {
|
||||||
match primitive {
|
match primitive {
|
||||||
Primitive::Mesh(mesh) => {
|
Primitive::Mesh(mesh) => {
|
||||||
let data: &[u8] = bytemuck::cast_slice(&mesh.indices);
|
let data: &[u8] = bytemuck::cast_slice(&mesh.indices);
|
||||||
if i < self.index_buffers.len() {
|
if mesh_idx < self.index_buffers.len() {
|
||||||
self.update_buffer(device, queue, &BufferType::Index, i, data);
|
self.update_buffer(device, queue, &BufferType::Index, mesh_idx, data);
|
||||||
} else {
|
} else {
|
||||||
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("egui_index_buffer"),
|
label: Some("egui_index_buffer"),
|
||||||
|
@ -688,8 +698,8 @@ impl RenderPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
let data: &[u8] = bytemuck::cast_slice(&mesh.vertices);
|
let data: &[u8] = bytemuck::cast_slice(&mesh.vertices);
|
||||||
if i < self.vertex_buffers.len() {
|
if mesh_idx < self.vertex_buffers.len() {
|
||||||
self.update_buffer(device, queue, &BufferType::Vertex, i, data);
|
self.update_buffer(device, queue, &BufferType::Vertex, mesh_idx, data);
|
||||||
} else {
|
} else {
|
||||||
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("egui_vertex_buffer"),
|
label: Some("egui_vertex_buffer"),
|
||||||
|
@ -702,6 +712,8 @@ impl RenderPass {
|
||||||
size: data.len(),
|
size: data.len(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mesh_idx += 1;
|
||||||
}
|
}
|
||||||
Primitive::Callback(callback) => {
|
Primitive::Callback(callback) => {
|
||||||
let cbfn = if let Some(c) = callback.callback.downcast_ref::<CallbackFn>() {
|
let cbfn = if let Some(c) = callback.callback.downcast_ref::<CallbackFn>() {
|
||||||
|
|
Loading…
Reference in a new issue