Skip to content

Commit 633c657

Browse files
committed
Implement olivec_fill_triangle()
1 parent dd37029 commit 633c657

File tree

4 files changed

+95
-0
lines changed

4 files changed

+95
-0
lines changed

olive.c

+66
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,72 @@ void olivec_draw_line(uint32_t *pixels, size_t pixels_width, size_t pixels_heigh
105105
}
106106
}
107107

108+
void olivec_sort_triangle_points_by_y(int *x1, int *y1,
109+
int *x2, int *y2,
110+
int *x3, int *y3)
111+
{
112+
113+
if (*y1 > *y2) {
114+
OLIVEC_SWAP(int, *x1, *x2);
115+
OLIVEC_SWAP(int, *y1, *y2);
116+
}
117+
118+
if (*y2 > *y3) {
119+
OLIVEC_SWAP(int, *x2, *x3);
120+
OLIVEC_SWAP(int, *y2, *y3);
121+
}
122+
123+
if (*y1 > *y2) {
124+
OLIVEC_SWAP(int, *x1, *x2);
125+
OLIVEC_SWAP(int, *y1, *y2);
126+
}
127+
}
128+
129+
void olivec_fill_triangle(uint32_t *pixels, size_t width, size_t height,
130+
int x1, int y1,
131+
int x2, int y2,
132+
int x3, int y3,
133+
uint32_t color)
134+
{
135+
olivec_sort_triangle_points_by_y(&x1, &y1, &x2, &y2, &x3, &y3);
136+
137+
int dx12 = x2 - x1;
138+
int dy12 = y2 - y1;
139+
int dx13 = x3 - x1;
140+
int dy13 = y3 - y1;
141+
142+
for (int y = y1; y <= y2; ++y) {
143+
if (0 <= y && (size_t) y < height) {
144+
int s1 = dy12 != 0 ? (y - y1)*dx12/dy12 + x1 : x1;
145+
int s2 = dy13 != 0 ? (y - y1)*dx13/dy13 + x1 : x1;
146+
if (s1 > s2) OLIVEC_SWAP(int, s1, s2);
147+
for (int x = s1; x <= s2; ++x) {
148+
if (0 <= x && (size_t) x < width) {
149+
pixels[y*width + x] = color;
150+
}
151+
}
152+
}
153+
}
154+
155+
int dx32 = x2 - x3;
156+
int dy32 = y2 - y3;
157+
int dx31 = x1 - x3;
158+
int dy31 = y1 - y3;
159+
160+
for (int y = y2; y <= y3; ++y) {
161+
if (0 <= y && (size_t) y < height) {
162+
int s1 = dy32 != 0 ? (y - y3)*dx32/dy32 + x3 : x3;
163+
int s2 = dy31 != 0 ? (y - y3)*dx31/dy31 + x3 : x3;
164+
if (s1 > s2) OLIVEC_SWAP(int, s1, s2);
165+
for (int x = s1; x <= s2; ++x) {
166+
if (0 <= x && (size_t) x < width) {
167+
pixels[y*width + x] = color;
168+
}
169+
}
170+
}
171+
}
172+
}
173+
108174
// TODO: supersampling for circles and lines
109175
// TODO: olivec_fill_triangle
110176
// TODO: olivec_draw_circle

test.c

+29
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ bool replay_test_case(const char *program_path, const char *file_path, const cha
107107
}
108108
}
109109

110+
// TODO: save the actual image along with the diff
110111
if (failed) {
111112
fprintf(stderr, "%s: TEST FAILURE: unexpected pixels in generated image\n", file_path);
112113
if (!stbi_write_png(failure_file_path, WIDTH, HEIGHT, 4, pixels, sizeof(uint32_t)*WIDTH)) {
@@ -160,12 +161,40 @@ void test_draw_line(void)
160161
olivec_fill(pixels, WIDTH, HEIGHT, BACKGROUND_COLOR);
161162
olivec_draw_line(pixels, WIDTH, HEIGHT, 0, 0, WIDTH, HEIGHT, RED_COLOR);
162163
olivec_draw_line(pixels, WIDTH, HEIGHT, WIDTH, 0, 0, HEIGHT, BLUE_COLOR);
164+
olivec_draw_line(pixels, WIDTH, HEIGHT, WIDTH/2, 0, WIDTH/2, HEIGHT, GREEN_COLOR);
165+
}
166+
167+
void test_fill_triangle(void)
168+
{
169+
olivec_fill(pixels, WIDTH, HEIGHT, BACKGROUND_COLOR);
170+
171+
{
172+
int x1 = WIDTH/2, y1 = HEIGHT/8;
173+
int x2 = WIDTH/8, y2 = HEIGHT/2;
174+
int x3 = WIDTH*7/8, y3 = HEIGHT*7/8;
175+
olivec_fill_triangle(pixels, WIDTH, HEIGHT, x1, y1, x2, y2, x3, y3, RED_COLOR);
176+
}
177+
178+
{
179+
int x1 = WIDTH/2, y1 = HEIGHT*2/8;
180+
int x2 = WIDTH*2/8, y2 = HEIGHT/2;
181+
int x3 = WIDTH*6/8, y3 = HEIGHT/2;
182+
olivec_fill_triangle(pixels, WIDTH, HEIGHT, x1, y1, x2, y2, x3, y3, GREEN_COLOR);
183+
}
184+
185+
{
186+
int x1 = WIDTH/8, y1 = HEIGHT/8;
187+
int x2 = WIDTH/8, y2 = HEIGHT*3/8;
188+
int x3 = WIDTH*3/8, y3 = HEIGHT*3/8;
189+
olivec_fill_triangle(pixels, WIDTH, HEIGHT, x1, y1, x2, y2, x3, y3, BLUE_COLOR);
190+
}
163191
}
164192

165193
Test_Case test_cases[] = {
166194
DEFINE_TEST_CASE(test_fill_rect),
167195
DEFINE_TEST_CASE(test_fill_circle),
168196
DEFINE_TEST_CASE(test_draw_line),
197+
DEFINE_TEST_CASE(test_fill_triangle),
169198
};
170199
#define TEST_CASES_COUNT (sizeof(test_cases)/sizeof(test_cases[0]))
171200

test/test_draw_line.png

-3 Bytes
Loading

test/test_fill_triangle.png

1.35 KB
Loading

0 commit comments

Comments
 (0)