X-Git-Url: https://codewiz.org/gitweb?p=mandelwow.git;a=blobdiff_plain;f=mandelwow.rs;h=8e759ef8013a1efc8943e0e78853063dca79a5fe;hp=8feb2b915093f5cbd39df949455246773d46100e;hb=e523420da6df64609d595e1e6e902592c00f6a47;hpb=76fc76631cf155123b127f5bc576d2922c536ebc diff --git a/mandelwow.rs b/mandelwow.rs index 8feb2b9..8e759ef 100644 --- a/mandelwow.rs +++ b/mandelwow.rs @@ -1,26 +1,11 @@ // Wow. Such fractal. -#[macro_use] - -extern crate glium; -extern crate glutin; - -use glium::DisplayBuild; -use glium::Surface; -use glium::index::IndexBuffer; +use cube::Cube; +use glium; use glium::index::PrimitiveType; +use glium::Surface; +use support; -mod support; - -#[derive(Copy, Clone)] -struct Cube { - xmin: f32, - ymin: f32, - zmin: f32, - xmax: f32, - ymax: f32, - zmax: f32, -} /* fn mand(cx: f32, cy: f32) -> [f32; 3] { @@ -43,135 +28,14 @@ fn mand(cx: f32, cy: f32) -> [f32; 3] { } */ -fn mandelwow_program(display: &glium::Display) -> glium::Program { +pub fn program(display: &glium::Display) -> glium::Program { return program!(display, - 140 => { - vertex: r#" - #version 140 - uniform mat4 perspective; - uniform mat4 view; - uniform mat4 model; - uniform vec2 z0; - in vec3 position; - out vec2 c; - out vec2 z; - - void main() { - mat4 modelview = view * model; - gl_Position = perspective * modelview * vec4(position, 1.0); - c = vec2(position.x, position.y); - z = vec2(z0.x, z0.y); - } - "#, - - fragment: r#" - #version 140 - precision highp float; - in vec2 c; - in vec2 z; - out vec4 f_color; - - void main() { - float zx = z.x; - float zy = z.y; - int maxiter = 64; - int iter = maxiter; - while (iter > 0) { - float zx2 = zx * zx; - float zy2 = zy * zy; - if (zx2 * zy2 > 4.0) { - float index = 1.0 - float(iter) / float(maxiter); - f_color = vec4(index, index * 0.5, index, index * 0.5); - return; - } - zy = zx * zy * 2.0 + c.y; - zx = zx2 - zy2 + c.x; - iter -= 1; - } - f_color = vec4((sin(z.y) + 1.0) / 2, - (sin(c.y) + 1.0) / 2, - (sin(c.x) + 1.0) / 2, - 1.0); - } - "# + 100 => { + vertex: include_str!("mandelwow.vert"), + fragment: include_str!("mandelwow.frag"), }).unwrap(); } -fn solid_fill_program(display: &glium::Display) -> glium::Program { - let vertex_shader_src = r#" - #version 140 - in vec3 position; - uniform mat4 perspective; - uniform mat4 view; - uniform mat4 model; - - void main() { - mat4 modelview = view * model; - gl_Position = perspective * modelview * vec4(position, 1.0); - } - "#; - - let fragment_shader_src = r#" - #version 140 - - out vec4 color; - - void main() { - color = vec4(1.0, 1.0, 1.0, 1.0); - } - "#; - - return glium::Program::from_source(display, - vertex_shader_src, - fragment_shader_src, - None).unwrap(); -} - -fn bounding_box(display: &glium::Display, - frame: &mut glium::Frame, - program: &glium::Program, - uniforms: &U, - cube: &Cube) where U: glium::uniforms::Uniforms { - - #[derive(Copy, Clone)] - struct Vertex { position: [f32; 3] } - implement_vertex!(Vertex, position); - - let cube = [ - Vertex { position: [cube.xmin, cube.ymin, cube.zmin] }, - Vertex { position: [cube.xmax, cube.ymin, cube.zmin] }, - Vertex { position: [cube.xmax, cube.ymax, cube.zmin] }, - Vertex { position: [cube.xmin, cube.ymax, cube.zmin] }, - Vertex { position: [cube.xmin, cube.ymin, cube.zmax] }, - Vertex { position: [cube.xmax, cube.ymin, cube.zmax] }, - Vertex { position: [cube.xmax, cube.ymax, cube.zmax] }, - Vertex { position: [cube.xmin, cube.ymax, cube.zmax] }, - ]; - let vb = glium::VertexBuffer::new(display, &cube).unwrap(); - - 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(); - frame.draw(&vb, &front_indices, program, uniforms, ¶ms).unwrap(); - - let back_indices = IndexBuffer::new(display, PrimitiveType::LineLoop, - &[4, 5, 6, 7u16]).unwrap(); - frame.draw(&vb, &back_indices, program, uniforms, ¶ms).unwrap(); - - let sides_indices = IndexBuffer::new(display, PrimitiveType::LinesList, - &[0, 4, 1, 5, 2, 6, 3, 7u16]).unwrap(); - frame.draw(&vb, &sides_indices, program, uniforms, ¶ms).unwrap(); -} - fn mandel(display: &glium::Display, frame: &mut glium::Frame, program: &glium::Program, @@ -222,8 +86,8 @@ fn mandel(display: &glium::Display, //let vb = glium::VertexBuffer::empty_persistent(display, width*height*3).unwrap(); let vb = glium::VertexBuffer::new(display, &v).unwrap(); - let indices = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip); - //let indices = glium::index::NoIndices(glium::index::PrimitiveType::LineStrip); + let indices = glium::index::NoIndices(PrimitiveType::TriangleStrip); + //let indices = glium::index::NoIndices(PrimitiveType::LineStrip); //let indices = glium::IndexBuffer::new(display, PrimitiveType::TrianglesList, // &[0u16, 1, 2]).unwrap(); @@ -231,16 +95,16 @@ fn mandel(display: &glium::Display, depth: glium::Depth { test: glium::draw_parameters::DepthTest::IfLess, write: true, - .. Default::default() + ..Default::default() }, blend: glium::Blend::alpha_blending(), - .. Default::default() + ..Default::default() }; frame.draw(&vb, &indices, program, uniforms, ¶ms).unwrap(); } -fn mandelwow(display: &glium::Display, +pub fn draw(display: &glium::Display, mut frame: &mut glium::Frame, program: &glium::Program, model: [[f32; 4]; 4], @@ -248,12 +112,13 @@ fn mandelwow(display: &glium::Display, bounds: &Cube, mandel_w: f32) { let mut z0 = [mandel_w, 0f32]; - let zres = 50; + let zres = 30; let zmin = bounds.zmin; let zmax = bounds.zmax; let zstep = (zmax - zmin) / zres as f32; let mut zy = zmin; - for _ in 0..zres { + // zres + 1 to reach the other face of the cube (fencepost error) + for _ in 0..(zres + 1) { z0[1] = zy; zy += zstep; @@ -267,96 +132,3 @@ fn mandelwow(display: &glium::Display, mandel(&display, &mut frame, &program, &uniforms, bounds, z0); } } - -fn main() { - let display = glium::glutin::WindowBuilder::new() - .with_dimensions(1024, 768) - .with_depth_buffer(24) - .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; - - 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); - - for ev in display.poll_events() { - match ev { - glium::glutin::Event::Closed => { - frame.finish().unwrap(); - return support::Action::Stop - }, - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::PageUp)) => { - t += 0.01; - }, - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::PageDown)) => { - t -= 0.01; - }, - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::P)) => { - pause ^= true; - }, - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::B)) => { - bounding_box_enabled ^= true; - }, - ev => camera.process_input(&ev), - } - } - - frame.finish().unwrap(); - support::Action::Continue - }); -}