summaryrefslogtreecommitdiff
path: root/modules/ray/ray_camera.h
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@gnugeneration.com>2016-12-13 07:57:56 -0800
committerVito Caputo <vcaputo@gnugeneration.com>2016-12-13 08:01:22 -0800
commit8340e615d46615894b44b4ffce5dc2dd86cbad40 (patch)
treeca9f82767d360f03e09425f21e35d0188eb52d1c /modules/ray/ray_camera.h
parent8add1663d9a02db2bc65224cdceb480733a81379 (diff)
ray: introduce a rudimentary ray tracer
My first ray tracer, it only has spheres, planes, and point light sources. No texture mapping, no soft shadows, no global illumination. This is all very basic right now, the camera movement is simple and boring, but sufficient for further development and optimization. I made some effort to support multiple CPUs, it should detect the number of CPUs in the system and use enough pthreads to keep them busy. Jacco Bikker's tutorial on flipcode was the original impetus to do this, and definitely served as a guide early on.
Diffstat (limited to 'modules/ray/ray_camera.h')
-rw-r--r--modules/ray/ray_camera.h77
1 files changed, 77 insertions, 0 deletions
diff --git a/modules/ray/ray_camera.h b/modules/ray/ray_camera.h
new file mode 100644
index 0000000..387f8c5
--- /dev/null
+++ b/modules/ray/ray_camera.h
@@ -0,0 +1,77 @@
+#ifndef _RAY_CAMERA_H
+#define _RAY_CAMERA_H
+
+#include <math.h>
+
+#include "fb.h"
+
+#include "ray_3f.h"
+#include "ray_euler.h"
+#include "ray_ray.h"
+
+
+typedef struct ray_camera_t {
+ ray_3f_t position; /* position of camera, the origin of all its rays */
+ ray_euler_t orientation; /* orientation of the camera */
+ float focal_length; /* controls the field of view */
+ unsigned width; /* width of camera viewport in pixels */
+ unsigned height; /* height of camera viewport in pixels */
+} ray_camera_t;
+
+
+typedef struct ray_camera_frame_t {
+ ray_camera_t *camera; /* the camera supplied to frame_begin() */
+ fb_fragment_t *fragment; /* the fragment supplied to frame_begin() */
+ ray_ray_t *ray; /* the ray supplied to frame_begin(), which gets updated as we step through the frame. */
+
+ ray_3f_t nw, ne, sw, se; /* directions pointing through the corners of the frame fragment */
+ ray_3f_t cur_w, cur_e; /* current row's west and east ends */
+ float x_alpha, y_alpha; /* interpolation position along the x and y axis */
+ float x_delta, y_delta; /* interpolation step delta along the x and y axis */
+ unsigned x, y; /* integral position within frame fragment */
+} ray_camera_frame_t;
+
+
+void ray_camera_frame_begin(ray_camera_t *camera, fb_fragment_t *fragment, ray_ray_t *ray, ray_camera_frame_t *frame);
+
+
+/* Step the ray through the frame on the x axis, returns 1 when rays remain on this axis, 0 at the end. */
+/* When 1 is returned, frame->ray is left pointing through the new coordinate. */
+static inline int ray_camera_frame_x_step(ray_camera_frame_t *frame)
+{
+ frame->x++;
+
+ if (frame->x >= frame->fragment->width) {
+ frame->x = 0;
+ frame->x_alpha = frame->x_delta * (float)frame->fragment->x;
+ return 0;
+ }
+
+ frame->x_alpha += frame->x_delta;
+ frame->ray->direction = ray_3f_nlerp(&frame->cur_w, &frame->cur_e, frame->x_alpha);
+
+ return 1;
+}
+
+
+/* Step the ray through the frame on the y axis, returns 1 when rays remain on this axis, 0 at the end. */
+/* When 1 is returned, frame->ray is left pointing through the new coordinate. */
+static inline int ray_camera_frame_y_step(ray_camera_frame_t *frame)
+{
+ frame->y++;
+
+ if (frame->y >= frame->fragment->height) {
+ frame->y = 0;
+ frame->y_alpha = frame->y_delta * (float)frame->fragment->y;
+ return 0;
+ }
+
+ frame->y_alpha += frame->y_delta;
+ frame->cur_w = ray_3f_nlerp(&frame->nw, &frame->sw, frame->y_alpha);
+ frame->cur_e = ray_3f_nlerp(&frame->ne, &frame->se, frame->y_alpha);
+ frame->ray->direction = frame->cur_w;
+
+ return 1;
+}
+
+#endif
© All Rights Reserved