summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2017-04-22 12:19:00 -0700
committerVito Caputo <vcaputo@pengaru.com>2017-04-22 12:35:05 -0700
commitd658d6265d5bb09bd48a205941fa74ca6b0580cf (patch)
treedeeccbe1c1b451fcda8dc9636489cde48912eb3c
parent3a55ed3d9470137843729ca5df4222122ad048b5 (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.
-rw-r--r--src/modules/ray/ray.c238
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",
};
© All Rights Reserved