mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-12 22:18:36 +00:00
Add example based on custom_textures.rs
This commit is contained in:
parent
87baa92b98
commit
d1df09dab4
@ -17,6 +17,7 @@ memoffset = "0.6.4"
|
||||
[dev-dependencies]
|
||||
glutin = "0.26.0"
|
||||
imgui-winit-support = { version = "0.7.1", path = "../imgui-winit-support" }
|
||||
image = "0.23"
|
||||
|
||||
[features]
|
||||
# Features here are used to opt-out of compiling code that depends on certain
|
||||
|
||||
284
imgui-glow-renderer/examples/04_custom_textures.rs
Normal file
284
imgui-glow-renderer/examples/04_custom_textures.rs
Normal file
@ -0,0 +1,284 @@
|
||||
//! Example showing the same functionality as
|
||||
//! `imgui-examples/examples/custom_textures.rs`
|
||||
|
||||
use std::{io::Cursor, time::Instant};
|
||||
|
||||
use glow::HasContext;
|
||||
use image::{jpeg::JpegDecoder, ImageDecoder};
|
||||
use imgui::{im_str, Condition};
|
||||
use imgui_glow_renderer::{RendererBuilder, StateBackupCsm};
|
||||
|
||||
mod utils;
|
||||
|
||||
const LENNA_JPEG: &[u8] = include_bytes!("../../resources/Lenna.jpg");
|
||||
|
||||
fn main() {
|
||||
let (event_loop, window) = utils::create_window("Custom textures", glutin::GlRequest::Latest);
|
||||
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
||||
let gl = utils::glow_context(&window);
|
||||
|
||||
let mut ig_renderer = RendererBuilder::new()
|
||||
.with_context_state_manager(StateBackupCsm::default())
|
||||
.with_texture_map(imgui::Textures::<glow::Texture>::default())
|
||||
.build_borrowing(&gl, &mut imgui_context)
|
||||
.expect("failed to create renderer");
|
||||
let textures_ui = TexturesUi::new(&gl, &mut ig_renderer.texture_map);
|
||||
|
||||
let mut last_frame = Instant::now();
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = glutin::event_loop::ControlFlow::Wait;
|
||||
match event {
|
||||
glutin::event::Event::NewEvents(_) => {
|
||||
let now = Instant::now();
|
||||
imgui_context
|
||||
.io_mut()
|
||||
.update_delta_time(now.duration_since(last_frame));
|
||||
last_frame = now;
|
||||
}
|
||||
glutin::event::Event::MainEventsCleared => {
|
||||
winit_platform
|
||||
.prepare_frame(imgui_context.io_mut(), window.window())
|
||||
.unwrap();
|
||||
|
||||
window.window().request_redraw();
|
||||
}
|
||||
glutin::event::Event::RedrawRequested(_) => {
|
||||
unsafe { gl.clear(glow::COLOR_BUFFER_BIT) };
|
||||
|
||||
let ui = imgui_context.frame();
|
||||
textures_ui.show(&ui);
|
||||
|
||||
winit_platform.prepare_render(&ui, window.window());
|
||||
let draw_data = ui.render();
|
||||
ig_renderer
|
||||
.render(&gl, &draw_data)
|
||||
.expect("error rendering imgui");
|
||||
|
||||
window.swap_buffers().unwrap();
|
||||
}
|
||||
glutin::event::Event::WindowEvent {
|
||||
event: glutin::event::WindowEvent::CloseRequested,
|
||||
..
|
||||
} => {
|
||||
*control_flow = glutin::event_loop::ControlFlow::Exit;
|
||||
}
|
||||
glutin::event::Event::LoopDestroyed => {
|
||||
ig_renderer.destroy(&gl);
|
||||
}
|
||||
event => {
|
||||
winit_platform.handle_event(imgui_context.io_mut(), window.window(), &event);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
struct TexturesUi {
|
||||
generated_texture: imgui::TextureId,
|
||||
lenna: Lenna,
|
||||
}
|
||||
|
||||
impl TexturesUi {
|
||||
fn new(gl: &glow::Context, textures: &mut imgui::Textures<glow::Texture>) -> Self {
|
||||
Self {
|
||||
generated_texture: Self::generate(gl, textures),
|
||||
lenna: Lenna::load(gl, textures),
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate dummy texture
|
||||
fn generate(
|
||||
gl: &glow::Context,
|
||||
textures: &mut imgui::Textures<glow::Texture>,
|
||||
) -> imgui::TextureId {
|
||||
const WIDTH: usize = 100;
|
||||
const HEIGHT: usize = 100;
|
||||
|
||||
let mut data = Vec::with_capacity(WIDTH * HEIGHT);
|
||||
for i in 0..WIDTH {
|
||||
for j in 0..HEIGHT {
|
||||
// Insert RGB values
|
||||
data.push(i as u8);
|
||||
data.push(j as u8);
|
||||
data.push((i + j) as u8);
|
||||
}
|
||||
}
|
||||
|
||||
let gl_texture = unsafe { gl.create_texture() }.expect("unable to create GL texture");
|
||||
|
||||
unsafe {
|
||||
gl.bind_texture(glow::TEXTURE_2D, Some(gl_texture));
|
||||
gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MIN_FILTER,
|
||||
glow::LINEAR as _,
|
||||
);
|
||||
gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MAG_FILTER,
|
||||
glow::LINEAR as _,
|
||||
);
|
||||
gl.tex_image_2d(
|
||||
glow::TEXTURE_2D,
|
||||
0,
|
||||
glow::RGB as _,
|
||||
WIDTH as _,
|
||||
HEIGHT as _,
|
||||
0,
|
||||
glow::RGB,
|
||||
glow::UNSIGNED_BYTE,
|
||||
Some(&data),
|
||||
)
|
||||
}
|
||||
|
||||
textures.insert(gl_texture)
|
||||
}
|
||||
|
||||
fn show(&self, ui: &imgui::Ui) {
|
||||
imgui::Window::new(im_str!("Hello textures"))
|
||||
.size([400.0, 400.0], Condition::FirstUseEver)
|
||||
.build(ui, || {
|
||||
ui.text(im_str!("Hello textures!"));
|
||||
ui.text("Some generated texture");
|
||||
imgui::Image::new(self.generated_texture, [100.0, 100.0]).build(ui);
|
||||
|
||||
ui.text("Say hello to Lenna.jpg");
|
||||
self.lenna.show(ui);
|
||||
|
||||
// Example of using custom textures on a button
|
||||
ui.text("The Lenna buttons");
|
||||
{
|
||||
ui.invisible_button(im_str!("Boring Button"), [100.0, 100.0]);
|
||||
// See also `imgui::Ui::style_color`
|
||||
let tint_none = [1.0, 1.0, 1.0, 1.0];
|
||||
let tint_green = [0.5, 1.0, 0.5, 1.0];
|
||||
let tint_red = [1.0, 0.5, 0.5, 1.0];
|
||||
|
||||
let tint = match (
|
||||
ui.is_item_hovered(),
|
||||
ui.is_mouse_down(imgui::MouseButton::Left),
|
||||
) {
|
||||
(false, _) => tint_none,
|
||||
(true, false) => tint_green,
|
||||
(true, true) => tint_red,
|
||||
};
|
||||
|
||||
let draw_list = ui.get_window_draw_list();
|
||||
draw_list
|
||||
.add_image(
|
||||
self.lenna.texture_id,
|
||||
ui.item_rect_min(),
|
||||
ui.item_rect_max(),
|
||||
)
|
||||
.col(tint)
|
||||
.build();
|
||||
}
|
||||
|
||||
{
|
||||
ui.same_line();
|
||||
|
||||
// Button using quad positioned image
|
||||
ui.invisible_button(im_str!("Exciting Button"), [100.0, 100.0]);
|
||||
|
||||
// Button bounds
|
||||
let min = ui.item_rect_min();
|
||||
let max = ui.item_rect_max();
|
||||
|
||||
// get corner coordinates
|
||||
let tl = [
|
||||
min[0],
|
||||
min[1] + (ui.frame_count() as f32 / 10.0).cos() * 10.0,
|
||||
];
|
||||
let tr = [
|
||||
max[0],
|
||||
min[1] + (ui.frame_count() as f32 / 10.0).sin() * 10.0,
|
||||
];
|
||||
let bl = [min[0], max[1]];
|
||||
let br = max;
|
||||
|
||||
let draw_list = ui.get_window_draw_list();
|
||||
draw_list
|
||||
.add_image_quad(self.lenna.texture_id, tl, tr, br, bl)
|
||||
.build();
|
||||
}
|
||||
|
||||
// Rounded image
|
||||
{
|
||||
ui.same_line();
|
||||
ui.invisible_button(im_str!("Smooth Button"), [100.0, 100.0]);
|
||||
|
||||
let draw_list = ui.get_window_draw_list();
|
||||
draw_list
|
||||
.add_image_rounded(
|
||||
self.lenna.texture_id,
|
||||
ui.item_rect_min(),
|
||||
ui.item_rect_max(),
|
||||
16.0,
|
||||
)
|
||||
// Tint brighter for visiblity of corners
|
||||
.col([2.0, 0.5, 0.5, 1.0])
|
||||
// Rounding on each corner can be changed separately
|
||||
.round_top_left(ui.frame_count() / 60 % 4 == 0)
|
||||
.round_top_right((ui.frame_count() + 1) / 60 % 4 == 1)
|
||||
.round_bot_right((ui.frame_count() + 3) / 60 % 4 == 2)
|
||||
.round_bot_left((ui.frame_count() + 2) / 60 % 4 == 3)
|
||||
.build();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
struct Lenna {
|
||||
texture_id: imgui::TextureId,
|
||||
size: [f32; 2],
|
||||
}
|
||||
|
||||
impl Lenna {
|
||||
fn load(gl: &glow::Context, textures: &mut imgui::Textures<glow::Texture>) -> Self {
|
||||
let decoder = JpegDecoder::new(Cursor::new(LENNA_JPEG)).expect("could not create decoder");
|
||||
let (width, height) = decoder.dimensions();
|
||||
|
||||
let lenna_image = {
|
||||
let mut bytes = vec![0; decoder.total_bytes() as usize];
|
||||
decoder
|
||||
.read_image(&mut bytes)
|
||||
.expect("unable to decode jpeg");
|
||||
bytes
|
||||
};
|
||||
|
||||
let gl_texture = unsafe { gl.create_texture() }.expect("unable to create GL texture");
|
||||
|
||||
unsafe {
|
||||
gl.bind_texture(glow::TEXTURE_2D, Some(gl_texture));
|
||||
gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MIN_FILTER,
|
||||
glow::LINEAR as _,
|
||||
);
|
||||
gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MAG_FILTER,
|
||||
glow::LINEAR as _,
|
||||
);
|
||||
gl.tex_image_2d(
|
||||
glow::TEXTURE_2D,
|
||||
0,
|
||||
glow::RGB as _,
|
||||
width as _,
|
||||
height as _,
|
||||
0,
|
||||
glow::RGB,
|
||||
glow::UNSIGNED_BYTE,
|
||||
Some(&lenna_image),
|
||||
)
|
||||
}
|
||||
|
||||
Self {
|
||||
texture_id: textures.insert(gl_texture),
|
||||
size: [width as _, height as _],
|
||||
}
|
||||
}
|
||||
|
||||
fn show(&self, ui: &imgui::Ui) {
|
||||
imgui::Image::new(self.texture_id, self.size).build(ui);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user