Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import "core:fmt.odin"
- import gl "core:opengl.odin"
- import "core:strings.odin"
- import "core:math.odin"
- import "shared:odin-glfw/glfw.odin"
- vertex2 :: proc(v: [vector 2]f32) #inline {
- gl.Vertex2f(v.x, v.y);
- }
- color4 :: proc(c: [vector 4]f32) #inline {
- gl.Color4f(c.x, c.y, c.z, c.w);
- }
- line :: proc(c: [vector 4]f32, size: f32, pa, pb: [vector 2]f32) #inline {
- gl.LineWidth(size);
- gl.Begin(gl.LINES);
- color4(c);
- vertex2(pa);
- vertex2(pb);
- gl.End();
- }
- lines :: proc(c: [vector 4]f32, size: f32, points: ...[vector 2]f32) #inline {
- gl.LineWidth(size);
- gl.Begin(gl.LINE_STRIP);
- color4(c);
- for p in points do vertex2(p);
- gl.End();
- }
- dot :: proc(c: [vector 4]f32, p: [vector 2]f32, size: f32 = 1) #inline {
- gl.PointSize(size);
- gl.Begin(gl.POINTS);
- color4(c);
- vertex2(p);
- gl.End();
- }
- bezier :: proc(t: f32, p0, p1, p2, p3: [vector 2]f32) -> [vector 2]f32 {
- t2 := t*t;
- t3 := t2*t;
- ot := 1-t;
- ot2 := ot*ot;
- ot3 := ot2*ot;
- return ot3*p0 + 3*t*ot2*p1 + 3*t2*ot*p2 + t3*p3;
- }
- bezier_velocity :: proc(t: f32, p0, p1, p2, p3: [vector 2]f32) -> [vector 2]f32 {
- t2 := t*t;
- ot := 1-t;
- ot2 := ot*ot;
- return 3*ot2*(p1-p0) + 6*ot*t*(p2-p1) + 3*t2*(p3-p2);
- }
- curve :: proc(factor: int, points: ...[vector 2]f32) -> [][vector 2]f32 {
- if len(points) % 4 != 0 do return nil;
- new_points := make([][vector 2]f32, 0, factor*len(points) + 1);
- t := f32(1.0)/f32(factor);
- for i := 0; i < len(points); i += 4 {
- p0, p1, p2, p3 := points[i+0], points[i+1], points[i+2], points[i+3];
- for j in 0..factor {
- append(&new_points, bezier(t*f32(j), p0, p1, p2, p3));
- }
- }
- append(&new_points, points[len(points)-1]);
- return new_points;
- }
- avg :: proc(vec: [vector 2]f32) -> f32 #inline do return (vec.x + vec.y) / 2;
- lerp :: proc(a, b: [vector 2]f32, t: f32) -> (x: [vector 2]f32) #inline do return a*(1-t) + b*t;
- unlerp :: proc(a, b, x: [vector 2]f32) -> (t: f32) #inline do return avg((x-a)/(b-a));
- cursor :: proc(window: ^glfw.window) -> [vector 2]f32 #inline {
- x, y: f64;
- glfw.GetCursorPos(window, &x, &y);
- return [vector 2]f32{f32(x), f32(y)};
- }
- key :: proc(window: ^glfw.window, k: i32) -> bool #inline {
- return bool(glfw.GetKey(window, k));
- }
- move_along_line :: proc(pos: ^[vector 2]f32, step: f32, pa, pb: [vector 2]f32) {
- if pos.x >= pb.x || pos.y >= pb.y {
- pos^ = pa;
- } else {
- pos^ += step*(pb-pa);
- }
- }
- move_along_bezier :: proc(pos: ^[vector 2]f32, p0, p1, p2, p3: [vector 2]f32) {
- //if pox.x >= pb.x || pos.y
- }
- main :: proc() {
- w, h := 800, 600;
- glfw.SetErrorCallback(proc(e: i32, desc: ^u8) #cc_c {
- fmt.printf("Error code %d: \r\n\t%s\r\n", e, strings.to_odin_string(desc));
- });
- assert(glfw.Init() != 0, "glfw failed to load!");
- defer glfw.Terminate();
- window := glfw.CreateWindow(i32(w), i32(h), "BMP Loader", nil, nil);
- assert(window != nil, "window creation failed!");
- glfw.MakeContextCurrent(window);
- glfw.SwapInterval(1);
- gl.ClearColor(0.5, 0.5, 0.6, 1.0);
- size: f32 = 0.9;
- gl.Ortho(0, f64(w), f64(h), 0, 0, 1);
- white := [vector 4]f32{1, 1, 1, 1};
- black := [vector 4]f32{0, 0, 0, 1};
- red := [vector 4]f32{1, 0, 0, 1};
- green := [vector 4]f32{0, 1, 0, 1};
- blue := [vector 4]f32{0, 0, 1, 1};
- yellow := [vector 4]f32{1, 1, 0, 1};
- teal := [vector 4]f32{0, 1, 1, 1};
- xmin, xmax := f32(20), f32(w - 20);
- ymin, ymax := f32(20), f32(h - 20);
- par: f32 = 400;
- p0 := [vector 2]f32{xmin, ymin};
- p1 := [vector 2]f32{xmin+par, ymax-par};
- p2 := [vector 2]f32{xmax-par, ymin+par};
- p3 := [vector 2]f32{xmax, ymax};
- e0 := p0;
- step: f32 = 0.005;
- for glfw.WindowShouldClose(window) == glfw.FALSE {
- glfw.calculate_frame_timings(window);
- glfw.PollEvents();
- gl.Clear(gl.COLOR_BUFFER_BIT);
- if key(window, glfw.KEY_A) do p1 = cursor(window);
- if key(window, glfw.KEY_S) do p2 = cursor(window);
- line(white, 2, p0, p3);
- points := curve(256, p0, p1, p2, p3);
- lines(red, 2, ...points);
- //lines(teal, 2, p0, p1, p2, p3);
- dot(white, p0, 5);
- dot(white, p1, 5);
- dot(white, p2, 5);
- dot(white, p3, 5);
- move_along_line(&e0, step, p0, p3);
- t := unlerp(p0, p3, e0);
- //e1 := bezier(t, p0, p1, p2, p3);
- t = t + 1.0 / math.mag(bezier_velocity(t, p0, p1, p2, p3)) * step;
- e1 := bezier(t, p0, p1, p2, p3);
- line(green, 2, e0, e1);
- dot(black, e0, 5);
- dot(black, e1, 5);
- glfw.SwapBuffers(window);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement