extern crate glium;
extern crate glutin;
-
-use glium::DisplayBuild;
-use glium::Surface;
-use glium::index::PrimitiveType;
-use glium::index::IndexBuffer;
+extern crate libxm;
+extern crate sdl2;
+
+use glium::{DisplayBuild, Surface};
+use glium::index::{IndexBuffer, PrimitiveType};
+use glutin::ElementState::Pressed;
+use glutin::Event::KeyboardInput;
+use glutin::VirtualKeyCode;
+use libxm::XMContext;
+use sdl2::audio::{AudioCallback, AudioDevice, AudioSpecDesired};
+use std::fs::File;
+use std::io::Read;
mod support;
];
let vb = glium::VertexBuffer::new(display, &cube).unwrap();
- let params = Default::default();
+ let params = glium::DrawParameters {
+ depth: glium::Depth {
+ test: glium::draw_parameters::DepthTest::IfLess,
+ write: true,
+ .. Default::default()
+ },
+ blend: glium::Blend::alpha_blending(),
+ .. Default::default()
+ };
let front_indices = IndexBuffer::new(display, PrimitiveType::LineLoop,
&[0, 1, 2, 3u16]).unwrap();
}
}
+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_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();
[ 0.0, 0.0, z_trans, 1.0f32]
];
- let program = mandelwow_program(&display);
- let bounding_box_program = solid_fill_program(&display);
+ // 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);
-
- let uniforms = uniform! {
- model: model,
- view: camera.get_view(),
- perspective: camera.get_perspective(),
- };
- bounding_box(&display, &mut frame, &bounding_box_program, &uniforms, &bounds);
+ frame.finish().unwrap();
for ev in display.poll_events() {
match ev {
- glium::glutin::Event::Closed => {
- frame.finish().unwrap();
+ glium::glutin::Event::Closed |
+ KeyboardInput(Pressed, _, Some(VirtualKeyCode::Escape)) |
+ KeyboardInput(Pressed, _, Some(VirtualKeyCode::Q)) => {
return support::Action::Stop
},
- glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::PageUp)) => {
- t += 0.01;
+ KeyboardInput(Pressed, _, Some(VirtualKeyCode::B)) => {
+ bounding_box_enabled ^= true;
},
- glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::PageDown)) => {
- t -= 0.01;
+ 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();
+ }
},
- glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::P)) => {
+ 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),
}
}
- frame.finish().unwrap();
support::Action::Continue
});
+
}