From 8520d0e24508b980a46c1444eb7bd93df064fa10 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Sat, 3 Oct 2015 22:27:38 -0600 Subject: [PATCH 1/5] Starting to work on keyboard input Update examples to use keyboard input --- examples/hello_world.rs | 3 +- examples/support/mod.rs | 76 ++++++++++++++++++++++++++++-------- examples/test_window.rs | 5 ++- examples/test_window_impl.rs | 3 +- src/lib.rs | 18 ++++++++- 5 files changed, 84 insertions(+), 21 deletions(-) diff --git a/examples/hello_world.rs b/examples/hello_world.rs index bb851a1..99c1c4e 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -16,7 +16,8 @@ fn main() { let mut support = Support::init(); loop { - let active = support.render(CLEAR_COLOR, hello_world); + support.render(CLEAR_COLOR, hello_world); + let active = support.update_events(); if !active { break } } } diff --git a/examples/support/mod.rs b/examples/support/mod.rs index fd64a5f..842cf07 100644 --- a/examples/support/mod.rs +++ b/examples/support/mod.rs @@ -1,8 +1,8 @@ use glium::{DisplayBuild, Surface}; use glium::backend::glutin_backend::GlutinFacade; use glium::glutin; -use glium::glutin::{ElementState, Event, MouseButton, VirtualKeyCode}; -use imgui::{ImGui, Ui}; +use glium::glutin::{ElementState, Event, MouseButton, MouseScrollDelta, VirtualKeyCode}; +use imgui::{ImGui, Ui, ImGuiKey}; use imgui::glium_renderer::Renderer; use time::SteadyTime; @@ -12,7 +12,8 @@ pub struct Support { renderer: Renderer, last_frame: SteadyTime, mouse_pos: (i32, i32), - mouse_pressed: (bool, bool, bool) + mouse_pressed: (bool, bool, bool), + mouse_wheel: f32, } impl Support { @@ -24,29 +25,53 @@ impl Support { let mut imgui = ImGui::init(); let renderer = Renderer::init(&mut imgui, &display).unwrap(); + // TODO: How can we get the virtual key -> scancode mapping from glium? + imgui.set_imgui_key(ImGuiKey::Tab, 15); + imgui.set_imgui_key(ImGuiKey::LeftArrow, 75); + imgui.set_imgui_key(ImGuiKey::RightArrow, 77); + imgui.set_imgui_key(ImGuiKey::UpArrow, 72); + imgui.set_imgui_key(ImGuiKey::DownArrow, 80); + imgui.set_imgui_key(ImGuiKey::PageUp, 73); + imgui.set_imgui_key(ImGuiKey::PageDown, 81); + imgui.set_imgui_key(ImGuiKey::Home, 71); + imgui.set_imgui_key(ImGuiKey::End, 79); + imgui.set_imgui_key(ImGuiKey::Delete, 83); + imgui.set_imgui_key(ImGuiKey::Backspace, 14); + imgui.set_imgui_key(ImGuiKey::Enter, 28); + imgui.set_imgui_key(ImGuiKey::Escape, 1); + imgui.set_imgui_key(ImGuiKey::A, 30); + imgui.set_imgui_key(ImGuiKey::C, 46); + imgui.set_imgui_key(ImGuiKey::V, 47); + imgui.set_imgui_key(ImGuiKey::X, 45); + imgui.set_imgui_key(ImGuiKey::Y, 21); + imgui.set_imgui_key(ImGuiKey::Z, 44); + Support { display: display, imgui: imgui, renderer: renderer, last_frame: SteadyTime::now(), mouse_pos: (0, 0), - mouse_pressed: (false, false, false) + mouse_pressed: (false, false, false), + mouse_wheel: 0.0 } } pub fn update_mouse(&mut self) { self.imgui.set_mouse_pos(self.mouse_pos.0 as f32, self.mouse_pos.1 as f32); self.imgui.set_mouse_down(&[self.mouse_pressed.0, self.mouse_pressed.1, self.mouse_pressed.2, false, false]); + self.imgui.set_mouse_wheel(self.mouse_wheel); } pub fn render<'ui, 'a: 'ui , F: FnMut(&Ui<'ui>)>( - &'a mut self, clear_color: (f32, f32, f32, f32), mut f: F) -> bool { + &'a mut self, clear_color: (f32, f32, f32, f32), mut f: F) { let now = SteadyTime::now(); let delta = now - self.last_frame; let delta_f = delta.num_nanoseconds().unwrap() as f32 / 1_000_000_000.0; self.last_frame = now; self.update_mouse(); + self.mouse_wheel = 0.0; let mut target = self.display.draw(); target.clear_color(clear_color.0, clear_color.1, @@ -58,20 +83,39 @@ impl Support { self.renderer.render(&mut target, ui).unwrap(); target.finish().unwrap(); + } + pub fn update_events(&mut self) -> bool { for event in self.display.poll_events() { match event { - Event::Closed | - Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Escape)) - => return false, - Event::MouseMoved(pos) => self.mouse_pos = pos, - Event::MouseInput(state, MouseButton::Left) => - self.mouse_pressed.0 = state == ElementState::Pressed, - Event::MouseInput(state, MouseButton::Right) => - self.mouse_pressed.1 = state == ElementState::Pressed, - Event::MouseInput(state, MouseButton::Middle) => - self.mouse_pressed.2 = state == ElementState::Pressed, - _ => () + Event::Closed => return false, + // TODO: Why does glutin not give us scancodes for left/right control? + Event::KeyboardInput(state, _, Some(code)) + if code == VirtualKeyCode::RControl || code == VirtualKeyCode::LControl + => self.imgui.set_key_ctrl(state == ElementState::Pressed), + Event::KeyboardInput(state, scancode, code) => { + println!("KeyCode {:?} scancode {} pressed? {}", code, scancode, + state == ElementState::Pressed); + self.imgui.set_key(scancode, state == ElementState::Pressed); + // TODO: This hack to do Ctrl should not be needed! + if scancode == 29 { + println!("Bad! Hacking in ctrl key press"); + self.imgui.set_key_ctrl(state == ElementState::Pressed); + } + }, + Event::MouseMoved(pos) => self.mouse_pos = pos, + Event::MouseInput(state, MouseButton::Left) => + self.mouse_pressed.0 = state == ElementState::Pressed, + Event::MouseInput(state, MouseButton::Right) => + self.mouse_pressed.1 = state == ElementState::Pressed, + Event::MouseInput(state, MouseButton::Middle) => + self.mouse_pressed.2 = state == ElementState::Pressed, + Event::MouseWheel(MouseScrollDelta::LineDelta(_, y)) => self.mouse_wheel = y, + Event::ReceivedCharacter(c) => { + println!("Got character {}", c); + self.imgui.add_input_character(c); + }, + _ => () } } true diff --git a/examples/test_window.rs b/examples/test_window.rs index d185dc0..b79df03 100644 --- a/examples/test_window.rs +++ b/examples/test_window.rs @@ -8,16 +8,17 @@ use self::support::Support; mod support; -const CLEAR_COLOR: (f32, f32, f32, f32) = (1.0, 1.0, 1.0, 1.0); +const CLEAR_COLOR: (f32, f32, f32, f32) = (0.2, 0.2, 0.2, 1.0); fn main() { let mut support = Support::init(); loop { let mut open = true; - let active = support.render(CLEAR_COLOR, |ui| { + support.render(CLEAR_COLOR, |ui| { ui.show_test_window(&mut open) }); + let active = support.update_events(); if !active || !open { break } } } diff --git a/examples/test_window_impl.rs b/examples/test_window_impl.rs index 6dbdaa0..61c5344 100644 --- a/examples/test_window_impl.rs +++ b/examples/test_window_impl.rs @@ -92,9 +92,10 @@ fn main() { let mut opened = true; loop { - let active = support.render(state.clear_color, |ui| { + support.render(state.clear_color, |ui| { show_test_window(ui, &mut state, &mut opened); }); + let active = support.update_events(); if !active || !opened { break } } } diff --git a/src/lib.rs b/src/lib.rs index cc678e9..f2ba293 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,8 @@ pub use imgui_sys::{ ImGuiWindowFlags_NoScrollbar, ImGuiWindowFlags_NoScrollWithMouse, ImGuiWindowFlags_NoCollapse, ImGuiWindowFlags_AlwaysAutoResize, ImGuiWindowFlags_ShowBorders, ImGuiWindowFlags_NoSavedSettings, ImGuiWindowFlags_NoInputs, ImGuiWindowFlags_MenuBar, - ImVec2, ImVec4 + ImVec2, ImVec4, + ImGuiKey }; pub use menus::{Menu, MenuItem}; pub use sliders::{SliderFloat, SliderInt}; @@ -221,6 +222,21 @@ impl ImGui { let io = self.io_mut(); io.key_alt = value; } + pub fn set_key(&mut self, key: u8, pressed: bool) { + let io = self.io_mut(); + io.keys_down[key as usize] = pressed; + } + pub fn set_imgui_key(&mut self, key: ImGuiKey, mapping: u8) { + let io = self.io_mut(); + io.key_map[key as usize] = mapping as i32; + } + pub fn add_input_character(&mut self, character: char) { + unsafe { + // TODO: This is not good. We should use char::encode_ut8 when it stabilizes + // (or whatever stabilizes to fill its place) and call ImGuiIO_AddInputCharactersUTF8 + imgui_sys::ImGuiIO_AddInputCharacter(character as u16); + } + } pub fn get_time(&self) -> f32 { unsafe { imgui_sys::igGetTime() } } pub fn get_frame_count(&self) -> i32 { unsafe { imgui_sys::igGetFrameCount() } } pub fn get_frame_rate(&self) -> f32 { self.io().framerate } From 238f5fead1a1b45ffaa8b1ca04c27eec065a7f21 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Wed, 14 Oct 2015 10:15:12 -0600 Subject: [PATCH 2/5] Cleaner method for sending keys to ImGui across platforms Use Virtual Key codes however glutin is missing virtual key codes for Ctrl/Shift and such on my Win10 machines --- Cargo.toml | 4 +- examples/support/mod.rs | 81 ++++++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1c2fa36..6b0ea00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ default = ["glium"] libc = "0.1" [dependencies.glium] -version = "0.9" +version = "0.9.3" default-features = false optional = true @@ -30,6 +30,6 @@ gcc = "0.3" time = "0.1" [dev-dependencies.glium] -version = "0.9" +version = "0.9.3" features = ["glutin"] default-features = false diff --git a/examples/support/mod.rs b/examples/support/mod.rs index 842cf07..24cec36 100644 --- a/examples/support/mod.rs +++ b/examples/support/mod.rs @@ -25,26 +25,25 @@ impl Support { let mut imgui = ImGui::init(); let renderer = Renderer::init(&mut imgui, &display).unwrap(); - // TODO: How can we get the virtual key -> scancode mapping from glium? - imgui.set_imgui_key(ImGuiKey::Tab, 15); - imgui.set_imgui_key(ImGuiKey::LeftArrow, 75); - imgui.set_imgui_key(ImGuiKey::RightArrow, 77); - imgui.set_imgui_key(ImGuiKey::UpArrow, 72); - imgui.set_imgui_key(ImGuiKey::DownArrow, 80); - imgui.set_imgui_key(ImGuiKey::PageUp, 73); - imgui.set_imgui_key(ImGuiKey::PageDown, 81); - imgui.set_imgui_key(ImGuiKey::Home, 71); - imgui.set_imgui_key(ImGuiKey::End, 79); - imgui.set_imgui_key(ImGuiKey::Delete, 83); - imgui.set_imgui_key(ImGuiKey::Backspace, 14); - imgui.set_imgui_key(ImGuiKey::Enter, 28); - imgui.set_imgui_key(ImGuiKey::Escape, 1); - imgui.set_imgui_key(ImGuiKey::A, 30); - imgui.set_imgui_key(ImGuiKey::C, 46); - imgui.set_imgui_key(ImGuiKey::V, 47); - imgui.set_imgui_key(ImGuiKey::X, 45); - imgui.set_imgui_key(ImGuiKey::Y, 21); - imgui.set_imgui_key(ImGuiKey::Z, 44); + imgui.set_imgui_key(ImGuiKey::Tab, 0); + imgui.set_imgui_key(ImGuiKey::LeftArrow, 1); + imgui.set_imgui_key(ImGuiKey::RightArrow, 2); + imgui.set_imgui_key(ImGuiKey::UpArrow, 3); + imgui.set_imgui_key(ImGuiKey::DownArrow, 4); + imgui.set_imgui_key(ImGuiKey::PageUp, 5); + imgui.set_imgui_key(ImGuiKey::PageDown, 6); + imgui.set_imgui_key(ImGuiKey::Home, 7); + imgui.set_imgui_key(ImGuiKey::End, 8); + imgui.set_imgui_key(ImGuiKey::Delete, 9); + imgui.set_imgui_key(ImGuiKey::Backspace, 10); + imgui.set_imgui_key(ImGuiKey::Enter, 11); + imgui.set_imgui_key(ImGuiKey::Escape, 12); + imgui.set_imgui_key(ImGuiKey::A, 13); + imgui.set_imgui_key(ImGuiKey::C, 14); + imgui.set_imgui_key(ImGuiKey::V, 15); + imgui.set_imgui_key(ImGuiKey::X, 16); + imgui.set_imgui_key(ImGuiKey::Y, 17); + imgui.set_imgui_key(ImGuiKey::Z, 18); Support { display: display, @@ -89,18 +88,39 @@ impl Support { for event in self.display.poll_events() { match event { Event::Closed => return false, - // TODO: Why does glutin not give us scancodes for left/right control? - Event::KeyboardInput(state, _, Some(code)) - if code == VirtualKeyCode::RControl || code == VirtualKeyCode::LControl - => self.imgui.set_key_ctrl(state == ElementState::Pressed), Event::KeyboardInput(state, scancode, code) => { println!("KeyCode {:?} scancode {} pressed? {}", code, scancode, state == ElementState::Pressed); - self.imgui.set_key(scancode, state == ElementState::Pressed); - // TODO: This hack to do Ctrl should not be needed! - if scancode == 29 { - println!("Bad! Hacking in ctrl key press"); - self.imgui.set_key_ctrl(state == ElementState::Pressed); + let pressed = state == ElementState::Pressed; + // TODO: glutin is missing some virtual key codes on windows 10 for Ctrl and + // Shift + match code { + Some(VirtualKeyCode::Tab) => self.imgui.set_key(0, pressed), + Some(VirtualKeyCode::Left) => self.imgui.set_key(1, pressed), + Some(VirtualKeyCode::Right) => self.imgui.set_key(2, pressed), + Some(VirtualKeyCode::Up) => self.imgui.set_key(3, pressed), + Some(VirtualKeyCode::Down) => self.imgui.set_key(4, pressed), + Some(VirtualKeyCode::PageUp) => self.imgui.set_key(5, pressed), + Some(VirtualKeyCode::PageDown) => self.imgui.set_key(6, pressed), + Some(VirtualKeyCode::Home) => self.imgui.set_key(7, pressed), + Some(VirtualKeyCode::End) => self.imgui.set_key(8, pressed), + Some(VirtualKeyCode::Delete) => self.imgui.set_key(9, pressed), + Some(VirtualKeyCode::Back) => self.imgui.set_key(10, pressed), + Some(VirtualKeyCode::Return) => self.imgui.set_key(11, pressed), + Some(VirtualKeyCode::Escape) => self.imgui.set_key(12, pressed), + Some(VirtualKeyCode::A) => self.imgui.set_key(13, pressed), + Some(VirtualKeyCode::C) => self.imgui.set_key(14, pressed), + Some(VirtualKeyCode::V) => self.imgui.set_key(15, pressed), + Some(VirtualKeyCode::X) => self.imgui.set_key(16, pressed), + Some(VirtualKeyCode::Y) => self.imgui.set_key(17, pressed), + Some(VirtualKeyCode::Z) => self.imgui.set_key(18, pressed), + Some(VirtualKeyCode::LControl) | Some(VirtualKeyCode::RControl) => + self.imgui.set_key_ctrl(pressed), + Some(VirtualKeyCode::LShift) | Some(VirtualKeyCode::RShift) => + self.imgui.set_key_shift(pressed), + Some(VirtualKeyCode::LAlt) | Some(VirtualKeyCode::RAlt) => + self.imgui.set_key_alt(pressed), + _ => {}, } }, Event::MouseMoved(pos) => self.mouse_pos = pos, @@ -110,7 +130,8 @@ impl Support { self.mouse_pressed.1 = state == ElementState::Pressed, Event::MouseInput(state, MouseButton::Middle) => self.mouse_pressed.2 = state == ElementState::Pressed, - Event::MouseWheel(MouseScrollDelta::LineDelta(_, y)) => self.mouse_wheel = y, + Event::MouseWheel(MouseScrollDelta::LineDelta(_, y)) => self.mouse_wheel = y * 5.0, + Event::MouseWheel(MouseScrollDelta::PixelDelta(_, y)) => self.mouse_wheel = y, Event::ReceivedCharacter(c) => { println!("Got character {}", c); self.imgui.add_input_character(c); From 6eb3ffefdf2e53b4437c8ac97bc1aa46470b0ea7 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Wed, 14 Oct 2015 11:19:26 -0600 Subject: [PATCH 3/5] Encode string of UTF8 chars using encode_default API Using encode_utf8 will be better when it stabilizes since we won't need the String intermediate and can go directly to a Vec. Update to glium 0.10 to resolve ctrl/shift/etc virtual keycodes on Win10 --- Cargo.toml | 4 ++-- imgui-sys/Cargo.toml | 2 +- src/glium_renderer.rs | 8 ++++++-- src/lib.rs | 15 +++++++++++---- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6b0ea00..106669d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ default = ["glium"] libc = "0.1" [dependencies.glium] -version = "0.9.3" +version = "0.10" default-features = false optional = true @@ -30,6 +30,6 @@ gcc = "0.3" time = "0.1" [dev-dependencies.glium] -version = "0.9.3" +version = "0.10" features = ["glutin"] default-features = false diff --git a/imgui-sys/Cargo.toml b/imgui-sys/Cargo.toml index ac035d5..97e0c4a 100644 --- a/imgui-sys/Cargo.toml +++ b/imgui-sys/Cargo.toml @@ -16,7 +16,7 @@ bitflags = "0.3" libc = "0.1" [dependencies.glium] -version = "0.9" +version = "0.10" default-features = false optional = true diff --git a/src/glium_renderer.rs b/src/glium_renderer.rs index daab72f..92b2d56 100644 --- a/src/glium_renderer.rs +++ b/src/glium_renderer.rs @@ -131,7 +131,7 @@ pub struct DeviceObjects { texture: Texture2d } -fn compile_default_program(ctx: &F) -> Result { +fn compile_default_program(ctx: &F) -> Result { program!( ctx, 140 => { @@ -152,7 +152,11 @@ impl DeviceObjects { let vertex_buffer = try!(VertexBuffer::empty_dynamic(ctx, 0)); let index_buffer = try!(IndexBuffer::empty_dynamic(ctx, PrimitiveType::TrianglesList, 0)); - let program = try!(compile_default_program(ctx)); + let program = match compile_default_program(ctx) { + Ok(p) => p, + Err(program::ProgramChooserCreationError::NoVersion) => panic!("No version for GLSL program"), + Err(e) => panic!("Error compiling shaders {:?}", e), + }; let texture = try!(im_gui.prepare_texture(|handle| { let data = RawImage2d { data: Cow::Borrowed(handle.pixels), diff --git a/src/lib.rs b/src/lib.rs index f2ba293..8539235 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -231,10 +231,17 @@ impl ImGui { io.key_map[key as usize] = mapping as i32; } pub fn add_input_character(&mut self, character: char) { - unsafe { - // TODO: This is not good. We should use char::encode_ut8 when it stabilizes - // (or whatever stabilizes to fill its place) and call ImGuiIO_AddInputCharactersUTF8 - imgui_sys::ImGuiIO_AddInputCharacter(character as u16); + if !character.is_control() { + // TODO: This is slightly better. We should use char::encode_utf8 when it stabilizes + // to allow us to skip the string intermediate since we can then go directly + // to bytes + let utf8_str: String = character.escape_default().collect(); + let mut bytes = utf8_str.into_bytes(); + // into_bytes does not produce a c-string, we must append the null terminator + bytes.push(0); + unsafe { + imgui_sys::ImGuiIO_AddInputCharactersUTF8(bytes.as_ptr() as *const i8); + } } } pub fn get_time(&self) -> f32 { unsafe { imgui_sys::igGetTime() } } From 064235f8c3fab517e7b3620268897d72a5eb4b59 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Wed, 14 Oct 2015 14:26:36 -0600 Subject: [PATCH 4/5] Clean up debug logging in example event handling --- examples/support/mod.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/examples/support/mod.rs b/examples/support/mod.rs index 24cec36..a7a6e58 100644 --- a/examples/support/mod.rs +++ b/examples/support/mod.rs @@ -88,12 +88,8 @@ impl Support { for event in self.display.poll_events() { match event { Event::Closed => return false, - Event::KeyboardInput(state, scancode, code) => { - println!("KeyCode {:?} scancode {} pressed? {}", code, scancode, - state == ElementState::Pressed); + Event::KeyboardInput(state, _, code) => { let pressed = state == ElementState::Pressed; - // TODO: glutin is missing some virtual key codes on windows 10 for Ctrl and - // Shift match code { Some(VirtualKeyCode::Tab) => self.imgui.set_key(0, pressed), Some(VirtualKeyCode::Left) => self.imgui.set_key(1, pressed), @@ -130,12 +126,9 @@ impl Support { self.mouse_pressed.1 = state == ElementState::Pressed, Event::MouseInput(state, MouseButton::Middle) => self.mouse_pressed.2 = state == ElementState::Pressed, - Event::MouseWheel(MouseScrollDelta::LineDelta(_, y)) => self.mouse_wheel = y * 5.0, + Event::MouseWheel(MouseScrollDelta::LineDelta(_, y)) => self.mouse_wheel = y, Event::MouseWheel(MouseScrollDelta::PixelDelta(_, y)) => self.mouse_wheel = y, - Event::ReceivedCharacter(c) => { - println!("Got character {}", c); - self.imgui.add_input_character(c); - }, + Event::ReceivedCharacter(c) => self.imgui.add_input_character(c), _ => () } } From 2fa549bcc961e1194d4e90ca50c1f9481960ff19 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Sat, 17 Oct 2015 14:14:27 -0600 Subject: [PATCH 5/5] Wrap ProgramChooserCreationError properly --- src/glium_renderer.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/glium_renderer.rs b/src/glium_renderer.rs index 92b2d56..2c932f7 100644 --- a/src/glium_renderer.rs +++ b/src/glium_renderer.rs @@ -17,7 +17,7 @@ pub type RendererResult = Result; pub enum RendererError { Vertex(vertex::BufferCreationError), Index(index::BufferCreationError), - Program(program::ProgramCreationError), + Program(program::ProgramChooserCreationError), Texture(texture::TextureCreationError), Draw(DrawError) } @@ -47,8 +47,8 @@ impl From for RendererError { } } -impl From for RendererError { - fn from(e: program::ProgramCreationError) -> RendererError { +impl From for RendererError { + fn from(e: program::ProgramChooserCreationError) -> RendererError { RendererError::Program(e) } } @@ -152,11 +152,7 @@ impl DeviceObjects { let vertex_buffer = try!(VertexBuffer::empty_dynamic(ctx, 0)); let index_buffer = try!(IndexBuffer::empty_dynamic(ctx, PrimitiveType::TrianglesList, 0)); - let program = match compile_default_program(ctx) { - Ok(p) => p, - Err(program::ProgramChooserCreationError::NoVersion) => panic!("No version for GLSL program"), - Err(e) => panic!("Error compiling shaders {:?}", e), - }; + let program = try!(compile_default_program(ctx)); let texture = try!(im_gui.prepare_texture(|handle| { let data = RawImage2d { data: Cow::Borrowed(handle.pixels),