Advertisement
sci4me

scan conversion rasterization

Dec 3rd, 2019
349
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.00 KB | None | 0 0
  1. fill_triangle :: proc(r: ^Renderer, a, b, c: V4, color: Color) {
  2. Edge :: struct {
  3. x: f64,
  4. x_step: f64,
  5. y_start: int,
  6. y_end: int
  7. };
  8.  
  9. make_edge :: inline proc(min, max: V4) -> Edge {
  10. using e: Edge;
  11.  
  12. y_start = int(math.ceil(min.y));
  13. y_end = int(math.ceil(max.y));
  14.  
  15. x_dist := max.x - min.x;
  16. y_dist := max.y - min.y;
  17.  
  18. y_prestep := f64(y_start) - min.y;
  19. x_step = x_dist / y_dist;
  20. x = min.x + y_prestep * x_step;
  21.  
  22. return e;
  23. }
  24.  
  25. step :: inline proc(using e: ^Edge) {
  26. x += x_step;
  27. }
  28.  
  29. draw_scan_line :: inline proc(r: ^Renderer, min, max: Edge, y: int, color: Color) {
  30. x_min := int(math.ceil(min.x));
  31. x_max := int(math.ceil(max.x));
  32.  
  33. for x in x_min..<x_max {
  34. draw_pixel(r.fb, x, y, color);
  35. }
  36. }
  37.  
  38. scan_edges :: inline proc(r: ^Renderer, a, b: Edge, handedness: bool, color: Color) {
  39. left := a;
  40. right := b;
  41.  
  42. if handedness do swap(&left, &right);
  43.  
  44. y_start := b.y_start;
  45. y_end := b.y_end;
  46. for y in y_start..<y_end {
  47. draw_scan_line(r, left, right, y, color);
  48. step(&left);
  49. step(&right);
  50. }
  51. }
  52.  
  53. a_p, b_p, c_p := mul(a, r.screen_space_transform), mul(b, r.screen_space_transform), mul(c, r.screen_space_transform);
  54. min, mid, max := perspective_divide(a_p), perspective_divide(b_p), perspective_divide(c_p);
  55.  
  56. if max.y < mid.y do swap(&max, &mid);
  57. if mid.y < min.y do swap(&mid, &min);
  58. if max.y < mid.y do swap(&max, &mid);
  59.  
  60. handedness := linalg.cross2(V2{min.x - max.x, min.y - max.y}, V2{min.x - mid.x, min.y - mid.y}) > 0;
  61.  
  62. top_to_bottom := make_edge(min, max);
  63. top_to_middle := make_edge(min, mid);
  64. middle_to_bottom := make_edge(mid, max);
  65.  
  66. scan_edges(r, top_to_bottom, top_to_middle, handedness, color);
  67. scan_edges(r, top_to_bottom, middle_to_bottom, handedness, color);
  68. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement