Rust ImGui + Glium ( OpenGL )
ImGui のGUI(ボタン)から、Gliumで描画したtriangleの回転角をコントロールできる
ようにしています。
(実行結果)
・ imgui ウィンドウ上の「+」ボタンと「ー」ボタンを押すと、回転角の値が増減します。
プログラム
### imgui-glium.rs
#[macro_use] extern crate glium; #[macro_use] extern crate imgui; use glium::glutin; use glium::glutin::{ElementState, Event, MouseButton, MouseScrollDelta, TouchPhase}; use glium::{DisplayBuild, Surface}; use imgui::{ImGui, ImGuiSetCond_FirstUseEver}; use imgui::glium_renderer::Renderer; use std::time::Instant; fn main() { let display = glutin::WindowBuilder::new() .with_dimensions(600, 600) .with_title(format!("ImGui Glium Test")) .build_glium().unwrap(); let mut imgui = ImGui::init(); let mut renderer = Renderer::init(&mut imgui, &display).unwrap(); let mut last_frame = Instant::now(); let mut mouse_pos = (0, 0); let mut mouse_pressed = (false, false, false); let mut mouse_wheel = 0.0; #[derive(Copy, Clone)] struct Vertex { position: [f32; 2], } implement_vertex!(Vertex, position); let vertex1 = Vertex { position: [-0.5, -0.5] }; let vertex2 = Vertex { position: [ 0.0, 0.5] }; let vertex3 = Vertex { position: [ 0.5, -0.5] }; let shape = vec![vertex1, vertex2, vertex3]; let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap(); let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList); let vertex_shader_src = r#" #version 140 in vec2 position; uniform mat4 MVP; void main() { gl_Position = MVP * vec4(position, 0.0, 1.0); } "#; let fragment_shader_src = r#" #version 140 out vec4 color; void main() { color = vec4(1.0, 0.0, 0.0, 1.0); } "#; let program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap(); let mut t: f32 = 0.0; loop { let mut target = display.draw(); target.clear_color(0.2, 0.2, 0.2, 1.0); let uniform = uniform! { MVP: [ [ t.cos(), t.sin(), 0.0, 0.0], [-t.sin(), t.cos(), 0.0, 0.0], [ 0.0, 0.0, 1.0, 0.0], [ 0.0, 0.0, 0.0, 1.0f32], ], }; target.draw(&vertex_buffer, &indices, &program, &uniform, &Default::default()).unwrap(); let now = Instant::now(); let delta = now - last_frame; let delta_s = delta.as_secs() as f32 + delta.subsec_nanos() as f32 / 1_000_000_000.0; last_frame = now; let scale = imgui.display_framebuffer_scale(); imgui.set_mouse_pos(mouse_pos.0 as f32 / scale.0, mouse_pos.1 as f32 / scale.1); imgui.set_mouse_down(&[mouse_pressed.0, mouse_pressed.1, mouse_pressed.2, false, false]); imgui.set_mouse_wheel(mouse_wheel / scale.1); mouse_wheel = 0.0; let window = display.get_window().unwrap(); let size_points = window.get_inner_size_points().unwrap(); let size_pixels = window.get_inner_size_pixels().unwrap(); let ui = imgui.frame(size_points, size_pixels, delta_s); // imgui ui ui.window(im_str!("Triangle")) .position((10.0, 10.0), ImGuiSetCond_FirstUseEver) .size((200.0, 100.0), ImGuiSetCond_FirstUseEver) .build(|| { ui.text(im_str!("rotation")); ui.separator(); if ui.small_button(im_str!("+")) { t += 0.02; } if ui.small_button(im_str!("-")) { t -= 0.02; } ui.text(im_str!("rotation angle: {:.2} rad", t)); }); renderer.render(&mut target, ui).unwrap(); target.finish().unwrap(); for event in display.poll_events() { match event { Event::Closed => return, Event::MouseMoved(x, y) => mouse_pos = (x, y), Event::MouseInput(state, MouseButton::Left) => mouse_pressed.0 = state == ElementState::Pressed, Event::MouseInput(state, MouseButton::Right) => mouse_pressed.1 = state == ElementState::Pressed, Event::MouseInput(state, MouseButton::Middle) => mouse_pressed.2 = state == ElementState::Pressed, Event::MouseWheel(MouseScrollDelta::LineDelta(_, y), TouchPhase::Moved) => mouse_wheel = y, Event::MouseWheel(MouseScrollDelta::PixelDelta(_, y), TouchPhase::Moved) => mouse_wheel = y, _ => () } } } }
### Cargo.toml
[package] name = "test1" version = "0.1.0" authors = ["xxxxx"] [dependencies] glium = "*" imgui = "*" image = "*"