From ef779090e858c2f1dcae6bf0fecae23b7753623d Mon Sep 17 00:00:00 2001 From: Sam Nystrom Date: Thu, 15 Feb 2024 07:57:12 -0500 Subject: Add time progress --- Makefile | 2 +- pineapple.c | 56 +++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 78828dc..d922d90 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .POSIX: .SUFFIXES: -CFLAGS = -O2 -Wall -Wextra -pedantic +CFLAGS = -O2 -Wall -Wextra -pedantic -D_POSIX_C_SOURCE=199309L -D_XOPEN_SOURCE LDFLAGS = -static LDLIBS = -lm diff --git a/pineapple.c b/pineapple.c index 772e7b6..5e97901 100644 --- a/pineapple.c +++ b/pineapple.c @@ -9,8 +9,7 @@ #include #include #include - -#define PI 3.14159265358979323846 +#include #define die(code, msg) do { fprintf(stderr, "pineapple: %s\n", msg); exit(code); } while (0) #define diesys(code, msg) do { fprintf(stderr, "pineapple: %s: %s\n", msg, strerror(errno)); exit(code); } while (0) @@ -20,6 +19,8 @@ #define ASCII_CHARS "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. " +static int verbosity = 0; + typedef struct { float x, y, z; } vec3; struct triangle { @@ -77,7 +78,7 @@ magnitude(vec3 v) } static inline vec3 -vnorm(vec3 v) +norm(vec3 v) { float mag = magnitude(v); return (vec3){ v.x / mag, v.y / mag, v.z / mag }; @@ -90,7 +91,7 @@ ray_triangle_intersect(vec3 P, vec3 d, struct triangle tri) vec3 edge2 = vsub(tri.c, tri.a); vec3 ray_cross_e2 = cross(d, edge2); float det = dot(edge1, ray_cross_e2); - if (det > -FLT_EPSILON && det < FLT_EPSILON) return NAN; + if (-FLT_EPSILON < det && det < FLT_EPSILON) return NAN; float inv_det = 1.0 / det; vec3 s = vsub(P, tri.a); float u = inv_det * dot(s, ray_cross_e2); @@ -108,36 +109,50 @@ render_frame(struct camera cam, vec3 light, const struct triangle *triangles, uint32_t len, float *pixels, uint32_t width, uint32_t height) { - for (int h = height - 1; h >= 0; --h) { - for (uint32_t w = 0; w < width; ++w) { + struct timespec start, now; + if (verbosity >= 1) clock_gettime(CLOCK_MONOTONIC, &start); + + light = norm(light); + for (size_t w = 0; w < width; ++w) { + if (verbosity >= 1) { + clock_gettime(CLOCK_MONOTONIC, &now); + int elapsed = now.tv_sec - start.tv_sec; + int total = elapsed * width / (w+1); + fprintf(stderr, "%ld/%d %02d:%02d/%02d:%02d\r", w, width, elapsed / 60, elapsed % 60, total / 60, total % 60); + } + for (size_t h = 0; h < height; ++h) { float theta = cam.theta - cam.fov/2.0 + cam.fov/height*h; float phi = cam.phi - cam.fov/2.0 + cam.fov/width*w; vec3 dir = { sinf(theta) * cosf(phi), sinf(theta) * sinf(phi), cosf(theta) }; - dir = vnorm(dir); + dir = norm(dir); float shortest = INFINITY; - vec3 shortest_norm = {0}; + struct triangle shortest_tri = {0}; for (size_t i = 0; i < len; ++i) { float d = ray_triangle_intersect(cam.pos, dir, triangles[i]); - if (d != NAN && fabs(d) < fabs(shortest)) { + if (d != NAN && d < shortest) { shortest = d; - shortest_norm = triangles[i].n; + shortest_tri = triangles[i]; } } - pixels[w*width + h] = 0.0; + pixels[w*height + h] = 0.0; if (shortest != INFINITY) { - float light_angle = acosf(dot(shortest_norm, light) / magnitude(shortest_norm) / magnitude(light)); - pixels[w*width + h] = light_angle / PI; + float light_angle = acosf(dot(shortest_tri.n, light)); + pixels[w*height + h] = light_angle / M_PI; } } } + if (verbosity >= 1) { + clock_gettime(CLOCK_MONOTONIC, &now); + int elapsed = now.tv_sec - start.tv_sec; + fprintf(stderr, "Rendered in %02d:%02d\n", elapsed / 60, elapsed % 60); + } } int main(int argc, char *argv[]) { - int verbosity = 0; uint32_t width = 80; uint32_t height = 40; enum { ASCII, FARBFELD } mode = ASCII; @@ -169,17 +184,17 @@ main(int argc, char *argv[]) for (size_t i = 0; i < len; ++i) { if (fread(&raw, sizeof(raw), 1, stdin) < 1) diesys(111, "fatal: unable to read STL facets"); - triangles[i] = (struct triangle){ .n = raw.n, .a = raw.a, .b = raw.b, .c = raw.c }; + triangles[i] = (struct triangle){ .n = norm(raw.n), .a = raw.a, .b = raw.b, .c = raw.c }; } if (verbosity >= 1) fprintf(stderr, "finished reading STL: %d facets\n", len); struct camera cam = { .pos = { -70.0, 60.0, 60.0 }, - .phi = PI * 0.8, - .theta = PI * 0.5, - .fov = 80.0 * PI / 180.0 + .phi = M_PI * 0.8, + .theta = M_PI * 0.5, + .fov = 80.0 * M_PI / 180.0 }; - vec3 light = { 0.0, 0.0, -1.0 }; + vec3 light = { 0.0, 0.5, -1.0 }; if (mode == FARBFELD) { uint32_t wbe = htobe32(width); @@ -195,7 +210,7 @@ main(int argc, char *argv[]) for (int h = height - 1; h >= 0; --h) { for (uint32_t w = 0; w < width; ++w) { - float brightness = pixels[w*width + h]; + float brightness = pixels[w*height + h]; if (mode == ASCII) { printf("%c", ASCII_CHARS[strlen(ASCII_CHARS) - 1 - (int)(brightness * strlen(ASCII_CHARS))]); } else if (mode == FARBFELD) { @@ -206,7 +221,6 @@ main(int argc, char *argv[]) } if (mode == ASCII) printf("\n"); } - free(pixels); return 0; } \ No newline at end of file -- cgit v1.2.3