summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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