4 #[macro_use(uniform,program,implement_vertex)]
11 //use cgmath::prelude::*;
12 use cgmath::{Euler, Matrix4, Rad, Vector3};
14 use glium::{DisplayBuild, Surface};
15 use glutin::ElementState::Pressed;
16 use glutin::Event::KeyboardInput;
17 use glutin::VirtualKeyCode;
25 fn screenshot(display : &glium::Display) {
26 let image: glium::texture::RawImage2d<u8> = display.read_front_buffer();
27 let image = image::ImageBuffer::from_raw(image.width, image.height, image.data.into_owned()).unwrap();
28 let image = image::DynamicImage::ImageRgba8(image).flipv();
29 let mut output = std::fs::File::create(&std::path::Path::new("screenshot.png")).unwrap();
30 image.save(&mut output, image::ImageFormat::PNG).unwrap();
34 let _soundplayer = sound::start();
36 let display = glutin::WindowBuilder::new()
37 //.with_dimensions(1024, 768)
38 .with_fullscreen(glutin::get_primary_monitor())
39 .with_depth_buffer(24)
41 .with_title(format!("MandelWow"))
45 let mandelwow_program = mandelwow::program(&display);
46 let bounding_box_program = bounding_box::solid_fill_program(&display);
48 let mut camera = support::camera::CameraState::new();
50 let mut pause = false;
51 let mut bounding_box_enabled = true;
52 let mut fullscreen = true;
54 // These are the bounds of the 3D Mandelwow section which we render in 3-space.
64 support::start_loop(|| {
72 // Vary the wow factor to slice the Mandelwow along its 4th dimension.
75 let wsize = wmax - wmin;
76 let wow = (((t * 0.7).sin() + 1.0) / 2.0) * wsize + wmin;
78 //println!("t={} w={:?} camera={:?}", t, w, camera.get_pos());
80 let mut frame = display.draw();
81 frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
83 let rotation = cgmath::Matrix4::from(
84 Euler { x: Rad(t.sin() / 3.), y: Rad(t.sin() / 2.), z: Rad(t)});
85 let z_trans = -2.0; // Send the model back a little bit so it fits the screen.
87 Matrix4::from_translation(Vector3::unit_z() * z_trans) * rotation;
88 let model = cgmath::conv::array4x4(model2);
90 // Draw the bounding box before the fractal, when the Z-buffer is still clear,
91 // so the lines behind the semi-translucent areas will be drawn.
92 if bounding_box_enabled {
93 let uniforms = uniform! {
95 view: camera.get_view(),
96 perspective: camera.get_perspective(),
98 bounding_box::draw(&display, &mut frame, &bounding_box_program, &uniforms, &bounds);
101 mandelwow::draw(&display, &mut frame, &mandelwow_program, model, &camera, &bounds, wow);
102 frame.finish().unwrap();
104 for ev in display.poll_events() {
106 glutin::Event::Closed |
107 KeyboardInput(Pressed, _, Some(VirtualKeyCode::Escape)) |
108 KeyboardInput(Pressed, _, Some(VirtualKeyCode::Q)) => {
109 return support::Action::Stop
111 KeyboardInput(Pressed, _, Some(VirtualKeyCode::B)) => {
112 bounding_box_enabled ^= true;
114 KeyboardInput(Pressed, _, Some(VirtualKeyCode::P)) => {
117 KeyboardInput(Pressed, _, Some(VirtualKeyCode::PageUp)) => {
120 KeyboardInput(Pressed, _, Some(VirtualKeyCode::PageDown)) => {
123 KeyboardInput(Pressed, _, Some(VirtualKeyCode::F10)) => {
124 screenshot(&display);
126 KeyboardInput(Pressed, _, Some(VirtualKeyCode::F11)) => {
129 // Not implemented on Linux
130 glutin::WindowBuilder::new()
131 .with_fullscreen(glutin::get_primary_monitor())
132 .with_depth_buffer(24)
133 .rebuild_glium(&display).unwrap();
135 //glutin::WindowBuilder::new()
136 // .rebuild_glium(&display).unwrap();
139 ev => camera.process_input(&ev),
143 support::Action::Continue