diff options
-rw-r--r-- | src/modules/ray/ray.c | 238 |
1 files changed, 113 insertions, 125 deletions
diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c index a0613e8..9847bd9 100644 --- a/src/modules/ray/ray.c +++ b/src/modules/ray/ray.c @@ -13,113 +13,117 @@ /* Copyright (C) 2016-2017 Vito Caputo <vcaputo@pengaru.com> */ -/* ray trace a simple scene into the fragment */ -static void ray_render_fragment(fb_fragment_t *fragment) -{ - static ray_object_t objects[] = { - { - .plane = { - .type = RAY_OBJECT_TYPE_PLANE, - .surface = { - .color = { .x = 0.6, .y = 0.3, .z = 0.8 }, - .diffuse = 1.0f, - .specular = 0.2f, - .highlight_exponent = 20.0f - }, - .normal = { .x = 0.0, .y = 1.0, .z = 0.0 }, - .distance = 2.0f, - } - }, { - .sphere = { - .type = RAY_OBJECT_TYPE_SPHERE, - .surface = { - .color = { .x = 1.0, .y = 0.0, .z = 0.0 }, - .diffuse = 1.0f, - .specular = 0.05f, - .highlight_exponent = 20.0f - }, - .center = { .x = 0.5, .y = 1.0, .z = 0.0 }, - .radius = 1.2f, - } - }, { - .sphere = { - .type = RAY_OBJECT_TYPE_SPHERE, - .surface = { - .color = { .x = 0.0, .y = 0.0, .z = 1.0 }, - .diffuse = 0.9f, - .specular = 0.4f, - .highlight_exponent = 20.0f - }, - .center = { .x = -2.0, .y = 1.0, .z = 0.0 }, - .radius = 0.9f, - } - }, { - .sphere = { - .type = RAY_OBJECT_TYPE_SPHERE, - .surface = { - .color = { .x = 0.0, .y = 1.0, .z = 1.0 }, - .diffuse = 0.9f, - .specular = 0.3f, - .highlight_exponent = 20.0f - }, - .center = { .x = 2.0, .y = -1.0, .z = 0.0 }, - .radius = 1.0f, - } - }, { - .sphere = { - .type = RAY_OBJECT_TYPE_SPHERE, - .surface = { - .color = { .x = 0.0, .y = 1.0, .z = 0.0 }, - .diffuse = 0.95f, - .specular = 0.85f, - .highlight_exponent = 1500.0f +static ray_object_t objects[] = { + { + .plane = { + .type = RAY_OBJECT_TYPE_PLANE, + .surface = { + .color = { .x = 0.6, .y = 0.3, .z = 0.8 }, + .diffuse = 1.0f, + .specular = 0.2f, + .highlight_exponent = 20.0f + }, + .normal = { .x = 0.0, .y = 1.0, .z = 0.0 }, + .distance = 2.0f, + } + }, { + .sphere = { + .type = RAY_OBJECT_TYPE_SPHERE, + .surface = { + .color = { .x = 1.0, .y = 0.0, .z = 0.0 }, + .diffuse = 1.0f, + .specular = 0.05f, + .highlight_exponent = 20.0f + }, + .center = { .x = 0.5, .y = 1.0, .z = 0.0 }, + .radius = 1.2f, + } + }, { + .sphere = { + .type = RAY_OBJECT_TYPE_SPHERE, + .surface = { + .color = { .x = 0.0, .y = 0.0, .z = 1.0 }, + .diffuse = 0.9f, + .specular = 0.4f, + .highlight_exponent = 20.0f + }, + .center = { .x = -2.0, .y = 1.0, .z = 0.0 }, + .radius = 0.9f, + } + }, { + .sphere = { + .type = RAY_OBJECT_TYPE_SPHERE, + .surface = { + .color = { .x = 0.0, .y = 1.0, .z = 1.0 }, + .diffuse = 0.9f, + .specular = 0.3f, + .highlight_exponent = 20.0f + }, + .center = { .x = 2.0, .y = -1.0, .z = 0.0 }, + .radius = 1.0f, + } + }, { + .sphere = { + .type = RAY_OBJECT_TYPE_SPHERE, + .surface = { + .color = { .x = 0.0, .y = 1.0, .z = 0.0 }, + .diffuse = 0.95f, + .specular = 0.85f, + .highlight_exponent = 1500.0f + }, + .center = { .x = 0.2, .y = -1.25, .z = 0.0 }, + .radius = 0.6f, + } + }, { + .light = { + .type = RAY_OBJECT_TYPE_LIGHT, + .brightness = 1.0, + .emitter = { + .point.type = RAY_LIGHT_EMITTER_TYPE_POINT, + .point.center = { .x = 3.0f, .y = 3.0f, .z = 3.0f }, + .point.surface = { + .color = { .x = 1.0f, .y = 1.0f, .z = 1.0f }, }, - .center = { .x = 0.2, .y = -1.25, .z = 0.0 }, - .radius = 0.6f, - } - }, { - .light = { - .type = RAY_OBJECT_TYPE_LIGHT, - .brightness = 1.0, - .emitter = { - .point.type = RAY_LIGHT_EMITTER_TYPE_POINT, - .point.center = { .x = 3.0f, .y = 3.0f, .z = 3.0f }, - .point.surface = { - .color = { .x = 1.0f, .y = 1.0f, .z = 1.0f }, - }, - } } } - }; - - ray_camera_t camera = { - .position = { .x = 0.0, .y = 0.0, .z = 6.0 }, - .orientation = { - .order = RAY_EULER_ORDER_YPR, /* yaw,pitch,roll */ - .yaw = RAY_EULER_DEGREES(0.0f), - .pitch = RAY_EULER_DEGREES(0.0f), - .roll = RAY_EULER_DEGREES(180.0f), - }, - .focal_length = 700.0f, - .width = fragment->width, - .height = fragment->height, - }; - - static ray_scene_t scene = { - .objects = objects, - .n_objects = nelems(objects), - .lights = &objects[5], - .n_lights = 1, - .ambient_color = { .x = 1.0f, .y = 1.0f, .z = 1.0f }, - .ambient_brightness = .04f, - }; - static int initialized; - static ray_threads_t *threads; - static fb_fragment_t *fragments; - static unsigned ncpus; + } +}; + +static ray_camera_t camera = { + .position = { .x = 0.0, .y = 0.0, .z = 6.0 }, + .orientation = { + .order = RAY_EULER_ORDER_YPR, /* yaw,pitch,roll */ + .yaw = RAY_EULER_DEGREES(0.0f), + .pitch = RAY_EULER_DEGREES(0.0f), + .roll = RAY_EULER_DEGREES(180.0f), + }, + .focal_length = 700.0f, + }; + +static ray_scene_t scene = { + .objects = objects, + .n_objects = nelems(objects), + .lights = &objects[5], + .n_lights = 1, + .ambient_color = { .x = 1.0f, .y = 1.0f, .z = 1.0f }, + .ambient_brightness = .04f, + }; + +static float r; + + +/* prepare a frame for concurrent rendering */ +static void ray_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame) +{ + /* TODO experiment with tiled fragments vs. rows */ + res_frame->n_fragments = n_cpus; + fb_fragment_divide(fragment, n_cpus, res_frame->fragments); + + /* TODO: the camera doesn't need the width and height anymore, the fragment has the frame_width/frame_height */ + camera.width = fragment->frame_width, + camera.height = fragment->frame_height, #if 1 /* animated point light source */ - static float r; r += .02; @@ -139,37 +143,21 @@ static void ray_render_fragment(fb_fragment_t *fragment) /* tilt camera pitch in time with up and down movements, phase shifted appreciably */ camera.orientation.pitch = sinf((M_PI * 1.5f) + r * 1.3f) * .6f + -.35f; #endif +} - if (!initialized) { - initialized = 1; - ncpus = get_ncpus(); - if (ncpus > 1) { - threads = ray_threads_create(ncpus - 1); - fragments = malloc(sizeof(fb_fragment_t) * ncpus); - } - } - - if (ncpus > 1) { - /* Always recompute the fragments[] geometry. - * This way the fragment geometry can change at any moment and things will - * continue functioning, which may prove important later on. - * (imagine things like a preview window, or perhaps composite modules - * which call on other modules supplying virtual fragments of varying dimensions..) - */ - fb_fragment_divide(fragment, ncpus, fragments); - } else { - fragments = fragment; - } - - ray_scene_render_fragments(&scene, &camera, threads, fragments); +/* ray trace a simple scene into the fragment */ +static void ray_render_fragment(fb_fragment_t *fragment) +{ + ray_scene_render_fragment(&scene, &camera, fragment); } rototiller_module_t ray_module = { + .prepare_frame = ray_prepare_frame, .render_fragment = ray_render_fragment, .name = "ray", - .description = "Multi-threaded ray tracer", + .description = "Ray tracer (threaded)", .author = "Vito Caputo <vcaputo@pengaru.com>", .license = "GPLv2", }; |