]> git.lizzy.rs Git - nothing.git/blob - src/renderer.c
(#132) Test sound medium
[nothing.git] / src / renderer.c
1 #include <assert.h>
2 #include <SDL2/SDL.h>
3 #include "./renderer.h"
4 #include "./error.h"
5
6 int draw_triangle(SDL_Renderer *render,
7                   triangle_t t)
8 {
9     assert(render);
10
11     if (SDL_RenderDrawLine(render,
12                            (int) roundf(t.p1.x),
13                            (int) roundf(t.p1.y),
14                            (int) roundf(t.p2.x),
15                            (int) roundf(t.p2.y)) < 0) {
16         throw_error(ERROR_TYPE_SDL2);
17         return -1;
18     }
19
20     if (SDL_RenderDrawLine(render,
21                            (int) roundf(t.p2.x),
22                            (int) roundf(t.p2.y),
23                            (int) roundf(t.p3.x),
24                            (int) roundf(t.p3.y)) < 0) {
25         throw_error(ERROR_TYPE_SDL2);
26         return -1;
27     }
28
29     if (SDL_RenderDrawLine(render,
30                            (int) roundf(t.p3.x),
31                            (int) roundf(t.p3.y),
32                            (int) roundf(t.p1.x),
33                            (int) roundf(t.p1.y)) < 0) {
34         throw_error(ERROR_TYPE_SDL2);
35         return -1;
36     }
37
38     return 0;
39 }
40
41 static int fill_bottom_flat_triangle(SDL_Renderer *render,
42                                      triangle_t t)
43 {
44     assert(render);
45
46     const float invslope1 = (t.p2.x - t.p1.x) / (t.p2.y - t.p1.y);
47     const float invslope2 = (t.p3.x - t.p1.x) / (t.p3.y - t.p1.y);
48
49     const int y0 = (int) roundf(t.p1.y);
50     const int y1 = (int) roundf(t.p2.y);
51
52     float curx1 = t.p1.x;
53     float curx2 = t.p1.x;
54
55     for (int scanline = y0; scanline < y1; scanline++) {
56         if (SDL_RenderDrawLine(render,
57                                (int) roundf(curx1),
58                                scanline,
59                                (int) roundf(curx2),
60                                scanline) < 0) {
61             return -1;
62         }
63         curx1 += invslope1;
64         curx2 += invslope2;
65     }
66
67     return 0;
68 }
69
70 static int fill_top_flat_triangle(SDL_Renderer *render,
71                                   triangle_t t)
72 {
73     assert(render);
74
75     const float invslope1 = (t.p3.x - t.p1.x) / (t.p3.y - t.p1.y);
76     const float invslope2 = (t.p3.x - t.p2.x) / (t.p3.y - t.p2.y);
77
78     const int y0 = (int) roundf(t.p3.y);
79     const int y1 = (int) roundf(t.p1.y);
80
81     float curx1 = t.p3.x;
82     float curx2 = t.p3.x;
83
84     for (int scanline = y0; scanline > y1; --scanline) {
85         if (SDL_RenderDrawLine(render,
86                                (int) roundf(curx1),
87                                scanline,
88                                (int) roundf(curx2),
89                                scanline) < 0) {
90             return -1;
91         }
92
93         curx1 -= invslope1;
94         curx2 -= invslope2;
95     }
96
97     return 0;
98 }
99
100 int fill_triangle(SDL_Renderer *render,
101                   triangle_t t)
102 {
103     t = triangle_sorted_by_y(t);
104
105     if (fabs(t.p2.y - t.p3.y) < 1e-6) {
106         if (fill_bottom_flat_triangle(render, t) < 0) {
107             return -1;
108         }
109     } else if (fabs(t.p1.y - t.p2.y) < 1e-6) {
110         if (fill_top_flat_triangle(render, t) < 0) {
111             return -1;
112         }
113     } else {
114         const point_t p4 = vec(t.p1.x + ((t.p2.y - t.p1.y) / (t.p3.y - t.p1.y)) * (t.p3.x - t.p1.x), t.p2.y);
115
116         if (fill_bottom_flat_triangle(render, triangle(t.p1, t.p2, p4)) < 0) {
117             return -1;
118         }
119
120         if (fill_top_flat_triangle(render, triangle(t.p2, p4, t.p3)) < 0) {
121             return -1;
122         }
123
124         if (SDL_RenderDrawLine(render,
125                                (int) roundf(t.p2.x),
126                                (int) roundf(t.p2.y),
127                                (int) roundf(p4.x),
128                                (int) roundf(p4.y)) < 0) {
129             return -1;
130         }
131     }
132
133     return 0;
134 }