diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2017-04-22 12:19:00 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2017-04-22 12:35:05 -0700 |
commit | d658d6265d5bb09bd48a205941fa74ca6b0580cf (patch) | |
tree | deeccbe1c1b451fcda8dc9636489cde48912eb3c /src/modules/ray | |
parent | 3a55ed3d9470137843729ca5df4222122ad048b5 (diff) |
ray: convert to generalized threaded rendering
The ray tracer was already threaded, so this required little change other
than making some state global like the previous commits, and calling the
underlying non-threaded single-fragment scene renderer function.
A future commit will discard the now vestigial ray_threads related code.
Diffstat (limited to 'src/modules/ray')
-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", }; |