From fc22d14dfdb041797db66a9232b3beb06fada08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Sat, 30 Jan 2021 18:18:23 -0300 Subject: Refactor curve drawing functionality --- src/main.rs | 163 +++--------------------------------------------------------- 1 file changed, 6 insertions(+), 157 deletions(-) (limited to 'src/main.rs') 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); } -- cgit v1.2.3