summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdimension/Makefile.am4
-rw-r--r--libdimension/camera.c66
-rw-r--r--libdimension/dimension.h2
-rw-r--r--libdimension/dimension/camera.h47
-rw-r--r--libdimension/dimension/scene.h3
-rw-r--r--libdimension/scene.c22
-rw-r--r--tests/raytrace.c8
7 files changed, 131 insertions, 21 deletions
diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am
index 857d233..29bc268 100644
--- a/libdimension/Makefile.am
+++ b/libdimension/Makefile.am
@@ -17,10 +17,10 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>. ##
###########################################################################
-nobase_include_HEADERS = dimension.h dimension/array.h dimension/canvas.h dimension/color.h dimension/error.h dimension/geometry.h dimension/png.h dimension/object.h dimension/scene.h dimension/sphere.h
+nobase_include_HEADERS = dimension.h dimension/array.h dimension/camera.h dimension/canvas.h dimension/color.h dimension/error.h dimension/geometry.h dimension/png.h dimension/object.h dimension/scene.h dimension/sphere.h
lib_LTLIBRARIES = libdimension.la
-libdimension_la_SOURCES = $(nobase_include_HEADERS) array.c canvas.c color.c error.c geometry.c png.c object.c scene.c sphere.c
+libdimension_la_SOURCES = $(nobase_include_HEADERS) array.c camera.c canvas.c color.c error.c geometry.c png.c object.c scene.c sphere.c
libdimension_la_LDFLAGS = -version-info 0:0:0
libdimension_la_LIBADD = -lm -lpthread -lpng
diff --git a/libdimension/camera.c b/libdimension/camera.c
new file mode 100644
index 0000000..2052785
--- /dev/null
+++ b/libdimension/camera.c
@@ -0,0 +1,66 @@
+/*************************************************************************
+ * Copyright (C) 2008 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#include "dimension.h"
+#include <stdlib.h> /* For malloc */
+
+dmnsn_camera *
+dmnsn_new_camera()
+{
+ return malloc(sizeof(dmnsn_camera));
+}
+
+void
+dmnsn_delete_camera(dmnsn_camera *camera)
+{
+ free(camera);
+}
+
+/* Perspective camera */
+
+static dmnsn_line dmnsn_perspective_camera_ray_fn(const dmnsn_canvas *canvas,
+ unsigned int x,
+ unsigned int y);
+
+dmnsn_camera *
+dmnsn_new_perspective_camera()
+{
+ dmnsn_camera *camera = dmnsn_new_camera();
+ camera->ray_fn = &dmnsn_perspective_camera_ray_fn;
+ return camera;
+}
+
+void
+dmnsn_delete_perspective_camera(dmnsn_camera *camera)
+{
+ dmnsn_delete_camera(camera);
+}
+
+static dmnsn_line
+dmnsn_perspective_camera_ray_fn(const dmnsn_canvas *canvas,
+ unsigned int x, unsigned int y)
+{
+ dmnsn_line l;
+ l.x0 = dmnsn_vector_construct(0.0, 0.0, 0.0);
+ l.n.x = ((double)x)/(canvas->x - 1) - 0.5;
+ l.n.y = ((double)y)/(canvas->y - 1) - 0.5;
+ l.n.z = 1.0;
+ return l;
+}
diff --git a/libdimension/dimension.h b/libdimension/dimension.h
index e7fbe55..3eb0bae 100644
--- a/libdimension/dimension.h
+++ b/libdimension/dimension.h
@@ -32,6 +32,8 @@ extern "C" {
#include <dimension/color.h>
#include <dimension/canvas.h>
#include <dimension/object.h>
+#include <dimension/sphere.h>
+#include <dimension/camera.h>
#include <dimension/scene.h>
#include <dimension/png.h>
diff --git a/libdimension/dimension/camera.h b/libdimension/dimension/camera.h
new file mode 100644
index 0000000..b1c4ebe
--- /dev/null
+++ b/libdimension/dimension/camera.h
@@ -0,0 +1,47 @@
+/*************************************************************************
+ * Copyright (C) 2008 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#ifndef DIMENSION_CAMERA_H
+#define DIMENSION_CAMERA_H
+
+/*
+ * A camera.
+ */
+
+typedef dmnsn_line dmnsn_camera_ray_fn(const dmnsn_canvas *canvas,
+ unsigned int x, unsigned int y);
+
+typedef struct {
+ /* Generic pointer for camera info */
+ void *ptr;
+
+ /* Callback function */
+ dmnsn_camera_ray_fn *ray_fn;
+} dmnsn_camera;
+
+dmnsn_camera *dmnsn_new_camera();
+void dmnsn_delete_camera(dmnsn_camera *camera);
+
+/* A perspective camera, at the origin, looking at (0, 0, 1) */
+
+dmnsn_camera *dmnsn_new_perspective_camera();
+void dmnsn_delete_perspective_camera(dmnsn_camera *camera);
+
+#endif /* DIMENSION_CAMERA_H */
diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h
index e075cdd..a6f2e5d 100644
--- a/libdimension/dimension/scene.h
+++ b/libdimension/dimension/scene.h
@@ -28,10 +28,11 @@
typedef struct {
dmnsn_color background;
dmnsn_array *objects;
+ dmnsn_camera *camera;
dmnsn_canvas *canvas;
} dmnsn_scene;
-dmnsn_scene *dmnsn_new_scene(unsigned int x, unsigned int y);
+dmnsn_scene *dmnsn_new_scene();
void dmnsn_delete_scene(dmnsn_scene *scene);
void dmnsn_raytrace_scene(dmnsn_scene *scene);
diff --git a/libdimension/scene.c b/libdimension/scene.c
index 541e3ba..780f8c6 100644
--- a/libdimension/scene.c
+++ b/libdimension/scene.c
@@ -22,19 +22,11 @@
#include <stdlib.h> /* For malloc */
dmnsn_scene *
-dmnsn_new_scene(unsigned int x, unsigned int y)
+dmnsn_new_scene()
{
dmnsn_scene *scene = malloc(sizeof(dmnsn_scene));
- if (scene) {
+ if (scene)
scene->objects = dmnsn_new_array(sizeof(dmnsn_object*));
-
- scene->canvas = dmnsn_new_canvas(x, y);
- if (!scene->canvas) {
- dmnsn_delete_array(scene->objects);
- return NULL;
- }
- }
-
return scene;
}
@@ -52,18 +44,14 @@ dmnsn_raytrace_scene(dmnsn_scene *scene)
{
unsigned int i, j;
dmnsn_object *object;
- dmnsn_line l;
+ dmnsn_line ray;
- l.x0 = dmnsn_vector_construct(0.0, 0.0, -3.0);
dmnsn_array_get(scene->objects, 0, &object);
for (i = 0; i < scene->canvas->x; ++i) {
for (j = 0; j < scene->canvas->y; ++j) {
- l.n.x = 1.6*(((double)i)/(scene->canvas->x - 1) - 0.5);
- l.n.y = ((double)j)/(scene->canvas->y - 1) - 0.5;
- l.n.z = 1.0;
-
- if ((*object->intersections_fn)(l)->length > 0) {
+ ray = (*scene->camera->ray_fn)(scene->canvas, i, j);
+ if ((*object->intersections_fn)(ray)->length > 0) {
dmnsn_set_pixel(scene->canvas, i, j,
dmnsn_color_from_XYZ(dmnsn_whitepoint));
} else {
diff --git a/tests/raytrace.c b/tests/raytrace.c
index 7a5f3aa..15c5d70 100644
--- a/tests/raytrace.c
+++ b/tests/raytrace.c
@@ -31,7 +31,9 @@ int main() {
dmnsn_set_resilience(DMNSN_SEVERITY_LOW);
- scene = dmnsn_new_scene(768, 480);
+ scene = dmnsn_new_scene();
+ scene->canvas = dmnsn_new_canvas(768, 480);
+ scene->camera = dmnsn_new_perspective_camera();
sRGB.R = 0.0;
sRGB.G = 0.0;
@@ -48,5 +50,9 @@ int main() {
file = fopen("raytrace.png", "wb");
dmnsn_png_write_canvas(scene->canvas, file);
+ dmnsn_delete_perspective_camera(scene->camera);
+ dmnsn_delete_canvas(scene->canvas);
+ dmnsn_delete_scene(scene);
+
return EXIT_SUCCESS;
}