diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 149 | ||||
| -rw-r--r-- | src/main.rs | 163 | 
2 files changed, 155 insertions, 157 deletions
| @@ -4,6 +4,10 @@ mod poly;  use lerp::Lerp;  use poly::Poly; +use std::ffi::{CStr, CString}; + +use gl::types::*; +  pub struct Bezier {      pub degree: usize,      pub vx: Vec<f32>, @@ -68,4 +72,149 @@ impl Bezier {          }          s      } + +    pub fn draw(&self) { +        let vertex_shader_source = b" +        #version 410 core +        layout (location = 0) in vec3 aPos; +     +        void main() { +            gl_Position = vec4(aPos.xyz, 1.0); +        } +        " +        .to_vec(); +     +        let fragment_shader_source = format!( +            " +        #version 410 core +        out vec4 FragColor; +     +        float vx[{s}] = float[{s}]({vx}); +        float vy[{s}] = float[{s}]({vy}); +     +        float px[{sx}] = float[{sx}]({px}); +        float py[{sy}] = float[{sy}]({py}); +     +        float dpx[{dsx}] = float[{dsx}]({dpx}); +        float dpy[{dsy}] = float[{dsy}]({dpy}); +     +        float thr = 32; +        float step_size = 10; +        float inf = 1000000; +     +        float eval_px(float t) {{ +            float result = 0.0; +            for (int i = 0; i < {sx}; i++) {{ +              result += px[i] * pow(t, i); +            }} +            return result; +        }} +     +        float eval_py(float t) {{ +            float result = 0.0; +            for (int i = 0; i < {sy}; i++) {{ +              result += py[i] * pow(t, i); +            }} +            return result; +        }} +     +        float eval_dpx(float t) {{ +            float result = 0.0; +            for (int i = 0; i < {dsx}; i++) {{ +              result += dpx[i] * pow(t, i); +            }} +            return result; +        }} +     +        float eval_dpy(float t) {{ +            float result = 0.0; +            for (int i = 0; i < {dsy}; i++) {{ +              result += dpy[i] * pow(t, i); +            }} +            return result; +        }} +     +        float control(vec2 pos) {{ +          float closest = inf; +          for (int i = 0; i < {s}; i++) {{ +            float d = distance(pos, vec2(vx[i], vy[i])); +            if (d < closest) {{ +              closest = d; +            }} +          }} +          return 1 - closest / thr; +        }} +     +        float inside(vec2 pos) {{ +          float closest = inf; +          float t = 0.0; +          float dstep = 0.0; +          while (t < 1.0 - dstep) {{ +            dstep = step_size / length(vec2(eval_dpx(t), eval_dpy(t))); +            float step = t + dstep; +            vec2 a = vec2(eval_px(t), eval_py(t)); +            vec2 b = vec2(eval_px(step), eval_py(step)); +            float c = pow(length(a - b), 2); +            float d = distance(pos, a + clamp(dot(pos - a, b - a) / c, 0, 1) * (b - a)); +            if (d < closest) {{ +              closest = d; +            }} +            t = step; +          }} +          return 1 - closest / thr; +        }} +     +        void main() {{ +          float r = inside(gl_FragCoord.xy); +          float c = control(gl_FragCoord.xy); +          FragColor = vec4(r, c, 0.0, 1.0); +        }} +        ", +            s = self.degree, +            vx = self.show_x(), +            vy = self.show_y(), +            px = &self.px, +            py = &self.py, +            sx = self.px.degree() + 1, +            sy = self.py.degree() + 1, +            dpx = &self.dpx, +            dpy = &self.dpy, +            dsx = self.dpx.degree() + 1, +            dsy = self.dpy.degree() + 1, +        ) +        .into_bytes(); +     +        let shader_program: GLuint; +        unsafe { +            let vertex_shader = shader_from_source( +                &CString::from_vec_unchecked(vertex_shader_source), +                gl::VERTEX_SHADER, +            ); +            let fragment_shader = shader_from_source( +                &CString::from_vec_unchecked(fragment_shader_source), +                gl::FRAGMENT_SHADER, +            ); +            shader_program = gl::CreateProgram(); +            gl::AttachShader(shader_program, vertex_shader); +            gl::AttachShader(shader_program, fragment_shader); +            gl::LinkProgram(shader_program); +            gl::DeleteShader(vertex_shader); +            gl::DeleteShader(fragment_shader); +            gl::UseProgram(shader_program); +        } +    }  } + +fn shader_from_source(source: &CStr, shader_type: GLenum) -> GLuint { +    unsafe { +        let shader: GLuint = gl::CreateShader(shader_type); +        gl::ShaderSource(shader, 1, &source.as_ptr(), std::ptr::null()); +        gl::CompileShader(shader); +        let mut success: gl::types::GLint = 1; +        gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success); +        if success == 0 { +            println!("Compilation error: {}", source.to_str().unwrap()); +        } +        shader +    } +}
\ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 25a3ec1..f922376 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,158 +1,10 @@  use bezier::Bezier; -use std::ffi::{CStr, CString}; -  use sdl2::event::Event;  use sdl2::keyboard::Keycode;  use gl::types::*; -fn shader_from_source(source: &CStr, shader_type: GLenum) -> GLuint { -    unsafe { -        let shader: GLuint = gl::CreateShader(shader_type); -        gl::ShaderSource(shader, 1, &source.as_ptr(), std::ptr::null()); -        gl::CompileShader(shader); -        let mut success: gl::types::GLint = 1; -        gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success); -        if success == 0 { -            println!("Compilation error: {}", source.to_str().unwrap()); -        } -        shader -    } -} - -fn compile_bezier_shader(c: &Bezier) -> GLuint { -    let vertex_shader_source = b" -    #version 410 core -    layout (location = 0) in vec3 aPos; - -    void main() { -        gl_Position = vec4(aPos.xyz, 1.0); -    } -    " -    .to_vec(); - -    let fragment_shader_source = format!( -        " -    #version 410 core -    out vec4 FragColor; - -    float vx[{s}] = float[{s}]({vx}); -    float vy[{s}] = float[{s}]({vy}); - -    float px[{sx}] = float[{sx}]({px}); -    float py[{sy}] = float[{sy}]({py}); - -    float dpx[{dsx}] = float[{dsx}]({dpx}); -    float dpy[{dsy}] = float[{dsy}]({dpy}); - -    float thr = 32; -    float step_size = 10; -    float inf = 1000000; - -    float eval_px(float t) {{ -        float result = 0.0; -        for (int i = 0; i < {sx}; i++) {{ -          result += px[i] * pow(t, i); -        }} -        return result; -    }} - -    float eval_py(float t) {{ -        float result = 0.0; -        for (int i = 0; i < {sy}; i++) {{ -          result += py[i] * pow(t, i); -        }} -        return result; -    }} - -    float eval_dpx(float t) {{ -        float result = 0.0; -        for (int i = 0; i < {dsx}; i++) {{ -          result += dpx[i] * pow(t, i); -        }} -        return result; -    }} - -    float eval_dpy(float t) {{ -        float result = 0.0; -        for (int i = 0; i < {dsy}; i++) {{ -          result += dpy[i] * pow(t, i); -        }} -        return result; -    }} - -    float control(vec2 pos) {{ -      float closest = inf; -      for (int i = 0; i < {s}; i++) {{ -        float d = distance(pos, vec2(vx[i], vy[i])); -        if (d < closest) {{ -          closest = d; -        }} -      }} -      return 1 - closest / thr; -    }} - -    float inside(vec2 pos) {{ -      float closest = inf; -      float t = 0.0; -      float dstep = 0.0; -      while (t < 1.0 - dstep) {{ -        dstep = step_size / length(vec2(eval_dpx(t), eval_dpy(t))); -        float step = t + dstep; -        vec2 a = vec2(eval_px(t), eval_py(t)); -        vec2 b = vec2(eval_px(step), eval_py(step)); -        float c = pow(length(a - b), 2); -        float d = distance(pos, a + clamp(dot(pos - a, b - a) / c, 0, 1) * (b - a)); -        if (d < closest) {{ -          closest = d; -        }} -        t = step; -      }} -      return 1 - closest / thr; -    }} - -    void main() {{ -      float r = inside(gl_FragCoord.xy); -      float c = control(gl_FragCoord.xy); -      FragColor = vec4(r, c, 0.0, 1.0); -    }} -    ", -        s = c.degree, -        vx = c.show_x(), -        vy = c.show_y(), -        px = &c.px, -        py = &c.py, -        sx = c.px.degree() + 1, -        sy = c.py.degree() + 1, -        dpx = &c.dpx, -        dpy = &c.dpy, -        dsx = c.dpx.degree() + 1, -        dsy = c.dpy.degree() + 1, -    ) -    .into_bytes(); - -    let shader_program: GLuint; -    unsafe { -        let vertex_shader = shader_from_source( -            &CString::from_vec_unchecked(vertex_shader_source), -            gl::VERTEX_SHADER, -        ); -        let fragment_shader = shader_from_source( -            &CString::from_vec_unchecked(fragment_shader_source), -            gl::FRAGMENT_SHADER, -        ); -        shader_program = gl::CreateProgram(); -        gl::AttachShader(shader_program, vertex_shader); -        gl::AttachShader(shader_program, fragment_shader); -        gl::LinkProgram(shader_program); -        gl::DeleteShader(vertex_shader); -        gl::DeleteShader(fragment_shader); -        gl::UseProgram(shader_program); -    } -    shader_program -} -  fn main() {      let mut curve = Bezier::new(); @@ -164,8 +16,8 @@ fn main() {      gl_attr.set_context_profile(sdl2::video::GLProfile::Core);      gl_attr.set_context_version(4, 1); -    let window_w: u32 = 1920; -    let window_h: u32 = 1080; +    let window_w: u32 = 800; +    let window_h: u32 = 600;      let window = video_subsystem          .window("bezier", window_w, window_h) @@ -178,18 +30,14 @@ fn main() {      gl::load_with(|s| video_subsystem.gl_get_proc_address(s) as *const std::os::raw::c_void); -    unsafe { -        gl::Viewport(0, 0, window_w as i32, window_h as i32); -    } -      let vertices: [f32; 18] = [ -        1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, -1.0, 1.0, -        0.0, +        1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, -1.0, 1.0, 0.0,      ];      let mut vbo: GLuint = 0;      let mut vao: GLuint = 0;      unsafe { +        gl::Viewport(0, 0, window_w as i32, window_h as i32);          gl::GenVertexArrays(1, &mut vao);          gl::BindVertexArray(vao);          gl::GenBuffers(1, &mut vbo); @@ -227,13 +75,14 @@ fn main() {                      ..                  } => {                      curve.push(x, window_h as i32 - y); -                    compile_bezier_shader(&curve); +                    curve.draw();                  }                  _ => {}              }          }          unsafe { +            gl::ClearColor(0.0, 0.0, 0.0, 1.0);              gl::Clear(gl::COLOR_BUFFER_BIT);              gl::DrawArrays(gl::TRIANGLES, 0, 6);          } | 
