-
-struct XmCallback {
- xm: XMContext,
-}
-
-impl AudioCallback for XmCallback {
- type Channel = f32;
-
- fn callback(&mut self, out: &mut [f32]) {
- self.xm.generate_samples(out);
- }
-}
-
-struct SoundPlayer {
- _device: AudioDevice<XmCallback>,
-}
-
-fn play_xm(raw_xm: &[u8]) -> SoundPlayer {
- let sdl_context = sdl2::init().unwrap();
- let sdl_audio = sdl_context.audio().unwrap();
-
- let sample_rate = 48000u32;
- let desired_spec = AudioSpecDesired {
- freq: Some(sample_rate as i32),
- channels: Some(2u8),
- samples: None,
- };
- let device = sdl_audio.open_playback(None, &desired_spec, |actual_spec| {
- let xm = XMContext::new(&raw_xm, actual_spec.freq as u32).unwrap();
-
- XmCallback {
- xm: xm,
- }
- }).unwrap();
-
- device.resume();
-
- SoundPlayer {
- _device: device,
- }
-}
-
-fn main() {
- let mut xm = Vec::new();
- File::open("flora.xm").unwrap().read_to_end(&mut xm).unwrap();
- let _sound_player = play_xm(&xm);
-
- let display = glium::glutin::WindowBuilder::new()
- //.with_dimensions(1024, 768)
- .with_fullscreen(glutin::get_primary_monitor())
- .with_depth_buffer(24)
- .with_vsync()
- .with_title(format!("MandelWow"))
- .build_glium()
- .unwrap();
-
- let program = mandelwow_program(&display);
- let bounding_box_program = solid_fill_program(&display);
-
- let mut camera = support::camera::CameraState::new();
- let mut t: f32 = 0.0;
- let mut pause = false;
- let mut bounding_box_enabled = true;
- let mut fullscreen = true;
-
- support::start_loop(|| {
- camera.update();
-
- if !pause {
- // Increment time
- t += 0.01;
- }
-
- // These are the bounds of the 3D Mandelwow section which we render in 3-space.
- let bounds = Cube {
- xmin: -2.0,
- xmax: 0.7,
- ymin: -1.0,
- ymax: 1.0,
- zmin: -1.2,
- zmax: 1.2,
- };
-
- // Vary the wow factor to slice the Mandelwow along its 4th dimension.
- let wmin = -0.8;
- let wmax = 0.8;
- let wsize = wmax - wmin;
- let wow = (((t * 0.7).sin() + 1.0) / 2.0) * wsize + wmin;
-
- //println!("t={} w={:?} camera={:?}", t, w, camera.get_pos());
-
- let mut frame = display.draw();
- frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
-
- let z_trans = -2.0; // Send the model back a little bit so it fits the screen.
- let model = [
- [ 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, z_trans, 1.0f32]
- ];
-
- // Draw the bounding box before the fractal, when the Z-buffer is still clear, so the lines
- // behind the semi-translucent areas will be drawn.
- if bounding_box_enabled {
- let uniforms = uniform! {
- model: model,
- view: camera.get_view(),
- perspective: camera.get_perspective(),
- };
- bounding_box(&display, &mut frame, &bounding_box_program, &uniforms, &bounds);
- }
-
- mandelwow(&display, &mut frame, &program, model, &camera, &bounds, wow);
- frame.finish().unwrap();
-
- for ev in display.poll_events() {
- match ev {
- glium::glutin::Event::Closed |
- KeyboardInput(Pressed, _, Some(VirtualKeyCode::Escape)) |
- KeyboardInput(Pressed, _, Some(VirtualKeyCode::Q)) => {
- return support::Action::Stop
- },
- KeyboardInput(Pressed, _, Some(VirtualKeyCode::B)) => {
- bounding_box_enabled ^= true;
- },
- KeyboardInput(Pressed, _, Some(VirtualKeyCode::F)) => {
- fullscreen ^= true;
- if fullscreen {
- glutin::WindowBuilder::new()
- .with_fullscreen(glutin::get_primary_monitor())
- .rebuild_glium(&display).unwrap();
- } else {
- glutin::WindowBuilder::new()
- .rebuild_glium(&display).unwrap();
- }
- },
- KeyboardInput(Pressed, _, Some(VirtualKeyCode::P)) => {
- pause ^= true;
- },
- KeyboardInput(Pressed, _, Some(VirtualKeyCode::PageUp)) => {
- t += 0.01;
- },
- KeyboardInput(Pressed, _, Some(VirtualKeyCode::PageDown)) => {
- t -= 0.01;
- },
- ev => camera.process_input(&ev),
- }
- }
-
- support::Action::Continue
- });
-
-}