Advertisement
Guest User

Untitled

a guest
Oct 15th, 2017
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 4.80 KB | None | 0 0
  1. import "core:fmt.odin"
  2. import gl "core:opengl.odin"
  3. import "core:strings.odin"
  4. import "core:math.odin"
  5.  
  6. import "shared:odin-glfw/glfw.odin"
  7.  
  8. vertex2 :: proc(v: [vector 2]f32) #inline {
  9.     gl.Vertex2f(v.x, v.y);
  10. }
  11.  
  12. color4 :: proc(c: [vector 4]f32) #inline {
  13.     gl.Color4f(c.x, c.y, c.z, c.w);
  14. }
  15.  
  16. line :: proc(c: [vector 4]f32, size: f32, pa, pb: [vector 2]f32) #inline {
  17.     gl.LineWidth(size);
  18.     gl.Begin(gl.LINES);
  19.     color4(c);
  20.     vertex2(pa);
  21.     vertex2(pb);
  22.     gl.End();
  23. }
  24.  
  25. lines :: proc(c: [vector 4]f32, size: f32, points: ...[vector 2]f32) #inline {
  26.     gl.LineWidth(size);
  27.     gl.Begin(gl.LINE_STRIP);
  28.     color4(c);
  29.     for p in points do vertex2(p);
  30.     gl.End();
  31. }
  32.  
  33. dot :: proc(c: [vector 4]f32, p: [vector 2]f32, size: f32 = 1) #inline {
  34.     gl.PointSize(size);
  35.     gl.Begin(gl.POINTS);
  36.     color4(c);
  37.     vertex2(p);
  38.     gl.End();
  39. }
  40.  
  41. bezier :: proc(t: f32, p0, p1, p2, p3: [vector 2]f32) -> [vector 2]f32 {
  42.     t2  := t*t;
  43.     t3  := t2*t;
  44.     ot  := 1-t;
  45.     ot2 := ot*ot;
  46.     ot3 := ot2*ot;
  47.  
  48.     return ot3*p0 + 3*t*ot2*p1 + 3*t2*ot*p2 + t3*p3;
  49. }
  50.  
  51. bezier_velocity :: proc(t: f32, p0, p1, p2, p3: [vector 2]f32) -> [vector 2]f32 {
  52.     t2  := t*t;
  53.     ot  := 1-t;
  54.     ot2 := ot*ot;
  55.  
  56.     return 3*ot2*(p1-p0) + 6*ot*t*(p2-p1) + 3*t2*(p3-p2);
  57. }
  58.  
  59. curve :: proc(factor: int, points: ...[vector 2]f32) -> [][vector 2]f32 {
  60.     if len(points) % 4 != 0 do return nil;
  61.  
  62.     new_points := make([][vector 2]f32, 0, factor*len(points) + 1);
  63.  
  64.     t := f32(1.0)/f32(factor);
  65.  
  66.     for i := 0; i < len(points); i += 4 {
  67.         p0, p1, p2, p3 := points[i+0], points[i+1], points[i+2], points[i+3];
  68.         for j in 0..factor {
  69.             append(&new_points, bezier(t*f32(j), p0, p1, p2, p3));
  70.         }
  71.     }
  72.  
  73.     append(&new_points, points[len(points)-1]);
  74.  
  75.     return new_points;
  76. }
  77.  
  78. avg :: proc(vec: [vector 2]f32) -> f32 #inline do return (vec.x + vec.y) / 2;
  79.  
  80. lerp :: proc(a, b: [vector 2]f32, t: f32) -> (x: [vector 2]f32) #inline do return a*(1-t) + b*t;
  81. unlerp :: proc(a, b, x: [vector 2]f32) -> (t: f32) #inline do return avg((x-a)/(b-a));
  82.  
  83. cursor :: proc(window: ^glfw.window) -> [vector 2]f32 #inline {
  84.     x, y: f64;
  85.     glfw.GetCursorPos(window, &x, &y);
  86.     return [vector 2]f32{f32(x), f32(y)};
  87. }
  88.  
  89. key :: proc(window: ^glfw.window, k: i32) -> bool #inline {
  90.     return bool(glfw.GetKey(window, k));
  91. }
  92.  
  93. move_along_line :: proc(pos: ^[vector 2]f32, step: f32, pa, pb: [vector 2]f32) {
  94.     if pos.x >= pb.x || pos.y >= pb.y {
  95.         pos^ = pa;
  96.     } else {
  97.         pos^ += step*(pb-pa);
  98.     }
  99. }
  100.  
  101. move_along_bezier :: proc(pos: ^[vector 2]f32, p0, p1, p2, p3: [vector 2]f32) {
  102.     //if pox.x >= pb.x || pos.y
  103. }
  104.  
  105. main :: proc() {
  106.     w, h := 800, 600;
  107.  
  108.     glfw.SetErrorCallback(proc(e: i32, desc: ^u8) #cc_c {
  109.         fmt.printf("Error code %d: \r\n\t%s\r\n", e, strings.to_odin_string(desc));
  110.     });
  111.  
  112.     assert(glfw.Init() != 0, "glfw failed to load!");
  113.     defer glfw.Terminate();
  114.  
  115.     window := glfw.CreateWindow(i32(w), i32(h), "BMP Loader", nil, nil);
  116.     assert(window != nil, "window creation failed!");
  117.  
  118.     glfw.MakeContextCurrent(window);
  119.     glfw.SwapInterval(1);
  120.  
  121.     gl.ClearColor(0.5, 0.5, 0.6, 1.0);
  122.  
  123.     size: f32 = 0.9;
  124.  
  125.     gl.Ortho(0, f64(w), f64(h), 0, 0, 1);
  126.  
  127.     white  := [vector 4]f32{1, 1, 1, 1};
  128.     black  := [vector 4]f32{0, 0, 0, 1};
  129.     red    := [vector 4]f32{1, 0, 0, 1};
  130.     green  := [vector 4]f32{0, 1, 0, 1};
  131.     blue   := [vector 4]f32{0, 0, 1, 1};
  132.     yellow := [vector 4]f32{1, 1, 0, 1};
  133.     teal   := [vector 4]f32{0, 1, 1, 1};
  134.  
  135.     xmin, xmax := f32(20), f32(w - 20);
  136.     ymin, ymax := f32(20), f32(h - 20);
  137.     par: f32 = 400;
  138.  
  139.     p0 := [vector 2]f32{xmin, ymin};
  140.     p1 := [vector 2]f32{xmin+par, ymax-par};
  141.     p2 := [vector 2]f32{xmax-par, ymin+par};
  142.     p3 := [vector 2]f32{xmax, ymax};
  143.  
  144.     e0 := p0;  
  145.  
  146.     step: f32 = 0.005;
  147.  
  148.     for glfw.WindowShouldClose(window) == glfw.FALSE {
  149.         glfw.calculate_frame_timings(window);
  150.  
  151.         glfw.PollEvents();
  152.  
  153.         gl.Clear(gl.COLOR_BUFFER_BIT);
  154.  
  155.         if key(window, glfw.KEY_A) do p1 = cursor(window);
  156.         if key(window, glfw.KEY_S) do p2 = cursor(window);
  157.  
  158.         line(white, 2, p0, p3);
  159.  
  160.         points := curve(256, p0, p1, p2, p3);
  161.         lines(red, 2, ...points);
  162.  
  163.         //lines(teal, 2, p0, p1, p2, p3);
  164.  
  165.         dot(white, p0, 5);
  166.         dot(white, p1, 5);
  167.         dot(white, p2, 5);
  168.         dot(white, p3, 5);
  169.  
  170.         move_along_line(&e0, step, p0, p3);
  171.         t := unlerp(p0, p3, e0);
  172.         //e1 := bezier(t, p0, p1, p2, p3);
  173.        
  174.         t = t + 1.0 / math.mag(bezier_velocity(t, p0, p1, p2, p3)) * step;
  175.         e1 := bezier(t, p0, p1, p2, p3);
  176.  
  177.         line(green, 2, e0, e1);
  178.        
  179.         dot(black, e0, 5);
  180.         dot(black, e1, 5);
  181.  
  182.         glfw.SwapBuffers(window);
  183.     }
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement