From 60a0cc22a7153ec8947b17d16c2495e5e10abfa9 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Sat, 19 Sep 2020 17:21:26 +0200 Subject: [PATCH 01/10] added benchmark --- bench | Bin 0 -> 33504 bytes bench.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/camera.c | 10 +-- 3 files changed, 180 insertions(+), 9 deletions(-) create mode 100755 bench create mode 100644 bench.c diff --git a/bench b/bench new file mode 100755 index 0000000000000000000000000000000000000000..71ecc549cfaa43ab4c8df6014704b9daa24f4e2a GIT binary patch literal 33504 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 +#include +#include +#include +#include +#include +#include "images/images.h" +#include "marcher.h" + +typedef int bool; +#define true 1 +#define false 0 + +#define BENCH_VERSION "1.0" + + +/* + + Mandelbulb scene object + + Currently cannot be set at a specific location, always resides at origin (0,0,0) + + Color function is just a flat shader, detail is displayed with ambient occlusion + +*/ +double mandelbulb_dist(Point pt, SceneObject *self) { + int iters = self->args[0]; + double power = self->args[1]; + + Point z = pt; + float dr = 1.0; + float r = 0.0; + for (int i = 0; i < iters ; i++) { + r = pt_length(z); + + if (r>2) { + break; + } + + // convert to polar coordinates + float theta = acos(z.z/r); + float phi = atan2(z.y,z.x); + dr = pow(r, power-1.0)*power*dr + 1.0; + + // scale and rotate the point + float zr = pow(r, power); + theta = theta*power; + phi = phi*power; + + // convert back to cartesian coordinates + z = pt_mult(pt_new(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta)), zr); + pt_add(&z, pt); + } + + return 0.5*log(r)*r/dr; + +} + +Color mandelbulb_color(Point hit, Point direction, SceneObject *self) { + return self->color; +} + +// constructs the scene object +SceneObject mandelbulb_new(Point location, int iters, double power) { + SceneObject so; + so.location = location; + so.args = malloc(sizeof(double) * 3); + so.args[0] = iters; // iterations + so.args[1] = power; // power + so.args[2] = -1; // reserved for color calculations + so.distance = mandelbulb_dist; + so.get_color = mandelbulb_color; + so.color = color_new(255,255,255); + return so; +} + +int run_bench(int size, float pow, int threads, const char path[], bool save) { + float cam_position = 1.15; + int steps = 2000; + int iters = 1000; + float threshold = 0.0001; + + Camera cam; + cam.fov = 90; + + camera_set_looking_at(&cam, pt_new(cam_position, cam_position, cam_position), pt_new(0,0,0)); + + // create basic scene with up to 10 objects + Scene scene = scene_new(size, size, 1); + scene.perf_opts.max_steps = steps; + scene.perf_opts.threshold = threshold; + scene.perf_opts.speed_cutoff = 10; + scene.background = color_new(0,0,0); + + scene_add_obj(&scene, mandelbulb_new(pt_new(0,0,0), iters, pow)); + + Image *img = render_scene(&scene, &cam, threads); + + if (save) { + image_save_bmp(*img, path); + } + + image_destroy_shared(*img); + scene_destroy(scene); + + return 0; +} + +struct timer { + struct timeval start; + struct timeval end; + char *name; +}; + +void timer_start(struct timer *t) { + printf("\n\n\nStarting bench %s\n", t->name); + gettimeofday(&t->start, NULL); +} +void timer_end(struct timer *t) { + gettimeofday(&t->end, NULL); +} +void timer_print(struct timer t) { + long time, secs, usecs; + secs = t.end.tv_sec - t.start.tv_sec; + usecs = t.end.tv_usec - t.start.tv_usec; + time = ((secs) * 1000 + usecs/1000.0) + 0.5; + printf("\nBenchmark %s took %ldms (%.2fs)\n", t.name, time, time / 1000.0f); +} + +int main(int argc, char *argv[]) +{ + int threads = get_nprocs(); + struct timer bench; + int size = 1080; + + printf("Mandelbulb Benchmark v%s\n\nDetected %d threads...\n", BENCH_VERSION, threads); + + sleep(2); + + bench.name = "1080px render with saving"; + timer_start(&bench); + run_bench(1080, 3.0, threads, "bench-pow3-1080p.bmp", true); + timer_end(&bench); + timer_print(bench); + + sleep(2); + + bench.name = "1080px render without saving"; + timer_start(&bench); + run_bench(1080, 3.0, threads, "", false); + timer_end(&bench); + timer_print(bench); + + sleep(2); + + bench.name = "10 megapixel render with saving"; + timer_start(&bench); + run_bench(3162, 3.0, threads, "bench-pow3-10mpx.bmp", true); + timer_end(&bench); + timer_print(bench); + + sleep(2); + + bench.name = "40 megapixel render with saving"; + timer_start(&bench); + run_bench(6324, 3.0, threads, "bench-pow3-40mpx.bmp", true); + timer_end(&bench); + timer_print(bench); + + sleep(2); + + bench.name = "1080px render single threaded without saving"; + timer_start(&bench); + run_bench(1080, 3.0, 1, "", false); + timer_end(&bench); + timer_print(bench); + + return 0; +} diff --git a/src/camera.c b/src/camera.c index fd205e4..6cbfd53 100644 --- a/src/camera.c +++ b/src/camera.c @@ -105,11 +105,7 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th // get rotation axis pt_orthogonal_plane(camera.direction, &span_z, &span_xy); - printf("rendering %ix%i px\n", width, height); - - pt_print_n("span_xy", span_xy); - pt_print_n("span_z", span_z); - + printf("rendering %ix%ipx\n", width, height); // distance each ray has from anothe on the ortogonal plane double step_dist = 2 / (double) (width - 1); @@ -118,7 +114,6 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th Point move_right = pt_scale(span_xy, step_dist); Point move_up = pt_scale(span_z, step_dist);; - printf("step: %f\n", step_dist); // set starting point Point starting_point = pt_normalize(camera.direction); @@ -161,7 +156,6 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th } if (thread_id != 0) { - printf("Thread %i is finished\n", thread_id); exit(0); } @@ -169,6 +163,4 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th for (int i = 0; i < threads - 1; i++) { while(wait(&status) > 0) {} } - - printf("got threads\n"); } \ No newline at end of file -- 2.40.1 From dc023e5c695128dba739609096fadd0809bfddf9 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Sat, 19 Sep 2020 17:23:13 +0200 Subject: [PATCH 02/10] updated images lib --- images | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images b/images index e20f4cb..329520d 160000 --- a/images +++ b/images @@ -1 +1 @@ -Subproject commit e20f4cb891ae1f6ac34f7572ea6847957b7195db +Subproject commit 329520da739f07aded44841eb1b5de6e5903a425 -- 2.40.1 From 1d8b4fa7c4afb66ecd48dfef2de6080baad8ed50 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Sat, 19 Sep 2020 18:06:02 +0200 Subject: [PATCH 03/10] fixed git module --- .gitmodules | 2 +- bench | Bin 33504 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100755 bench diff --git a/.gitmodules b/.gitmodules index 3c9ded2..bb3729c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "images"] path = images - url = gitlab@git.datenvorr.at:anton/images.h.git + url = https://git.datenvorr.at/anton/images.h.git diff --git a/bench b/bench deleted file mode 100755 index 71ecc549cfaa43ab4c8df6014704b9daa24f4e2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33504 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 Date: Sat, 19 Sep 2020 18:30:10 +0200 Subject: [PATCH 04/10] added header to point.c --- src/point.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/point.c b/src/point.c index 1324312..e4ba7a7 100644 --- a/src/point.c +++ b/src/point.c @@ -1,3 +1,4 @@ +#include "../marcher.h" #include #include -- 2.40.1 From 19292274a8b24a1a3a4d8299ba1c3e7cbd972fbf Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Sat, 19 Sep 2020 18:42:00 +0200 Subject: [PATCH 05/10] removed some newlines --- bench.c | 2 +- src/camera.c | 2 -- src/point.c | 1 - src/scene.c | 2 -- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/bench.c b/bench.c index 392a85e..cc9442c 100644 --- a/bench.c +++ b/bench.c @@ -113,7 +113,7 @@ struct timer { }; void timer_start(struct timer *t) { - printf("\n\n\nStarting bench %s\n", t->name); + printf("\nStarting bench %s\n", t->name); gettimeofday(&t->start, NULL); } void timer_end(struct timer *t) { diff --git a/src/camera.c b/src/camera.c index 6cbfd53..33a24f2 100644 --- a/src/camera.c +++ b/src/camera.c @@ -1,9 +1,7 @@ -#include "../marcher.h" #include #include #include - Camera camera_new(Point direction, unsigned int fov) { Camera camera; camera.location = pt_new(0,0,0); diff --git a/src/point.c b/src/point.c index e4ba7a7..1324312 100644 --- a/src/point.c +++ b/src/point.c @@ -1,4 +1,3 @@ -#include "../marcher.h" #include #include diff --git a/src/scene.c b/src/scene.c index 6b08202..d5525fa 100644 --- a/src/scene.c +++ b/src/scene.c @@ -1,6 +1,4 @@ -#include "../marcher.h" #include "../images/images.h" - #include static Image* current_image; -- 2.40.1 From 4ed2c6dd08643b212b9c3338685c7181a8206e68 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Sun, 8 May 2022 16:15:49 +0200 Subject: [PATCH 06/10] refactored most of the code --- .gitignore | 3 +- .idea/.gitignore | 8 ++ .idea/modules.xml | 8 ++ .idea/raymarcher.iml | 8 ++ .idea/vcs.xml | 7 ++ Makefile | 27 +++++++ main.c => marcher.c | 89 ++++++++++++----------- marcher.h | 97 ------------------------- src/camera.c | 115 ++++++----------------------- src/camera.h | 11 +++ src/point.c | 169 ++++++++++++------------------------------- src/point.h | 25 +++++++ src/scene.c | 51 +++++++------ src/scene.h | 52 +++++++++++++ 14 files changed, 294 insertions(+), 376 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/raymarcher.iml create mode 100644 .idea/vcs.xml create mode 100644 Makefile rename main.c => marcher.c (56%) delete mode 100644 marcher.h create mode 100644 src/camera.h create mode 100644 src/point.h create mode 100644 src/scene.h diff --git a/.gitignore b/.gitignore index 877906e..bf48f6c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.bmp *.png *.out -out/ \ No newline at end of file +obj +out diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7a8cdab --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/raymarcher.iml b/.idea/raymarcher.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/.idea/raymarcher.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..46bff8d --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..57b4a0b --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ + + +OPTIMIZATION=-O3 +CC=gcc +CFLAGS=-Isrc/ -lm -Wall -Wextra -pedantic-errors $(OPTIMIZATION) + +.PHONY: directories + +directories: + mkdir -p obj out + +obj/point.o: src/point.c src/point.h + $(CC) $(CFLAGS) -c -o $@ src/point.c + +obj/scene.o: src/scene.c src/scene.h + $(CC) $(CFLAGS) -c -o $@ src/scene.c + +obj/camera.o: src/camera.c src/camera.h + $(CC) $(CFLAGS) -c -o $@ src/camera.c + +obj/images.o: images/src/images.c images/src/images.h + $(CC) $(CFLAGS) -c -o $@ images/src/images.c + + +march: obj/camera.o obj/scene.o obj/point.o obj/images.o + $(CC) $(CFLAGS) -o out/march $^ marcher.c + diff --git a/main.c b/marcher.c similarity index 56% rename from main.c rename to marcher.c index 685501d..c32562b 100644 --- a/main.c +++ b/marcher.c @@ -1,6 +1,10 @@ #include -#include "images/images.h" -#include "marcher.h" +#include +#include +#include "images/src/images.h" +#include "src/scene.h" +#include "src/camera.h" +#include "src/point.h" #define SCENE_MOD 2 @@ -15,15 +19,15 @@ */ -double circle_dist(Point x, SceneObject *self) { +double circle_dist(struct point x, struct scene_object *self) { double r = self->args[0]; return pt_dist(pt_mod(x, SCENE_MOD), self->location) - r; } -Color circle_color(Point hit, Point direction, SceneObject *self) { - Point obj_direction = self->location; +Color circle_color(struct point hit, struct point direction, struct scene_object *self) { + struct point obj_direction = self->location; - pt_sub(&obj_direction, pt_mod(hit, SCENE_MOD)); + obj_direction = pt_sub(obj_direction, pt_mod(hit, SCENE_MOD)); double angle = pt_angle(direction, obj_direction) / M_PI * 180; Color color = self->color; @@ -34,15 +38,16 @@ Color circle_color(Point hit, Point direction, SceneObject *self) { return color; } // constructs the scene object -SceneObject circle_new(Point loc, double radius) { - SceneObject so; - so.location = loc; - so.args = malloc(sizeof(double) * 2); - so.args[0] = radius; - so.distance = circle_dist; - so.get_color = circle_color; - so.color = color_new(255,255,255); - return so; +struct scene_object circle_new(struct point loc, double radius) { + double * args = malloc(sizeof (double) * 2); + args[0] = radius; + return (struct scene_object) { + .location = loc, + .args = args, + .distance = circle_dist, + .get_color = circle_color, + .color = color_new(255, 255, 255), + }; } @@ -55,11 +60,11 @@ SceneObject circle_new(Point loc, double radius) { Color function is just a flat shader, detail is displayed with ambient occlusion */ -double mandelbulb_dist(Point pt, SceneObject *self) { +double mandelbulb_dist(struct point pt, struct scene_object *self) { int iters = self->args[0]; double power = self->args[1]; - Point z = pt; + struct point z = pt; float dr = 1.0; float r = 0.0; for (int i = 0; i < iters ; i++) { @@ -79,39 +84,43 @@ double mandelbulb_dist(Point pt, SceneObject *self) { theta = theta*power; phi = phi*power; - // convert back to cartesian coordinates - z = pt_mult(pt_new(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta)), zr); - pt_add(&z, pt); + // convert back to cartesian coordinates, add zr and the old pt + z = (struct point) { + .x = sin(theta)*cos(phi) * zr + pt.x, + .y = sin(phi)*sin(theta) * zr + pt.y, + .z = cos(theta) * zr + pt.z + }; } return 0.5*log(r)*r/dr; - } -Color mandelbulb_color(Point hit, Point direction, SceneObject *self) { +Color mandelbulb_color(struct point hit, struct point direction, struct scene_object *self) { return self->color; } // constructs the scene object -SceneObject mandelbulb_new(Point location, int iters, double power) { - SceneObject so; - so.location = location; - so.args = malloc(sizeof(double) * 3); - so.args[0] = iters; // iterations - so.args[1] = power; // power - so.args[2] = -1; // reserved for color calculations - so.distance = mandelbulb_dist; - so.get_color = mandelbulb_color; - so.color = color_new(255,255,255); - return so; +struct scene_object mandelbulb_new(struct point location, int iters, double power) { + double * args = malloc(sizeof(double) * 3); + args[0] = iters; + args[1] = power; + args[2] = -1; + + return (struct scene_object) { + .location= location, + .args= args, + .distance= mandelbulb_dist, + .get_color= mandelbulb_color, + .color= color_new(255,255,255), + }; } int main(int argc, char* argv[]) { - float dpi = 800; + float dpi = 200; int threads = 32; int size = dpi * 27.56f; // 400dpi by 70cm size float pow = 3; - float cam_position = 1.15; + float cam_position = 1.35; int steps = 1000; int iters = 500; float threshold = 0.001; @@ -131,15 +140,13 @@ int main(int argc, char* argv[]) { printf("Rendering to %s\n", path); - Camera cam; + struct camera cam; cam.fov = 90; - camera_set_looking_at(&cam, pt_new(cam_position, cam_position, cam_position), pt_new(0,0,0)); - - + camera_set_looking_at(&cam, (struct point){.x=cam_position, .y= 0, .z = cam_position}, PT_ZERO); // create basic scene with up to 10 objects - Scene scene = scene_new(size, size, 1); + struct scene scene = scene_new(size, size, 1); scene.perf_opts.max_steps = steps; scene.perf_opts.threshold = threshold; scene.perf_opts.speed_cutoff = 10; @@ -147,7 +154,7 @@ int main(int argc, char* argv[]) { //scene_add_obj(&scene, circle_new(pt_new(SCENE_MOD / 2.0, SCENE_MOD/ 2.0, SCENE_MOD / 2.0), .2)); - scene_add_obj(&scene, mandelbulb_new(pt_new(0,0,0), iters, pow)); + scene_add_obj(&scene, mandelbulb_new(PT_ZERO, iters, pow)); Image *img = render_scene(&scene, &cam, threads); diff --git a/marcher.h b/marcher.h deleted file mode 100644 index acc539a..0000000 --- a/marcher.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef __MARCHER_H__ -#define __MARCHER_H__ - -#include "images/images.h" - -// define pi if not available -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -struct __myvec; -struct __mymtrx; -struct __mycam; -struct __myobject; -struct __myscene; - -typedef struct __myvec { - double x; - double y; - double z; -} Point; - -typedef struct __mymtrx { - double entries[9]; -} Matrix; - -inline Point pt_new(double x, double y, double z); -inline Point pt_scale(Point pt, double length); -inline Point pt_normalize(Point pt); -inline double pt_length(Point pt); -inline void pt_add(Point* pt, Point add); -inline void pt_sub(Point* pt, Point sub); -inline double pt_dist(Point p1, Point p2); -inline Point pt_mod(Point pt, double mod); -inline double pt_dot(Point a, Point b); -inline Point pt_cross(Point a, Point b); -inline double pt_angle(Point a, Point b); -inline void pt_print(Point pt); -inline void pt_print_n(const char* name, Point pt); - - -typedef struct __mycam { - Point location; - Point direction; - unsigned int fov; -} Camera; - -Camera camera_new(Point direction, unsigned int fov); -void camera_set_looking_at(Camera *cam, Point origin, Point thing); - -// Scene objects have a position, some args, and a distance calculation function -// the distance calc function has the following signature: -// double distanceTo(Point myLocation, double * myArgs, Point externalPoint) -// where myLocation is this.location, myArgs is this.args and externalPoint is the point from wich we want to know the distance -// the get_color function takes args: point_hit, direction_hit, myArgs, MyLocation, MyColor -typedef struct __myobject { - Point location; - double * args; - double (*distance)(Point, struct __myobject *); - Color (*get_color)(Point, Point, struct __myobject *); - Color color; - struct __myscene* scene; -} SceneObject; - - -typedef struct __perfopts { - int speed_cutoff; - int max_steps; - double threshold; -} PerformanceOptimizations; - - -typedef struct __myscene { - unsigned int width; - unsigned int height; - SceneObject * objects; - int object_count; - int allocated_space; - // performance opts - PerformanceOptimizations perf_opts; - // colors etc - Color background; -} Scene; - -Image* render_scene(Scene *scene, Camera *camera, unsigned int threads); - -Scene scene_new(unsigned int width, unsigned int height, int obj_count); - -void scene_add_obj(Scene* scene, SceneObject object); - -void scene_destroy(Scene scene); - -#include "src/point.c" -#include "src/camera.c" -#include "src/scene.c" - -#endif \ No newline at end of file diff --git a/src/camera.c b/src/camera.c index 33a24f2..54a493b 100644 --- a/src/camera.c +++ b/src/camera.c @@ -1,10 +1,18 @@ #include #include #include - -Camera camera_new(Point direction, unsigned int fov) { - Camera camera; - camera.location = pt_new(0,0,0); +#include +#include +#include "point.h" +#include "camera.h" + +struct camera camera_new(struct point direction, unsigned int fov) { + struct camera camera; + camera.location = (struct point) { + .x = 0, + .y = 0, + .z = 0 + }; camera.fov = fov; // normalize camera direction @@ -13,92 +21,17 @@ Camera camera_new(Point direction, unsigned int fov) { return camera; } -void camera_set_looking_at(Camera *cam, Point origin, Point thing) { +void camera_set_looking_at(struct camera *cam, struct point origin, struct point thing) { cam->location = origin; - pt_sub(&thing, origin); - cam->direction = pt_normalize(thing); + cam->direction = pt_normalize(pt_sub(thing, origin)); } -void camera_iterate_rays_const_angle(Camera camera, int width, int height, int threads, void (*callback)(Point, int, int)) { - // negative threads => single threaded. - if (threads < 0) threads = 0; - - Point span_z, span_xy; - - // get rotation axis - pt_orthogonal_plane(camera.direction, &span_z, &span_xy); - - printf("rendering %ix%i px", width, height); - - pt_print_n("span_xy", span_xy); - pt_print_n("span_z", span_z); - - // angle between rays - double angle_step = camera.fov / (double) (width - 1); - - // rotation applied to reach the outmost end of the view - double angle_start_h = - (camera.fov / 2.0); - double angle_start_v = ((angle_step * (height - 1)) / 2) ; - - printf("step: %f\nstart_h: %f\nstart_v: %f\n", angle_step, angle_start_h, angle_start_v); - - // calculate both rotation matrices (expensive!) - Matrix rot_z = mtrx_rotation(span_z, angle_step); - Matrix rot_xy = mtrx_rotation(span_xy, -angle_step); - - // rotate vector to starting location (bot left of screen) - // (very expensive!) - Point starting_point = mtrx_mult( - mtrx_rotation(span_xy, angle_start_v), - mtrx_mult( - mtrx_rotation(span_z, angle_start_h), - camera.direction - ) - ); - - // initialize threads - int thread_id = 0; - for (int i = 0; i < threads - 1; i++) { - if (fork() == 0) { - thread_id = i + 1; - break; - } - } - - // this point is rotated for every pixel - Point curr_pt = starting_point; - // (0,0) screenspace is bottom left corner - for (int y = 0; y < height; y++) { - curr_pt = mtrx_mult(rot_xy, starting_point); - // move starting point one row down - starting_point = curr_pt; - - if (y % threads != thread_id) continue; - - for (int x = 0; x < width; x++) { - callback(curr_pt, x, y); - curr_pt = mtrx_mult(rot_z, curr_pt); // rotate point - } - } - - if (thread_id != 0) { - printf("Thread %i is finished\n", thread_id); - exit(0); - } - - int status; - for (int i = 0; i < threads - 1; i++) { - while(wait(&status) > 0) {} - } - - printf("got threads\n"); -} -void camera_iterate_rays_const_dist(Camera camera, int width, int height, int threads, void (*callback)(Point, int, int)) { +void camera_iterate_rays_const_dist(struct camera camera, int width, int height, int threads, void (*callback)(struct point, int, int)) { // negative threads => single threaded. if (threads < 0) threads = 0; - Point span_z, span_xy; + struct point span_z, span_xy; // get rotation axis pt_orthogonal_plane(camera.direction, &span_z, &span_xy); @@ -109,15 +42,15 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th double step_dist = 2 / (double) (width - 1); // vectors to move on the projection plane - Point move_right = pt_scale(span_xy, step_dist); - Point move_up = pt_scale(span_z, step_dist);; + struct point move_right = pt_scale(span_xy, step_dist); + struct point move_up = pt_scale(span_z, step_dist);; // set starting point - Point starting_point = pt_normalize(camera.direction); + struct point starting_point = pt_normalize(camera.direction); // rotate starting point to (0,0) - pt_add(&starting_point, pt_mult(move_right, - width / (double) 2)); - pt_add(&starting_point, pt_mult(move_up, - height / (double) 2)); + starting_point = pt_add(starting_point, pt_mult(move_right, - width / (double) 2)); + starting_point = pt_add(starting_point, pt_mult(move_up, - height / (double) 2)); // initialize threads int thread_id = 0; @@ -129,12 +62,12 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th } // this point is moved for every pixel - Point curr_pt = starting_point; + struct point curr_pt = starting_point; // (0,0) screenspace is bottom left corner for (int y = 0; y < height; y++) { // move one row up (this has to be done in every thread!) - pt_add(&starting_point, move_up); + starting_point = pt_add(starting_point, move_up); // only render the lines this thread is responsible for if (y % threads != thread_id) continue; @@ -149,7 +82,7 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th curr_pt = starting_point; for (int x = 0; x < width; x++) { callback(curr_pt, x, y); - pt_add(&curr_pt, move_right); // move pt right to next pt + curr_pt = pt_add(curr_pt, move_right); // move pt right to next pt } } diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 0000000..b766c3f --- /dev/null +++ b/src/camera.h @@ -0,0 +1,11 @@ +#pragma once + +struct camera { + struct point location; + struct point direction; + unsigned int fov; +}; + +struct camera camera_new(struct point direction, unsigned int fov); +void camera_set_looking_at(struct camera *cam, struct point origin, struct point thing); +void camera_iterate_rays_const_dist(struct camera camera, int width, int height, int threads, void (*callback)(struct point, int, int)); \ No newline at end of file diff --git a/src/point.c b/src/point.c index 1324312..219a70c 100644 --- a/src/point.c +++ b/src/point.c @@ -1,35 +1,27 @@ #include #include - -// basically a vector3 -inline Point pt_new(double x, double y, double z) { - Point pt; - pt.x = x; - pt.y = y; - pt.z = z; - return pt; -} +#include "point.h" // scale vector to length -inline Point pt_scale(Point pt, double length) { +struct point pt_scale(struct point pt, double length) { double f = length / pt_length(pt); - return pt_new( - pt.x * f, - pt.y * f, - pt.z * f - ); + return (struct point) { + .x = pt.x * f, + .y = pt.y * f, + .z = pt.z * f + }; } -inline Point pt_mult(Point pt, double scalar) { - return pt_new( - pt.x * scalar, - pt.y * scalar, - pt.z * scalar - ); +struct point pt_mult(struct point pt, double scalar) { + return (struct point) { + .x = pt.x * scalar, + .y = pt.y * scalar, + .z = pt.z * scalar + }; } // return internal angle between a and b -inline double pt_angle(Point a, Point b) { +double pt_angle(struct point a, struct point b) { return acos(pt_dot( pt_normalize(a), pt_normalize(b) @@ -37,144 +29,77 @@ inline double pt_angle(Point a, Point b) { } // get the length of vector -inline double pt_length(Point pt) { +double pt_length(struct point pt) { return sqrt((pt.x * pt.x) + (pt.y * pt.y) + (pt.z * pt.z)); } // add the vector add to the vector pt -inline void pt_add(Point* pt, Point add) { - pt->x = pt->x + add.x; - pt->y = pt->y + add.y; - pt->z = pt->z + add.z; +struct point pt_add(struct point pt, struct point add) { + return (struct point) { + .x = pt.x + add.x, + .y = pt.y + add.y, + .z = pt.z + add.z, + }; } // add the vector add to the vector pt -inline void pt_sub(Point* pt, Point sub) { - pt->x -= sub.x; - pt->y -= sub.y; - pt->z -= sub.z; +struct point pt_sub(struct point pt, struct point sub) { + return (struct point) { + .x = pt.x - sub.x, + .y = pt.y - sub.y, + .z = pt.z - sub.z, + }; } -inline double pt_dist(Point p1, Point p2) { - pt_sub(&p1, p2); - return pt_length(p1); +double pt_dist(struct point p1, struct point p2) { + return pt_length(pt_sub(p1, p2)); } // normalize a vector -inline Point pt_normalize(Point pt) { +struct point pt_normalize(struct point pt) { return pt_scale(pt, 1); } // dot product of two vectors -inline double pt_dot(Point a, Point b) { +double pt_dot(struct point a, struct point b) { return a.x*b.x + a.y*b.y + a.z*b.z; } // cross product of two vectors -inline Point pt_cross(Point a, Point b) { - return pt_new( - a.y*b.z - a.z*b.y, - a.z*b.x - a.x*b.z, - a.x*b.y - a.y*b.x - ); +struct point pt_cross(struct point a, struct point b) { + return (struct point) { + .x = a.y*b.z - a.z*b.y, + .y = a.z*b.x - a.x*b.z, + .z = a.x*b.y - a.y*b.x + }; } -inline void pt_print(Point pt) { +void pt_print(struct point pt) { printf("(%f, %f, %f)\n", pt.x, pt.y, pt.z); } -inline void pt_print_n(const char* name, Point pt) { +void pt_print_n(const char* name, struct point pt) { printf("%s: (%f, %f, %f)\n", name, pt.x, pt.y, pt.z); } // find two vectors that span the orthogonal plane, where // span_xy is a vector lying on the xy-plane (and pointing left) // and span_z is orthogonal to span_xy pointing "upwards" -void pt_orthogonal_plane(Point pt, Point *span_z, Point *span_xy) { +void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy) { pt = pt_normalize(pt); // get the vector lying on the xy axis // this is done by - *span_xy = pt_normalize(pt_cross(pt_new(0,0,1), pt)); // points to the "left" (of the viewing direction) + *span_xy = pt_normalize(pt_cross((struct point){.x = 0, .y = 0, .z = 1}, pt)); // points to the "left" (of the viewing direction) // now use this, to find the vector *span_z = pt_normalize(pt_cross(pt, *span_xy)); } -inline Point pt_mod(Point pt, double mod) { - return pt_new( - fabs(fmod(pt.x, mod)), - fabs(fmod(pt.y, mod)), - fabs(fmod(pt.z, mod)) - ); -} - - -/////////////////////////////// -////// Matrix operations ////// -/////////////////////////////// - - -/* create a new matrix with entries: - x1 x2 x3 - y1 y2 y3 - z1 z2 z3 -*/ -inline Matrix mtrx_new(double x1, double x2, double x3, - double y1, double y2, double y3, - double z1, double z2, double z3) -{ - Matrix m; - m.entries[0] = x1; - m.entries[1] = y1; - m.entries[2] = z1; - m.entries[3] = x2; - m.entries[4] = y2; - m.entries[5] = z2; - m.entries[6] = x3; - m.entries[7] = y3; - m.entries[8] = z3; - return m; -} - -inline Point mtrx_mult(Matrix mtrx, Point pt) { - Point result; - - double *m = mtrx.entries; - - result.x = m[0] * pt.x + m[3] * pt.y + m[6] * pt.z; - result.y = m[1] * pt.x + m[4] * pt.y + m[7] * pt.z; - result.z = m[2] * pt.x + m[5] * pt.y + m[8] * pt.z; - - return result; -} - -// create a rotation matrix around an axis given by the normalized axis vector (u) -// taken from https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle -Matrix mtrx_rotation(Point u, double theta) { - double theta_rad = theta * (M_PI / 180); - double cost = cos(theta_rad); - double sint = sin(theta_rad); - - return mtrx_new( - cost+u.x*u.x*(1-cost), u.x*u.y*(1-cost)-u.z*sint, u.x*u.z*(1-cost)+u.y*sint, - u.y*u.x*(1-cost)+u.z*sint, cost+u.y*u.y*(1-cost), u.y*u.z*(1-cost)-u.x*sint, - u.z*u.x*(1-cost)-u.y*sint, u.z*u.y*(1-cost)+u.x*sint, cost+u.z*u.z*(1-cost) - ); -} - -void mtrx_print(Matrix mtrx) { - printf(" %8.2f %8.2f %8.2f\n %8.2f %8.2f %8.2f\n %8.2f %8.2f %8.2f\n", - mtrx.entries[0], mtrx.entries[3], mtrx.entries[6], - mtrx.entries[1], mtrx.entries[4], mtrx.entries[7], - mtrx.entries[2], mtrx.entries[5], mtrx.entries[8] - ); -} - -inline Matrix mtrx_outer_prod(Point a, Point b) { - return mtrx_new( - a.x*b.x, a.x*b.y, a.x*b.z, - a.y*b.x, a.y*b.y, a.y*b.z, - a.z*b.x, a.z*b.y, a.z*b.z - ); +struct point pt_mod(struct point pt, double mod) { + return (struct point) { + .x = fabs(fmod(pt.x, mod)), + .y = fabs(fmod(pt.y, mod)), + .z = fabs(fmod(pt.z, mod)) + }; } \ No newline at end of file diff --git a/src/point.h b/src/point.h new file mode 100644 index 0000000..69cb378 --- /dev/null +++ b/src/point.h @@ -0,0 +1,25 @@ +#pragma once + + +struct point { + double x; + double y; + double z; +}; + +#define PT_ZERO ((struct point) {.x=0, .y=0, .z=0}) + +struct point pt_scale(struct point pt, double length); +struct point pt_normalize(struct point pt); +struct point pt_mult(struct point pt, double scalar); +double pt_length(struct point pt); +struct point pt_add(struct point pt, struct point add); +struct point pt_sub(struct point pt, struct point sub); +double pt_dist(struct point p1, struct point p2); +struct point pt_mod(struct point pt, double mod); +double pt_dot(struct point a, struct point b); +struct point pt_cross(struct point a, struct point b); +double pt_angle(struct point a, struct point b); +void pt_print(struct point pt); +void pt_print_n(const char* name, struct point pt); +void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy); diff --git a/src/scene.c b/src/scene.c index d5525fa..bad4222 100644 --- a/src/scene.c +++ b/src/scene.c @@ -1,34 +1,37 @@ -#include "../images/images.h" +#include "../images/src/images.h" +#include "scene.h" +#include "camera.h" +#include "point.h" #include +#include static Image* current_image; -static Scene* current_scene; -static Camera* current_camera; +static struct scene* current_scene; +static struct camera* current_camera; -Color march_ray(Point origin, Point direction, Scene* scene); -void camera_iter_callback(Point direction, int x, int y); +Color march_ray(struct point origin, struct point direction, struct scene* scene); +void camera_iter_callback(struct point direction, int x, int y); -Scene scene_new(unsigned int width, unsigned int height, int obj_count) { - Scene scene; +struct scene scene_new(unsigned int width, unsigned int height, int obj_count) { + struct scene scene; scene.height = height; scene.width = width; scene.object_count = 0; - scene.objects = malloc(obj_count * sizeof(SceneObject)); + scene.objects = malloc(obj_count * sizeof(struct scene_object)); scene.allocated_space = obj_count; scene.background = color_new(0,0,0); - PerformanceOptimizations perf_opts; - perf_opts.speed_cutoff = 0; - perf_opts.max_steps = 32; - perf_opts.threshold = 0.02; - - scene.perf_opts = perf_opts; + scene.perf_opts = (struct performance_optimization) { + .speed_cutoff = 0, + .max_steps = 32, + .threshold = 0.02 + }; return scene; } -void scene_add_obj(Scene* scene, SceneObject object) { +void scene_add_obj(struct scene * scene, struct scene_object object) { if (scene->object_count >= scene->allocated_space) return; // limit reached // TODO realloc @@ -42,7 +45,7 @@ void scene_add_obj(Scene* scene, SceneObject object) { // render out the scene with threads // creates a shared image, so destroy with image_destroy_shared then free struct with free_shared_memory -Image* render_scene(Scene *scene, Camera *camera, unsigned int threads) { +Image* render_scene(struct scene *scene, struct camera *camera, unsigned int threads) { current_image = malloc(sizeof(Image)); current_scene = scene; current_camera= camera; @@ -59,20 +62,20 @@ Image* render_scene(Scene *scene, Camera *camera, unsigned int threads) { } // march the ray, set the color. repeated for each direction generated by the camera -void camera_iter_callback(Point direction, int x, int y) { +void camera_iter_callback(struct point direction, int x, int y) { Color c = march_ray(current_camera->location, direction, current_scene); image_set_px_c(*current_image, x, y, c); } -Color march_ray(Point origin, Point direction, Scene* scene) { +Color march_ray(struct point origin, struct point direction, struct scene* scene) { // some local variables - Point pos = origin; + struct point pos = origin; double closest_encounter = DBL_MAX; double dist = closest_encounter; // the closest object we have - SceneObject* closest_obj = scene->objects; + struct scene_object* closest_obj = scene->objects; // get steps, threshold from scene int steps = scene->perf_opts.max_steps; @@ -86,7 +89,7 @@ Color march_ray(Point origin, Point direction, Scene* scene) { // find distance to closest object for(int i = 0; i < scene->object_count; i++) { // get pointer to scene obj - SceneObject* obj = scene->objects + i; + struct scene_object* obj = scene->objects + i; double curr_dist = scene->objects[i].distance(pos, obj); // if we are close @@ -104,8 +107,8 @@ Color march_ray(Point origin, Point direction, Scene* scene) { if (dist < closest_encounter) closest_encounter = dist; // scale direction vector to distance, then add it to our position - Point step_vector = pt_scale(direction, dist); - pt_add(&pos, step_vector); + struct point step_vector = pt_scale(direction, dist); + pos = pt_add(pos, step_vector); // one step taken... steps--; @@ -135,7 +138,7 @@ Color march_ray(Point origin, Point direction, Scene* scene) { } } -void scene_destroy(Scene scene) { +void scene_destroy(struct scene scene) { for (int i = 0; i < scene.object_count; i++) { // free args memory free(scene.objects[i].args); diff --git a/src/scene.h b/src/scene.h new file mode 100644 index 0000000..eacad6c --- /dev/null +++ b/src/scene.h @@ -0,0 +1,52 @@ +#pragma once + +#include "point.h" +#include "camera.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +struct scene; + +// Scene objects have a position, some args, and a distance calculation function +// the distance calc function has the following signature: +// double distanceTo(struct point myLocation, double * myArgs, struct point externalPoint) +// where myLocation is this.location, myArgs is this.args and externalPoint is the point from wich we want to know the distance +// the get_color function takes args: point_hit, direction_hit, myArgs, MyLocation, MyColor +struct scene_object { + struct point location; + double * args; + double (*distance)(struct point, struct scene_object *); + Color (*get_color)(struct point, struct point, struct scene_object *); + Color color; + struct scene* scene; +}; + + +struct performance_optimization { + int speed_cutoff; + int max_steps; + double threshold; +}; + + +struct scene { + unsigned int width; + unsigned int height; + struct scene_object * objects; + int object_count; + int allocated_space; + // performance opts + struct performance_optimization perf_opts; + // colors etc + Color background; +}; + +Image* render_scene(struct scene *scene, struct camera *camera, unsigned int threads); + +struct scene scene_new(unsigned int width, unsigned int height, int obj_count); + +void scene_add_obj(struct scene* scene, struct scene_object object); + +void scene_destroy(struct scene scene); \ No newline at end of file -- 2.40.1 From 693f00e113447a4ea30deeb492ba73494144ffb4 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Sun, 8 May 2022 16:38:29 +0200 Subject: [PATCH 07/10] bench also working --- Makefile | 2 ++ bench.c | 33 ++++++++++++++++++++------------- images | 2 +- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 57b4a0b..273fe2f 100644 --- a/Makefile +++ b/Makefile @@ -25,3 +25,5 @@ obj/images.o: images/src/images.c images/src/images.h march: obj/camera.o obj/scene.o obj/point.o obj/images.o $(CC) $(CFLAGS) -o out/march $^ marcher.c +bench: obj/camera.o obj/scene.o obj/point.o obj/images.o + $(CC) $(CFLAGS) -o out/bench $^ bench.c diff --git a/bench.c b/bench.c index cc9442c..20bc774 100644 --- a/bench.c +++ b/bench.c @@ -2,10 +2,14 @@ #include #include #include +#include #include #include -#include "images/images.h" -#include "marcher.h" +#include "images/src/images.h" +#include "src/scene.h" +#include "src/camera.h" +#include "src/point.h" + typedef int bool; #define true 1 @@ -23,11 +27,11 @@ typedef int bool; Color function is just a flat shader, detail is displayed with ambient occlusion */ -double mandelbulb_dist(Point pt, SceneObject *self) { +double mandelbulb_dist(struct point pt, struct scene_object *self) { int iters = self->args[0]; double power = self->args[1]; - Point z = pt; + struct point z = pt; float dr = 1.0; float r = 0.0; for (int i = 0; i < iters ; i++) { @@ -48,21 +52,24 @@ double mandelbulb_dist(Point pt, SceneObject *self) { phi = phi*power; // convert back to cartesian coordinates - z = pt_mult(pt_new(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta)), zr); - pt_add(&z, pt); + z = (struct point) { + .x = sin(theta)*cos(phi) * zr + pt.x, + .y = sin(phi)*sin(theta) * zr + pt.y, + .z = cos(theta) * zr + pt.z + }; } return 0.5*log(r)*r/dr; } -Color mandelbulb_color(Point hit, Point direction, SceneObject *self) { +Color mandelbulb_color(struct point hit, struct point direction, struct scene_object *self) { return self->color; } // constructs the scene object -SceneObject mandelbulb_new(Point location, int iters, double power) { - SceneObject so; +struct scene_object mandelbulb_new(struct point location, int iters, double power) { + struct scene_object so; so.location = location; so.args = malloc(sizeof(double) * 3); so.args[0] = iters; // iterations @@ -80,19 +87,19 @@ int run_bench(int size, float pow, int threads, const char path[], bool save) { int iters = 1000; float threshold = 0.0001; - Camera cam; + struct camera cam; cam.fov = 90; - camera_set_looking_at(&cam, pt_new(cam_position, cam_position, cam_position), pt_new(0,0,0)); + camera_set_looking_at(&cam, (struct point){.x = cam_position, .y = cam_position, .z = cam_position}, PT_ZERO); // create basic scene with up to 10 objects - Scene scene = scene_new(size, size, 1); + struct scene scene = scene_new(size, size, 1); scene.perf_opts.max_steps = steps; scene.perf_opts.threshold = threshold; scene.perf_opts.speed_cutoff = 10; scene.background = color_new(0,0,0); - scene_add_obj(&scene, mandelbulb_new(pt_new(0,0,0), iters, pow)); + scene_add_obj(&scene, mandelbulb_new(PT_ZERO, iters, pow)); Image *img = render_scene(&scene, &cam, threads); diff --git a/images b/images index 329520d..a71e319 160000 --- a/images +++ b/images @@ -1 +1 @@ -Subproject commit 329520da739f07aded44841eb1b5de6e5903a425 +Subproject commit a71e319fb4929135d51e4585a334643c194f5196 -- 2.40.1 From f420c39a4a1b0733158f0d51b7f2fe6fc456c853 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Fri, 20 May 2022 20:42:59 +0200 Subject: [PATCH 08/10] cleaned up a lot of code, but sadly no real speed up yet. Plan on debugging and fine-tuning later tho --- .idea/misc.xml | 4 ++ .idea/raymarcher.iml | 8 --- Makefile | 5 +- bench.c | 39 +++++++------- marcher.c | 2 +- src/camera.c | 119 +++++++++++++++++++++++++++++++------------ src/camera.h | 2 +- src/point.c | 65 +++++++++++++---------- src/point.h | 1 + src/scene.c | 2 +- 10 files changed, 153 insertions(+), 94 deletions(-) create mode 100644 .idea/misc.xml delete mode 100644 .idea/raymarcher.iml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/raymarcher.iml b/.idea/raymarcher.iml deleted file mode 100644 index bc2cd87..0000000 --- a/.idea/raymarcher.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/Makefile b/Makefile index 273fe2f..311d849 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -OPTIMIZATION=-O3 +OPTIMIZATION=-O3 -flto CC=gcc -CFLAGS=-Isrc/ -lm -Wall -Wextra -pedantic-errors $(OPTIMIZATION) +CFLAGS=-Isrc/ -lm -lpthread -Wall -Wextra -pedantic-errors $(OPTIMIZATION) .PHONY: directories @@ -21,7 +21,6 @@ obj/camera.o: src/camera.c src/camera.h obj/images.o: images/src/images.c images/src/images.h $(CC) $(CFLAGS) -c -o $@ images/src/images.c - march: obj/camera.o obj/scene.o obj/point.o obj/images.o $(CC) $(CFLAGS) -o out/march $^ marcher.c diff --git a/bench.c b/bench.c index 20bc774..138e588 100644 --- a/bench.c +++ b/bench.c @@ -11,10 +11,6 @@ #include "src/point.h" -typedef int bool; -#define true 1 -#define false 0 - #define BENCH_VERSION "1.0" @@ -28,12 +24,12 @@ typedef int bool; */ double mandelbulb_dist(struct point pt, struct scene_object *self) { - int iters = self->args[0]; + int iters = (int) self->args[0]; double power = self->args[1]; struct point z = pt; - float dr = 1.0; - float r = 0.0; + double dr = 1.0; + double r = 0.0; for (int i = 0; i < iters ; i++) { r = pt_length(z); @@ -42,12 +38,12 @@ double mandelbulb_dist(struct point pt, struct scene_object *self) { } // convert to polar coordinates - float theta = acos(z.z/r); - float phi = atan2(z.y,z.x); + double theta = acos(z.z/r); + double phi = atan2(z.y,z.x); dr = pow(r, power-1.0)*power*dr + 1.0; // scale and rotate the point - float zr = pow(r, power); + double zr = pow(r, power); theta = theta*power; phi = phi*power; @@ -81,11 +77,11 @@ struct scene_object mandelbulb_new(struct point location, int iters, double powe return so; } -int run_bench(int size, float pow, int threads, const char path[], bool save) { - float cam_position = 1.15; +int run_bench(int size, double pow, int threads, const char path[], int save) { + double cam_position = 1.15; int steps = 2000; int iters = 1000; - float threshold = 0.0001; + double threshold = 0.0001; struct camera cam; cam.fov = 90; @@ -107,7 +103,7 @@ int run_bench(int size, float pow, int threads, const char path[], bool save) { image_save_bmp(*img, path); } - image_destroy_shared(*img); + image_destroy(*img); scene_destroy(scene); return 0; @@ -134,11 +130,10 @@ void timer_print(struct timer t) { printf("\nBenchmark %s took %ldms (%.2fs)\n", t.name, time, time / 1000.0f); } -int main(int argc, char *argv[]) +int main() { - int threads = get_nprocs(); + int threads = get_nprocs() / 2; struct timer bench; - int size = 1080; printf("Mandelbulb Benchmark v%s\n\nDetected %d threads...\n", BENCH_VERSION, threads); @@ -146,7 +141,7 @@ int main(int argc, char *argv[]) bench.name = "1080px render with saving"; timer_start(&bench); - run_bench(1080, 3.0, threads, "bench-pow3-1080p.bmp", true); + run_bench(1080, 3.0, threads, "bench-pow3-1080p.bmp", 1); timer_end(&bench); timer_print(bench); @@ -154,7 +149,7 @@ int main(int argc, char *argv[]) bench.name = "1080px render without saving"; timer_start(&bench); - run_bench(1080, 3.0, threads, "", false); + run_bench(1080, 3.0, threads, "", 0); timer_end(&bench); timer_print(bench); @@ -162,7 +157,7 @@ int main(int argc, char *argv[]) bench.name = "10 megapixel render with saving"; timer_start(&bench); - run_bench(3162, 3.0, threads, "bench-pow3-10mpx.bmp", true); + run_bench(3162, 3.0, threads, "bench-pow3-10mpx.bmp", 1); timer_end(&bench); timer_print(bench); @@ -170,7 +165,7 @@ int main(int argc, char *argv[]) bench.name = "40 megapixel render with saving"; timer_start(&bench); - run_bench(6324, 3.0, threads, "bench-pow3-40mpx.bmp", true); + run_bench(6324, 3.0, threads, "bench-pow3-40mpx.bmp", 1); timer_end(&bench); timer_print(bench); @@ -178,7 +173,7 @@ int main(int argc, char *argv[]) bench.name = "1080px render single threaded without saving"; timer_start(&bench); - run_bench(1080, 3.0, 1, "", false); + run_bench(1080, 3.0, 1, "", 0); timer_end(&bench); timer_print(bench); diff --git a/marcher.c b/marcher.c index c32562b..4a786ae 100644 --- a/marcher.c +++ b/marcher.c @@ -160,7 +160,7 @@ int main(int argc, char* argv[]) { image_save_bmp(*img, path); - image_destroy_shared(*img); + image_destroy(*img); scene_destroy(scene); return 0; diff --git a/src/camera.c b/src/camera.c index 54a493b..7bcfe6e 100644 --- a/src/camera.c +++ b/src/camera.c @@ -1,11 +1,25 @@ -#include #include #include #include #include +#include #include "point.h" #include "camera.h" +struct thread_args { + struct point start; + int thread_id; + int thread_count; + int height; + int width; + struct point move_up; + struct point move_right; + void (*callback)(struct point, int, int); +}; + +static void * camera_iterate_rays_const_dist_thread(void* args); + + struct camera camera_new(struct point direction, unsigned int fov) { struct camera camera; camera.location = (struct point) { @@ -26,10 +40,9 @@ void camera_set_looking_at(struct camera *cam, struct point origin, struct point cam->direction = pt_normalize(pt_sub(thing, origin)); } - -void camera_iterate_rays_const_dist(struct camera camera, int width, int height, int threads, void (*callback)(struct point, int, int)) { - // negative threads => single threaded. - if (threads < 0) threads = 0; +void camera_iterate_rays_const_dist(struct camera camera, int width, int height, int thread_count, void (*callback)(struct point, int, int)) { + // negative thread_count => single threaded. + if (thread_count < 0) thread_count = 0; struct point span_z, span_xy; @@ -52,46 +65,88 @@ void camera_iterate_rays_const_dist(struct camera camera, int width, int height, starting_point = pt_add(starting_point, pt_mult(move_right, - width / (double) 2)); starting_point = pt_add(starting_point, pt_mult(move_up, - height / (double) 2)); - // initialize threads - int thread_id = 0; - for (int i = 0; i < threads - 1; i++) { - if (fork() == 0) { - thread_id = i + 1; - break; - } + if (thread_count < 2) { + //TODO implement single threaded work here + struct thread_args arg = { + .start = starting_point, + .thread_id = 0, + .thread_count = 1, + .height = height, + .width = width, + .move_up = move_up, + .move_right = move_right, + .callback = callback + }; + + camera_iterate_rays_const_dist_thread(&arg); + + return; + } + + // initialize thread_count + pthread_t * threads = malloc(sizeof(pthread_t) * thread_count); + struct thread_args* args = malloc(sizeof(struct thread_args) * thread_count); + + for (int i = 0; i < thread_count; i++) { + args[i] = (struct thread_args) { + .start = starting_point, + .thread_id = i, + .thread_count = thread_count, + .height = height, + .width = width, + .move_up = move_up, + .move_right = move_right, + .callback = callback + }; + + pthread_create(threads + i, NULL, camera_iterate_rays_const_dist_thread, (void*) (args + i)); + } + + //struct thread_args { + // struct point start; + // int thread_id; + // int thread_count; + // int height; + // int width; + // struct point move_up; + // struct point move_right; + // void (*callback)(struct point, int, int); + //}; + + + for (int i = 0; i < thread_count; i++) { + pthread_join(threads[i], NULL); } +} + +static void * camera_iterate_rays_const_dist_thread(void* arg_ptr) { + // explicit cast to make gcc happy + struct thread_args* args = (struct thread_args*) arg_ptr; // this point is moved for every pixel - struct point curr_pt = starting_point; + struct point curr_pt = args->start; // (0,0) screenspace is bottom left corner - for (int y = 0; y < height; y++) { + for (int y = 0; y < args->height; y++) { // move one row up (this has to be done in every thread!) - starting_point = pt_add(starting_point, move_up); + args->start = pt_add(args->start, args->move_up); // only render the lines this thread is responsible for - if (y % threads != thread_id) continue; - + if (y % args->thread_count != args->thread_id) continue; + // display progress in percent - if (height > 200 && y % (height / 100) == 0 && y != 0) { - printf("\r%02i%%", (y * 100) / height); + if (args->height > 200 && y % (args->height / 100) == 0 && y != 0) { + printf("\r%02i%%", (y * 100) / args->height); fflush(stdout); } // actually iterate this line - curr_pt = starting_point; - for (int x = 0; x < width; x++) { - callback(curr_pt, x, y); - curr_pt = pt_add(curr_pt, move_right); // move pt right to next pt + curr_pt = args->start; + for (int x = 0; x < args->width; x++) { + args->callback(curr_pt, x, y); + curr_pt = pt_add(curr_pt, args->move_right); // move pt right to next pt } } - if (thread_id != 0) { - exit(0); - } - - int status; - for (int i = 0; i < threads - 1; i++) { - while(wait(&status) > 0) {} - } -} \ No newline at end of file + return NULL; +} diff --git a/src/camera.h b/src/camera.h index b766c3f..2fb6318 100644 --- a/src/camera.h +++ b/src/camera.h @@ -8,4 +8,4 @@ struct camera { struct camera camera_new(struct point direction, unsigned int fov); void camera_set_looking_at(struct camera *cam, struct point origin, struct point thing); -void camera_iterate_rays_const_dist(struct camera camera, int width, int height, int threads, void (*callback)(struct point, int, int)); \ No newline at end of file +void camera_iterate_rays_const_dist(struct camera camera, int width, int height, int thread_count, void (*callback)(struct point, int, int)); \ No newline at end of file diff --git a/src/point.c b/src/point.c index 219a70c..bb928f4 100644 --- a/src/point.c +++ b/src/point.c @@ -2,17 +2,10 @@ #include #include "point.h" -// scale vector to length -struct point pt_scale(struct point pt, double length) { - double f = length / pt_length(pt); - return (struct point) { - .x = pt.x * f, - .y = pt.y * f, - .z = pt.z * f - }; -} +// get the length of vector +inline double pt_length_inline (struct point pt) __attribute__((always_inline)); -struct point pt_mult(struct point pt, double scalar) { +inline struct point pt_mult(struct point pt, double scalar) { return (struct point) { .x = pt.x * scalar, .y = pt.y * scalar, @@ -21,7 +14,7 @@ struct point pt_mult(struct point pt, double scalar) { } // return internal angle between a and b -double pt_angle(struct point a, struct point b) { +inline double pt_angle(struct point a, struct point b) { return acos(pt_dot( pt_normalize(a), pt_normalize(b) @@ -29,12 +22,16 @@ double pt_angle(struct point a, struct point b) { } // get the length of vector -double pt_length(struct point pt) { +inline double pt_length_inline (struct point pt) { return sqrt((pt.x * pt.x) + (pt.y * pt.y) + (pt.z * pt.z)); } +double pt_length(struct point pt) { + return pt_length_inline(pt); +} + // add the vector add to the vector pt -struct point pt_add(struct point pt, struct point add) { +inline struct point pt_add(struct point pt, struct point add) { return (struct point) { .x = pt.x + add.x, .y = pt.y + add.y, @@ -43,7 +40,7 @@ struct point pt_add(struct point pt, struct point add) { } // add the vector add to the vector pt -struct point pt_sub(struct point pt, struct point sub) { +inline struct point pt_sub(struct point pt, struct point sub) { return (struct point) { .x = pt.x - sub.x, .y = pt.y - sub.y, @@ -51,22 +48,38 @@ struct point pt_sub(struct point pt, struct point sub) { }; } -double pt_dist(struct point p1, struct point p2) { - return pt_length(pt_sub(p1, p2)); +inline double pt_dist(struct point p1, struct point p2) { + return pt_length_inline(pt_sub(p1, p2)); } // normalize a vector -struct point pt_normalize(struct point pt) { - return pt_scale(pt, 1); +inline struct point pt_normalize(struct point pt) { + double length = pt_length(pt); + + return (struct point) { + .x = pt.x / length, + .y = pt.y / length, + .z = pt.z / length + }; +} + +// scale vector to length +inline struct point pt_scale(struct point pt, double length) { + double f = length / pt_length_inline(pt); + return (struct point) { + .x = pt.x * f, + .y = pt.y * f, + .z = pt.z * f + }; } // dot product of two vectors -double pt_dot(struct point a, struct point b) { +inline double pt_dot(struct point a, struct point b) { return a.x*b.x + a.y*b.y + a.z*b.z; } // cross product of two vectors -struct point pt_cross(struct point a, struct point b) { +inline struct point pt_cross(struct point a, struct point b) { return (struct point) { .x = a.y*b.z - a.z*b.y, .y = a.z*b.x - a.x*b.z, @@ -74,29 +87,29 @@ struct point pt_cross(struct point a, struct point b) { }; } -void pt_print(struct point pt) { +inline void pt_print(struct point pt) { printf("(%f, %f, %f)\n", pt.x, pt.y, pt.z); } -void pt_print_n(const char* name, struct point pt) { +inline void pt_print_n(const char* name, struct point pt) { printf("%s: (%f, %f, %f)\n", name, pt.x, pt.y, pt.z); } // find two vectors that span the orthogonal plane, where // span_xy is a vector lying on the xy-plane (and pointing left) // and span_z is orthogonal to span_xy pointing "upwards" -void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy) { +inline void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy) { pt = pt_normalize(pt); // get the vector lying on the xy axis - // this is done by - *span_xy = pt_normalize(pt_cross((struct point){.x = 0, .y = 0, .z = 1}, pt)); // points to the "left" (of the viewing direction) + // this is done by + *span_xy = pt_normalize(pt_cross(PT_NEW(0,0,1), pt)); // points to the "left" (of the viewing direction) // now use this, to find the vector *span_z = pt_normalize(pt_cross(pt, *span_xy)); } -struct point pt_mod(struct point pt, double mod) { +inline struct point pt_mod(struct point pt, double mod) { return (struct point) { .x = fabs(fmod(pt.x, mod)), .y = fabs(fmod(pt.y, mod)), diff --git a/src/point.h b/src/point.h index 69cb378..62bde2d 100644 --- a/src/point.h +++ b/src/point.h @@ -8,6 +8,7 @@ struct point { }; #define PT_ZERO ((struct point) {.x=0, .y=0, .z=0}) +#define PT_NEW(x,y,z) ((struct point){(x), (y), (z)}) struct point pt_scale(struct point pt, double length); struct point pt_normalize(struct point pt); diff --git a/src/scene.c b/src/scene.c index bad4222..b62fab6 100644 --- a/src/scene.c +++ b/src/scene.c @@ -51,7 +51,7 @@ Image* render_scene(struct scene *scene, struct camera *camera, unsigned int thr current_camera= camera; // initialize shared pixel buffer - image_new_shared(scene->width, scene->height, current_image); + image_new(scene->width, scene->height, current_image); // iterate over the rays camera_iterate_rays_const_dist(*camera, scene->width, scene->height, threads, camera_iter_callback); -- 2.40.1 From 01d359b5031a91187208beb7490f03ccb7e8f437 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Fri, 20 May 2022 20:44:29 +0200 Subject: [PATCH 09/10] updated images version --- images | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images b/images index a71e319..f503f18 160000 --- a/images +++ b/images @@ -1 +1 @@ -Subproject commit a71e319fb4929135d51e4585a334643c194f5196 +Subproject commit f503f1835fd47de323b19d8f3f1ea0fc542dd6f6 -- 2.40.1 From a508cab2bcd88a102c7caf03534284b95e127c5f Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Fri, 24 Feb 2023 21:46:21 +0000 Subject: [PATCH 10/10] add openacc compatible version --- Makefile | 19 +++--- gpu.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/point.c | 118 --------------------------------- src/point.h | 157 +++++++++++++++++++++++++++++++++++++++----- 4 files changed, 337 insertions(+), 143 deletions(-) create mode 100644 gpu.c delete mode 100644 src/point.c diff --git a/Makefile b/Makefile index 311d849..fd0b93f 100644 --- a/Makefile +++ b/Makefile @@ -2,27 +2,30 @@ OPTIMIZATION=-O3 -flto CC=gcc -CFLAGS=-Isrc/ -lm -lpthread -Wall -Wextra -pedantic-errors $(OPTIMIZATION) +CFLAGS=-Isrc/ -lm -lpthread -Wall -Wextra -pedantic-errors $(OPTIMIZATION) -DPOINT_DTYPE=float .PHONY: directories directories: mkdir -p obj out -obj/point.o: src/point.c src/point.h - $(CC) $(CFLAGS) -c -o $@ src/point.c +clean: + rm -rf obj/* out/* -obj/scene.o: src/scene.c src/scene.h +obj/scene.o: src/scene.c src/scene.h src/point.h $(CC) $(CFLAGS) -c -o $@ src/scene.c -obj/camera.o: src/camera.c src/camera.h +obj/camera.o: src/camera.c src/camera.h src/point.h $(CC) $(CFLAGS) -c -o $@ src/camera.c -obj/images.o: images/src/images.c images/src/images.h +obj/images.o: images/src/images.c images/src/images.h src/point.h $(CC) $(CFLAGS) -c -o $@ images/src/images.c -march: obj/camera.o obj/scene.o obj/point.o obj/images.o +march: obj/camera.o obj/scene.o obj/images.o src/point.h $(CC) $(CFLAGS) -o out/march $^ marcher.c -bench: obj/camera.o obj/scene.o obj/point.o obj/images.o +bench: obj/camera.o obj/scene.o obj/images.o src/point.h $(CC) $(CFLAGS) -o out/bench $^ bench.c + +gpu: obj/camera.o obj/images.o src/point.h + $(CC) -fopenacc $(CFLAGS) -o out/gpu $^ gpu.c diff --git a/gpu.c b/gpu.c new file mode 100644 index 0000000..44470b4 --- /dev/null +++ b/gpu.c @@ -0,0 +1,186 @@ +// use floats instead of doubles +#define DTYPE float +// #define POINT_DTYPE DTYPE + +#include +#include + +#include "src/point.h" +#include "src/camera.h" +#include "images/src/images.h" + +#define ITERS 100 +#define POWER 3 + +#define SIZE 1000 +#define STEP_WIDTH (2 / ((DTYPE) (SIZE - 1))) + +#define CAM_POSITION 1.35 + +#define STEPS 100 +#define THRESHOLD 0.001 + +#include + + +float mandelbulb_dist(struct point pt) +{ + DTYPE power = POWER; + + struct point z = pt; + DTYPE dr = 1.0; + DTYPE r = 0.0; + for (int i = 0; i < ITERS ; i++) { + r = pt_length(z); + + if (r>2) { + break; + } + + // convert to polar coordinates + DTYPE theta = acos(z.z/r); + DTYPE phi = atan2(z.y,z.x); + dr = pow(r, power-1.0)*power*dr + 1.0; + + // scale and rotate the point + DTYPE zr = pow(r, power); + theta = theta*power; + phi = phi*power; + + // convert back to cartesian coordinates + z = (struct point) { + .x = sin(theta)*cos(phi) * zr + pt.x, + .y = sin(phi)*sin(theta) * zr + pt.y, + .z = cos(theta) * zr + pt.z + }; + } + + return 0.5*log(r)*r/dr; +} + +struct setup { + struct point p0; // origin + struct point direction; // ray direction + struct point x; // ray movement in col + struct point y; // ray movement in row +}; + +struct setup make_setup() +{ + // set up camera + struct camera cam; + cam.fov = 90; + + camera_set_looking_at(&cam, (struct point){.x=CAM_POSITION, .y= CAM_POSITION, .z = CAM_POSITION}, PT_ZERO); + + struct point span_z, span_xy; + + // get rotation axis + pt_orthogonal_plane(cam.direction, &span_z, &span_xy); + + printf("rendering %ix%ipx\n", SIZE, SIZE); + + // distance each ray has from anothe on the ortogonal plane + //DTYPE step_dist = 2 / (DTYPE) (width - 1); + + // vectors to move on the projection plane + struct point move_right = pt_scale(span_xy, STEP_WIDTH); + struct point move_up = pt_scale(span_z, STEP_WIDTH);; + + // set starting point + struct point starting_point = pt_normalize(cam.direction); + + // rotate starting point to (0,0) + starting_point = pt_add(starting_point, pt_mult(move_right, - SIZE / (DTYPE) 2)); + starting_point = pt_add(starting_point, pt_mult(move_up, - SIZE / (DTYPE) 2)); + + return (struct setup) { + cam.location, starting_point, span_xy, span_z + }; +} + +int main() +{ + struct setup setup = make_setup(); + struct point start = setup.p0; + + //printf("device num acc_device_current: %d\n", acc_get_num_devices(acc_device_current)); + //printf("device num acc_device_none: %d\n", acc_get_num_devices(acc_device_none)); + //printf("device num acc_device_default: %d\n", acc_get_num_devices(acc_device_default)); + //printf("device num acc_device_host: %d\n", acc_get_num_devices(acc_device_host)); + //printf("device num acc_device_not_host: %d\n", acc_get_num_devices(acc_device_not_host)); + //printf("device num acc_device_nvidia: %d\n", acc_get_num_devices(acc_device_nvidia)); + //printf("device num acc_device_radeon: %d\n", acc_get_num_devices(acc_device_radeon)); + + // get backing buff + int* buff = calloc(sizeof(int), SIZE * SIZE); + + // indicate malloc failure + if (buff == NULL) + return -255; + + printf("Before kernel\n"); + +#pragma acc data copy(buff) +{ + // kernel goes brr + #pragma acc kernels + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + // get direction + struct point offset = pt_add(pt_mult(setup.x, STEP_WIDTH * x), pt_mult(setup.y, STEP_WIDTH * y)); + struct point direction = pt_add(setup.direction, offset); + // get start + struct point loc = start; + // march! + DTYPE dist; + int res = -1; + + for (int i = 0; i < STEPS; i++) { + dist = mandelbulb_dist(loc); + if (dist < THRESHOLD) { + res = i; + break; + } + if (dist > 100) { + break; + } + loc = pt_add(loc, pt_scale(direction, dist)); + } + buff[y * SIZE + x] = res; + } + } +} + + printf("after kernel\n"); + + // convert distance field into image + + Image img; + + // initialize shared pixel buffer + image_new(SIZE, SIZE, &img); + + #pragma acc parallel + for (unsigned int x = 0; x < SIZE; x++) { + #pragma acc loop + for (unsigned int y = 0; y < SIZE; y++) { + if (buff[y * SIZE + x] < 0) { + image_set_px(img, x, y, 0, 0, 0); + } else { + // float in range of [0,1] + DTYPE fac = buff[y * SIZE + x] / (DTYPE) STEPS; + // calc shade + int shade = ((1-fac) * 255); + image_set_px(img, x, y, shade, shade, shade); + } + } + } + + printf("after encoding\n"); + + + image_save_bmp(img, "gpu-goes-brrrrrrr.bmp"); + + return 0; +} \ No newline at end of file diff --git a/src/point.c b/src/point.c deleted file mode 100644 index bb928f4..0000000 --- a/src/point.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include "point.h" - -// get the length of vector -inline double pt_length_inline (struct point pt) __attribute__((always_inline)); - -inline struct point pt_mult(struct point pt, double scalar) { - return (struct point) { - .x = pt.x * scalar, - .y = pt.y * scalar, - .z = pt.z * scalar - }; -} - -// return internal angle between a and b -inline double pt_angle(struct point a, struct point b) { - return acos(pt_dot( - pt_normalize(a), - pt_normalize(b) - )); -} - -// get the length of vector -inline double pt_length_inline (struct point pt) { - return sqrt((pt.x * pt.x) + (pt.y * pt.y) + (pt.z * pt.z)); -} - -double pt_length(struct point pt) { - return pt_length_inline(pt); -} - -// add the vector add to the vector pt -inline struct point pt_add(struct point pt, struct point add) { - return (struct point) { - .x = pt.x + add.x, - .y = pt.y + add.y, - .z = pt.z + add.z, - }; -} - -// add the vector add to the vector pt -inline struct point pt_sub(struct point pt, struct point sub) { - return (struct point) { - .x = pt.x - sub.x, - .y = pt.y - sub.y, - .z = pt.z - sub.z, - }; -} - -inline double pt_dist(struct point p1, struct point p2) { - return pt_length_inline(pt_sub(p1, p2)); -} - -// normalize a vector -inline struct point pt_normalize(struct point pt) { - double length = pt_length(pt); - - return (struct point) { - .x = pt.x / length, - .y = pt.y / length, - .z = pt.z / length - }; -} - -// scale vector to length -inline struct point pt_scale(struct point pt, double length) { - double f = length / pt_length_inline(pt); - return (struct point) { - .x = pt.x * f, - .y = pt.y * f, - .z = pt.z * f - }; -} - -// dot product of two vectors -inline double pt_dot(struct point a, struct point b) { - return a.x*b.x + a.y*b.y + a.z*b.z; -} - -// cross product of two vectors -inline struct point pt_cross(struct point a, struct point b) { - return (struct point) { - .x = a.y*b.z - a.z*b.y, - .y = a.z*b.x - a.x*b.z, - .z = a.x*b.y - a.y*b.x - }; -} - -inline void pt_print(struct point pt) { - printf("(%f, %f, %f)\n", pt.x, pt.y, pt.z); -} - -inline void pt_print_n(const char* name, struct point pt) { - printf("%s: (%f, %f, %f)\n", name, pt.x, pt.y, pt.z); -} - -// find two vectors that span the orthogonal plane, where -// span_xy is a vector lying on the xy-plane (and pointing left) -// and span_z is orthogonal to span_xy pointing "upwards" -inline void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy) { - pt = pt_normalize(pt); - - // get the vector lying on the xy axis - // this is done by - *span_xy = pt_normalize(pt_cross(PT_NEW(0,0,1), pt)); // points to the "left" (of the viewing direction) - - // now use this, to find the vector - *span_z = pt_normalize(pt_cross(pt, *span_xy)); -} - -inline struct point pt_mod(struct point pt, double mod) { - return (struct point) { - .x = fabs(fmod(pt.x, mod)), - .y = fabs(fmod(pt.y, mod)), - .z = fabs(fmod(pt.z, mod)) - }; -} \ No newline at end of file diff --git a/src/point.h b/src/point.h index 62bde2d..a1f4b7d 100644 --- a/src/point.h +++ b/src/point.h @@ -1,26 +1,149 @@ #pragma once +#ifndef POINT_DTYPE +#define POINT_DTYPE double +#endif + struct point { - double x; - double y; - double z; + POINT_DTYPE x; + POINT_DTYPE y; + POINT_DTYPE z; }; #define PT_ZERO ((struct point) {.x=0, .y=0, .z=0}) #define PT_NEW(x,y,z) ((struct point){(x), (y), (z)}) -struct point pt_scale(struct point pt, double length); -struct point pt_normalize(struct point pt); -struct point pt_mult(struct point pt, double scalar); -double pt_length(struct point pt); -struct point pt_add(struct point pt, struct point add); -struct point pt_sub(struct point pt, struct point sub); -double pt_dist(struct point p1, struct point p2); -struct point pt_mod(struct point pt, double mod); -double pt_dot(struct point a, struct point b); -struct point pt_cross(struct point a, struct point b); -double pt_angle(struct point a, struct point b); -void pt_print(struct point pt); -void pt_print_n(const char* name, struct point pt); -void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy); +static struct point pt_scale(struct point pt, POINT_DTYPE length); +static struct point pt_normalize(struct point pt); +static struct point pt_mult(struct point pt, POINT_DTYPE scalar); +static POINT_DTYPE pt_length(struct point pt); +static struct point pt_add(struct point pt, struct point add); +static struct point pt_sub(struct point pt, struct point sub); +static POINT_DTYPE pt_dist(struct point p1, struct point p2); +static struct point pt_mod(struct point pt, POINT_DTYPE mod); +static POINT_DTYPE pt_dot(struct point a, struct point b); +static struct point pt_cross(struct point a, struct point b); +static POINT_DTYPE pt_angle(struct point a, struct point b); +static void pt_print(struct point pt); +static void pt_print_n(const char* name, struct point pt); +static void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy); + +#include +#include +#include "point.h" + +// get the length of vector +static inline POINT_DTYPE pt_length_inline (struct point pt) __attribute__((always_inline)); + +static inline struct point pt_mult(struct point pt, POINT_DTYPE scalar) { + return (struct point) { + .x = pt.x * scalar, + .y = pt.y * scalar, + .z = pt.z * scalar + }; +} + +// return internal angle between a and b +static inline POINT_DTYPE pt_angle(struct point a, struct point b) { + return acos(pt_dot( + pt_normalize(a), + pt_normalize(b) + )); +} + +// get the length of vector +static inline POINT_DTYPE pt_length_inline (struct point pt) { + return sqrt((pt.x * pt.x) + (pt.y * pt.y) + (pt.z * pt.z)); +} + +static inline POINT_DTYPE pt_length(struct point pt) { + return pt_length_inline(pt); +} + +// add the vector add to the vector pt +static inline struct point pt_add(struct point pt, struct point add) { + return (struct point) { + .x = pt.x + add.x, + .y = pt.y + add.y, + .z = pt.z + add.z, + }; +} + +// add the vector add to the vector pt +static inline struct point pt_sub(struct point pt, struct point sub) { + return (struct point) { + .x = pt.x - sub.x, + .y = pt.y - sub.y, + .z = pt.z - sub.z, + }; +} + +static inline POINT_DTYPE pt_dist(struct point p1, struct point p2) { + return pt_length_inline(pt_sub(p1, p2)); +} + +// normalize a vector +static inline struct point pt_normalize(struct point pt) { + POINT_DTYPE length = pt_length(pt); + + return (struct point) { + .x = pt.x / length, + .y = pt.y / length, + .z = pt.z / length + }; +} + +// scale vector to length +static inline struct point pt_scale(struct point pt, POINT_DTYPE length) { + POINT_DTYPE f = length / pt_length_inline(pt); + return (struct point) { + .x = pt.x * f, + .y = pt.y * f, + .z = pt.z * f + }; +} + +// dot product of two vectors +static inline POINT_DTYPE pt_dot(struct point a, struct point b) { + return a.x*b.x + a.y*b.y + a.z*b.z; +} + +// cross product of two vectors +static inline struct point pt_cross(struct point a, struct point b) { + return (struct point) { + .x = a.y*b.z - a.z*b.y, + .y = a.z*b.x - a.x*b.z, + .z = a.x*b.y - a.y*b.x + }; +} + +static inline void pt_print(struct point pt) { + printf("(%f, %f, %f)\n", pt.x, pt.y, pt.z); +} + +static inline void pt_print_n(const char* name, struct point pt) { + printf("%s: (%f, %f, %f)\n", name, pt.x, pt.y, pt.z); +} + +// find two vectors that span the orthogonal plane, where +// span_xy is a vector lying on the xy-plane (and pointing left) +// and span_z is orthogonal to span_xy pointing "upwards" +static inline void pt_orthogonal_plane(struct point pt, struct point *span_z, struct point *span_xy) { + pt = pt_normalize(pt); + + // get the vector lying on the xy axis + // this is done by + *span_xy = pt_normalize(pt_cross(PT_NEW(0,0,1), pt)); // points to the "left" (of the viewing direction) + + // now use this, to find the vector + *span_z = pt_normalize(pt_cross(pt, *span_xy)); +} + +static inline struct point pt_mod(struct point pt, POINT_DTYPE mod) { + return (struct point) { + .x = fabs(fmod(pt.x, mod)), + .y = fabs(fmod(pt.y, mod)), + .z = fabs(fmod(pt.z, mod)) + }; +} \ No newline at end of file -- 2.40.1