Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fill_triangle :: proc(r: ^Renderer, a, b, c: V4, color: Color) {
- Edge :: struct {
- x: f64,
- x_step: f64,
- y_start: int,
- y_end: int
- };
- make_edge :: inline proc(min, max: V4) -> Edge {
- using e: Edge;
- y_start = int(math.ceil(min.y));
- y_end = int(math.ceil(max.y));
- x_dist := max.x - min.x;
- y_dist := max.y - min.y;
- y_prestep := f64(y_start) - min.y;
- x_step = x_dist / y_dist;
- x = min.x + y_prestep * x_step;
- return e;
- }
- step :: inline proc(using e: ^Edge) {
- x += x_step;
- }
- draw_scan_line :: inline proc(r: ^Renderer, min, max: Edge, y: int, color: Color) {
- x_min := int(math.ceil(min.x));
- x_max := int(math.ceil(max.x));
- for x in x_min..<x_max {
- draw_pixel(r.fb, x, y, color);
- }
- }
- scan_edges :: inline proc(r: ^Renderer, a, b: Edge, handedness: bool, color: Color) {
- left := a;
- right := b;
- if handedness do swap(&left, &right);
- y_start := b.y_start;
- y_end := b.y_end;
- for y in y_start..<y_end {
- draw_scan_line(r, left, right, y, color);
- step(&left);
- step(&right);
- }
- }
- a_p, b_p, c_p := mul(a, r.screen_space_transform), mul(b, r.screen_space_transform), mul(c, r.screen_space_transform);
- min, mid, max := perspective_divide(a_p), perspective_divide(b_p), perspective_divide(c_p);
- if max.y < mid.y do swap(&max, &mid);
- if mid.y < min.y do swap(&mid, &min);
- if max.y < mid.y do swap(&max, &mid);
- handedness := linalg.cross2(V2{min.x - max.x, min.y - max.y}, V2{min.x - mid.x, min.y - mid.y}) > 0;
- top_to_bottom := make_edge(min, max);
- top_to_middle := make_edge(min, mid);
- middle_to_bottom := make_edge(mid, max);
- scan_edges(r, top_to_bottom, top_to_middle, handedness, color);
- scan_edges(r, top_to_bottom, middle_to_bottom, handedness, color);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement