diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2025-04-25 10:12:37 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2025-04-25 10:12:37 +0200 |
commit | 67e3cb4f67692491be35899414f099d43bc975d6 (patch) | |
tree | 15c77a48d2a8db63a31b816a5c51a76dbb6d7337 | |
parent | 3f37db0647cb31955c8ad271f747c8e1ee5d2124 (diff) | |
download | reduced_system_layer-67e3cb4f67692491be35899414f099d43bc975d6.zip |
Add graphics tests; Fix triangles rendering
-rw-r--r-- | graphics.c | 238 |
1 files changed, 233 insertions, 5 deletions
@@ -413,11 +413,23 @@ void fill_triangles_to_buffer(Pixel_Buffer dst, vec4_f32 color, vec2 position, v for (i64 j = j0; j <= j1; ++j) for (i64 i = i0; i <= i1; ++i) - for (i64 k = 0; k < num_triangles; ++k) - if (hit_triangle(vertices + 3 * k, (vec2) { (f64) i, (f64) j, })) { + for (i64 k = 0; k < num_triangles; ++k) { + vec2 triangle[3] = { + vertices[3 * k], + vertices[3 * k + 1], + vertices[3 * k + 2], + }; + + for (i64 r = 0; r < 3; ++r) { + triangle[r].x = position.x + triangle[r].x * scale. x; + triangle[r].y = position.y + triangle[r].y * scale.y; + } + + if (hit_triangle(triangle, (vec2) { (f64) i, (f64) j, })) { put_pixel_(dst.pixels + j * dst.stride + i, color); break; } + } PROFILER_end(PROFILE_FILL_TRIANGLES); } @@ -493,14 +505,14 @@ void fill_ellipse_to_buffer(Pixel_Buffer dst, vec4_f32 color, Box area) { f64 cy = area.y + half_h; for (i64 j = j0; j <= j1; ++j) { - f64 ry = (j - cy) * inv_half_h; + f64 ry = (j - cy + 0.5) * inv_half_h; if (ry > 1.0 - EPSILON || ry < -1.0 + EPSILON) continue; f64 dx = half_w * sqrt(1.0 - ry * ry); - i64 left = (i64) ceil (cx - dx - EPSILON); - i64 right = (i64) floor(cx + dx + EPSILON); + i64 left = (i64) floor(cx - dx + 0.5); + i64 right = (i64) floor(cx + dx - 0.5); if (left < 0) left = 0; if (right >= dst.width) right = dst.width - 1; @@ -2359,6 +2371,222 @@ TEST("rectangle aliasing") { REQUIRE(ok); } +TEST("triangle") { + i64 w = 10; + i64 h = 10; + + vec4_f32 pixels[100] = {0}; + + fill_triangle_to_buffer( + (Pixel_Buffer) { .width = w, .height = h, .stride = w, .pixels = pixels, }, + (vec4_f32) { 1.0f, 1.0f, 1.0f, 1.0f }, + (vec2[3]) { + { 1.0, 1.0 }, + { 5.9, 1.0 }, + { 1.0, 5.9 }, + } + ); + + b8 expect_bits[100] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + b8 ok = 1; + + for (i64 i = 0; i < w * h; ++i) { + if (expect_bits[i] != (pixels[i].x > 0.5) || + expect_bits[i] != (pixels[i].y > 0.5) || + expect_bits[i] != (pixels[i].z > 0.5) || + expect_bits[i] != (pixels[i].w > 0.5)) { + ok = 0; + break; + } + } + + REQUIRE(ok); +} + +TEST("triangles") { + i64 w = 10; + i64 h = 10; + + vec4_f32 pixels[100] = {0}; + + fill_triangles_to_buffer( + (Pixel_Buffer) { .width = w, .height = h, .stride = w, .pixels = pixels, }, + (vec4_f32) { 1.0f, 1.0f, 1.0f, 1.0f }, + (vec2) { 1.0, 1.0 }, + (vec2) { 1.0, 1.0 }, + 2, + (vec2[6]) { + { 0.0, 0.0 }, { 3.1, 0.0 }, { 0.0, 3.1 }, + { 4.1, 0.9 }, { 0.9, 4.1 }, { 4.1, 4.1 }, + } + ); + + b8 expect_bits[100] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + b8 ok = 1; + + for (i64 i = 0; i < w * h; ++i) { + if (expect_bits[i] != (pixels[i].x > 0.5) || + expect_bits[i] != (pixels[i].y > 0.5) || + expect_bits[i] != (pixels[i].z > 0.5) || + expect_bits[i] != (pixels[i].w > 0.5)) { + ok = 0; + break; + } + } + + REQUIRE(ok); +} + +TEST("quad") { + i64 w = 10; + i64 h = 10; + + vec4_f32 pixels[100] = {0}; + + fill_quad_to_buffer( + (Pixel_Buffer) { .width = w, .height = h, .stride = w, .pixels = pixels, }, + (vec4_f32) { 1.0f, 1.0f, 1.0f, 1.0f }, + (vec2[4]) { + { 4.0, 0.9 }, + { 7.1, 4.0 }, + { 4.0, 7.1 }, + { 0.9, 4.0 }, + } + ); + + b8 expect_bits[100] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + b8 ok = 1; + + for (i64 i = 0; i < w * h; ++i) { + if (expect_bits[i] != (pixels[i].x > 0.5) || + expect_bits[i] != (pixels[i].y > 0.5) || + expect_bits[i] != (pixels[i].z > 0.5) || + expect_bits[i] != (pixels[i].w > 0.5)) { + ok = 0; + break; + } + } + + REQUIRE(ok); +} + +TEST("ellipse") { + i64 w = 10; + i64 h = 10; + + vec4_f32 pixels[100] = {0}; + + fill_ellipse_to_buffer( + (Pixel_Buffer) { .width = w, .height = h, .stride = w, .pixels = pixels, }, + (vec4_f32) { 1.0f, 1.0f, 1.0f, 1.0f }, + (Box) { 0.9, 0.9, 9.2, 9.2 } + ); + + b8 expect_bits[100] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, + }; + + b8 ok = 1; + + for (i64 i = 0; i < w * h; ++i) { + if (expect_bits[i] != (pixels[i].x > 0.5) || + expect_bits[i] != (pixels[i].y > 0.5) || + expect_bits[i] != (pixels[i].z > 0.5) || + expect_bits[i] != (pixels[i].w > 0.5)) { + ok = 0; + break; + } + } + + REQUIRE(ok); +} + +TEST("line") { + i64 w = 10; + i64 h = 10; + + vec4_f32 pixels[100] = {0}; + + fill_line_to_buffer( + (Pixel_Buffer) { .width = w, .height = h, .stride = w, .pixels = pixels, }, + (vec4_f32) { 1.0f, 1.0f, 1.0f, 1.0f }, + (vec2[2]) { { 1.0, 1.0 }, { 8.0, 3.0 }, }, + 1.0 + ); + + b8 expect_bits[100] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + b8 ok = 1; + + for (i64 i = 0; i < w * h; ++i) { + if (expect_bits[i] != (pixels[i].x > 0.5) || + expect_bits[i] != (pixels[i].y > 0.5) || + expect_bits[i] != (pixels[i].z > 0.5) || + expect_bits[i] != (pixels[i].w > 0.5)) { + ok = 0; + break; + } + } + + REQUIRE(ok); +} + TEST("text letter A") { i64 w = 10; i64 h = 10; |