From d658d6265d5bb09bd48a205941fa74ca6b0580cf Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Sat, 22 Apr 2017 12:19:00 -0700 Subject: 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. --- src/modules/ray/ray.c | 238 ++++++++++++++++++++++++-------------------------- 1 file changed, 113 insertions(+), 125 deletions(-) (limited to 'src/modules/ray') 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 */ -/* 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 ", .license = "GPLv2", }; -- cgit v1.2.3