mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 13:20:05 -04:00
Add Shape::Callback to do custom rendering inside of an egui UI (#1351)
* Add Shape::Callback to do custom rendering inside of an egui UI * Use Rc<glow::Context> everywhere * Remove trait WebPainter * Add glow::Context to epi::App::setup
This commit is contained in:
@@ -6,6 +6,7 @@ use glow::HasContext;
|
||||
/// Uses a framebuffer to render everything in linear color space and convert it back to `sRGB`
|
||||
/// in a separate "post processing" step
|
||||
pub(crate) struct PostProcess {
|
||||
gl: std::rc::Rc<glow::Context>,
|
||||
pos_buffer: glow::Buffer,
|
||||
index_buffer: glow::Buffer,
|
||||
vertex_array: crate::misc_util::VAO,
|
||||
@@ -18,7 +19,7 @@ pub(crate) struct PostProcess {
|
||||
|
||||
impl PostProcess {
|
||||
pub(crate) unsafe fn new(
|
||||
gl: &glow::Context,
|
||||
gl: std::rc::Rc<glow::Context>,
|
||||
shader_prefix: &str,
|
||||
need_to_emulate_vao: bool,
|
||||
is_webgl_1: bool,
|
||||
@@ -76,7 +77,7 @@ impl PostProcess {
|
||||
glow::UNSIGNED_BYTE,
|
||||
None,
|
||||
);
|
||||
check_for_gl_error(gl, "post process texture initialization");
|
||||
check_for_gl_error(&gl, "post process texture initialization");
|
||||
|
||||
gl.framebuffer_texture_2d(
|
||||
glow::FRAMEBUFFER,
|
||||
@@ -89,7 +90,7 @@ impl PostProcess {
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
|
||||
let vert_shader = compile_shader(
|
||||
gl,
|
||||
&gl,
|
||||
glow::VERTEX_SHADER,
|
||||
&format!(
|
||||
"{}\n{}",
|
||||
@@ -98,7 +99,7 @@ impl PostProcess {
|
||||
),
|
||||
)?;
|
||||
let frag_shader = compile_shader(
|
||||
gl,
|
||||
&gl,
|
||||
glow::FRAGMENT_SHADER,
|
||||
&format!(
|
||||
"{}\n{}",
|
||||
@@ -106,7 +107,7 @@ impl PostProcess {
|
||||
include_str!("shader/post_fragment_100es.glsl")
|
||||
),
|
||||
)?;
|
||||
let program = link_program(gl, [vert_shader, frag_shader].iter())?;
|
||||
let program = link_program(&gl, [vert_shader, frag_shader].iter())?;
|
||||
|
||||
let positions = vec![0.0f32, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0];
|
||||
|
||||
@@ -126,10 +127,10 @@ impl PostProcess {
|
||||
let mut vertex_array = if need_to_emulate_vao {
|
||||
crate::misc_util::VAO::emulated()
|
||||
} else {
|
||||
crate::misc_util::VAO::native(gl)
|
||||
crate::misc_util::VAO::native(&gl)
|
||||
};
|
||||
vertex_array.bind_vertex_array(gl);
|
||||
vertex_array.bind_buffer(gl, &pos_buffer);
|
||||
vertex_array.bind_vertex_array(&gl);
|
||||
vertex_array.bind_buffer(&gl, &pos_buffer);
|
||||
let buffer_info_a_pos = BufferInfo {
|
||||
location: a_pos_loc,
|
||||
vector_size: 2,
|
||||
@@ -138,16 +139,17 @@ impl PostProcess {
|
||||
stride: 0,
|
||||
offset: 0,
|
||||
};
|
||||
vertex_array.add_new_attribute(gl, buffer_info_a_pos);
|
||||
vertex_array.add_new_attribute(&gl, buffer_info_a_pos);
|
||||
|
||||
let index_buffer = gl.create_buffer()?;
|
||||
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(index_buffer));
|
||||
gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, &indices, glow::STATIC_DRAW);
|
||||
|
||||
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
|
||||
check_for_gl_error(gl, "post process initialization");
|
||||
check_for_gl_error(&gl, "post process initialization");
|
||||
|
||||
Ok(PostProcess {
|
||||
gl,
|
||||
pos_buffer,
|
||||
index_buffer,
|
||||
vertex_array,
|
||||
@@ -159,17 +161,17 @@ impl PostProcess {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn begin(&mut self, gl: &glow::Context, width: i32, height: i32) {
|
||||
pub(crate) unsafe fn begin(&mut self, width: i32, height: i32) {
|
||||
if (width, height) != self.texture_size {
|
||||
gl.bind_texture(glow::TEXTURE_2D, Some(self.texture));
|
||||
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
|
||||
self.gl.bind_texture(glow::TEXTURE_2D, Some(self.texture));
|
||||
self.gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
|
||||
|
||||
let (internal_format, format) = if self.is_webgl_1 {
|
||||
(glow::SRGB_ALPHA, glow::SRGB_ALPHA)
|
||||
} else {
|
||||
(glow::SRGB8_ALPHA8, glow::RGBA)
|
||||
};
|
||||
gl.tex_image_2d(
|
||||
self.gl.tex_image_2d(
|
||||
glow::TEXTURE_2D,
|
||||
0,
|
||||
internal_format as i32,
|
||||
@@ -181,40 +183,49 @@ impl PostProcess {
|
||||
None,
|
||||
);
|
||||
|
||||
gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
self.gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
self.texture_size = (width, height);
|
||||
}
|
||||
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, Some(self.fbo));
|
||||
gl.clear_color(0.0, 0.0, 0.0, 0.0);
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
self.gl.bind_framebuffer(glow::FRAMEBUFFER, Some(self.fbo));
|
||||
self.gl.clear_color(0.0, 0.0, 0.0, 0.0);
|
||||
self.gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn end(&self, gl: &glow::Context) {
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
gl.disable(glow::SCISSOR_TEST);
|
||||
|
||||
gl.use_program(Some(self.program));
|
||||
|
||||
gl.active_texture(glow::TEXTURE0);
|
||||
gl.bind_texture(glow::TEXTURE_2D, Some(self.texture));
|
||||
let u_sampler_loc = gl.get_uniform_location(self.program, "u_sampler").unwrap();
|
||||
gl.uniform_1_i32(Some(&u_sampler_loc), 0);
|
||||
self.vertex_array.bind_vertex_array(gl);
|
||||
|
||||
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.index_buffer));
|
||||
gl.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_BYTE, 0);
|
||||
self.vertex_array.unbind_vertex_array(gl);
|
||||
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
|
||||
gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
gl.use_program(None);
|
||||
pub(crate) unsafe fn bind(&self) {
|
||||
self.gl.bind_framebuffer(glow::FRAMEBUFFER, Some(self.fbo));
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn destroy(&self, gl: &glow::Context) {
|
||||
gl.delete_buffer(self.pos_buffer);
|
||||
gl.delete_buffer(self.index_buffer);
|
||||
gl.delete_program(self.program);
|
||||
gl.delete_framebuffer(self.fbo);
|
||||
gl.delete_texture(self.texture);
|
||||
pub(crate) unsafe fn end(&self) {
|
||||
self.gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
self.gl.disable(glow::SCISSOR_TEST);
|
||||
|
||||
self.gl.use_program(Some(self.program));
|
||||
|
||||
self.gl.active_texture(glow::TEXTURE0);
|
||||
self.gl.bind_texture(glow::TEXTURE_2D, Some(self.texture));
|
||||
let u_sampler_loc = self
|
||||
.gl
|
||||
.get_uniform_location(self.program, "u_sampler")
|
||||
.unwrap();
|
||||
self.gl.uniform_1_i32(Some(&u_sampler_loc), 0);
|
||||
self.vertex_array.bind_vertex_array(&self.gl);
|
||||
|
||||
self.gl
|
||||
.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.index_buffer));
|
||||
self.gl
|
||||
.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_BYTE, 0);
|
||||
self.vertex_array.unbind_vertex_array(&self.gl);
|
||||
self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
|
||||
self.gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
self.gl.use_program(None);
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn destroy(&self) {
|
||||
self.gl.delete_buffer(self.pos_buffer);
|
||||
self.gl.delete_buffer(self.index_buffer);
|
||||
self.gl.delete_program(self.program);
|
||||
self.gl.delete_framebuffer(self.fbo);
|
||||
self.gl.delete_texture(self.texture);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user