summaryrefslogtreecommitdiffstats
path: root/libdimension
diff options
context:
space:
mode:
Diffstat (limited to 'libdimension')
-rw-r--r--libdimension/canvas.c15
-rw-r--r--libdimension/dimension/array.h22
-rw-r--r--libdimension/gl.c15
-rw-r--r--libdimension/png.c12
-rw-r--r--libdimension/prtree.c13
-rw-r--r--libdimension/raytrace.c10
-rw-r--r--libdimension/scene.c14
7 files changed, 48 insertions, 53 deletions
diff --git a/libdimension/canvas.c b/libdimension/canvas.c
index 4ed7fd5..2c60c60 100644
--- a/libdimension/canvas.c
+++ b/libdimension/canvas.c
@@ -48,11 +48,9 @@ dmnsn_delete_canvas(dmnsn_canvas *canvas)
{
if (canvas) {
/* Free the optimizers */
- for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) {
- dmnsn_canvas_optimizer optimizer;
- dmnsn_array_get(canvas->optimizers, i, &optimizer);
- if (optimizer.free_fn) {
- (*optimizer.free_fn)(optimizer.ptr);
+ DMNSN_ARRAY_FOREACH(dmnsn_canvas_optimizer *, i, canvas->optimizers) {
+ if (i->free_fn) {
+ (*i->free_fn)(i->ptr);
}
}
dmnsn_delete_array(canvas->optimizers);
@@ -75,15 +73,12 @@ void
dmnsn_set_pixel(dmnsn_canvas *canvas, size_t x, size_t y,
dmnsn_color color)
{
- dmnsn_canvas_optimizer optimizer;
-
/* Set the pixel */
canvas->pixels[y*canvas->x + x] = color;
/* Call the optimizers */
- for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) {
- dmnsn_array_get(canvas->optimizers, i, &optimizer);
- (*optimizer.optimizer_fn)(canvas, optimizer, x, y);
+ DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) {
+ (*i->optimizer_fn)(canvas, *i, x, y);
}
}
diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h
index e3dc7b4..afd5e16 100644
--- a/libdimension/dimension/array.h
+++ b/libdimension/dimension/array.h
@@ -100,7 +100,21 @@ dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj)
memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size);
}
-/* Element access */
+/* First element */
+DMNSN_INLINE void *
+dmnsn_array_first(const dmnsn_array *array)
+{
+ return array->ptr;
+}
+
+/* Last element */
+DMNSN_INLINE void *
+dmnsn_array_last(const dmnsn_array *array)
+{
+ return (char *)array->ptr + array->obj_size*(array->length - 1);
+}
+
+/* Arbitrary element access */
DMNSN_INLINE void *
dmnsn_array_at(const dmnsn_array *array, size_t i)
{
@@ -156,4 +170,10 @@ dmnsn_array_remove(dmnsn_array *array, size_t i)
dmnsn_array_resize(array, size - 1);
}
+/* Macro to shorten array iteration */
+#define DMNSN_ARRAY_FOREACH(type, i, array) \
+ for (type i = dmnsn_array_first(array); \
+ i <= (type)dmnsn_array_last(array); \
+ ++i)
+
#endif /* DIMENSION_ARRAY_H */
diff --git a/libdimension/gl.c b/libdimension/gl.c
index 84dcc91..d07465f 100644
--- a/libdimension/gl.c
+++ b/libdimension/gl.c
@@ -32,16 +32,14 @@ static void dmnsn_gl_optimizer_fn(dmnsn_canvas *canvas,
int
dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas)
{
- dmnsn_canvas_optimizer optimizer;
-
/* Check if we've already optimized this canvas */
- for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) {
- dmnsn_array_get(canvas->optimizers, i, &optimizer);
- if (optimizer.optimizer_fn == &dmnsn_gl_optimizer_fn) {
+ DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) {
+ if (i->optimizer_fn == &dmnsn_gl_optimizer_fn) {
return 0;
}
}
+ dmnsn_canvas_optimizer optimizer;
optimizer.optimizer_fn = &dmnsn_gl_optimizer_fn;
optimizer.free_fn = &free;
@@ -67,10 +65,9 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas)
size_t height = canvas->y;
/* Check if we can optimize this */
- for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) {
- dmnsn_array_get(canvas->optimizers, i, &optimizer);
- if (optimizer.optimizer_fn == &dmnsn_gl_optimizer_fn) {
- glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_SHORT, optimizer.ptr);
+ DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) {
+ if (i->optimizer_fn == &dmnsn_gl_optimizer_fn) {
+ glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_SHORT, i->ptr);
return glGetError() == GL_NO_ERROR ? 0 : 1;
}
}
diff --git a/libdimension/png.c b/libdimension/png.c
index 021b9f2..177293c 100644
--- a/libdimension/png.c
+++ b/libdimension/png.c
@@ -39,9 +39,8 @@ dmnsn_png_optimize_canvas(dmnsn_canvas *canvas)
dmnsn_canvas_optimizer optimizer;
/* Check if we've already optimized this canvas */
- for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) {
- dmnsn_array_get(canvas->optimizers, i, &optimizer);
- if (optimizer.optimizer_fn == &dmnsn_png_optimizer_fn) {
+ DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) {
+ if (i->optimizer_fn == &dmnsn_png_optimizer_fn) {
return 0;
}
}
@@ -287,12 +286,11 @@ dmnsn_png_write_canvas_impl(dmnsn_progress *progress,
}
/* Check if we can optimize this */
- for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) {
- dmnsn_array_get(canvas->optimizers, i, &optimizer);
- if (optimizer.optimizer_fn == &dmnsn_png_optimizer_fn) {
+ DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) {
+ if (i->optimizer_fn == &dmnsn_png_optimizer_fn) {
for (size_t y = 0; y < height; ++y) {
/* Invert the rows. PNG coordinates are fourth quadrant. */
- uint16_t *row = (uint16_t *)optimizer.ptr + 4*(height - y - 1)*width;
+ uint16_t *row = (uint16_t *)i->ptr + 4*(height - y - 1)*width;
png_write_row(png_ptr, (png_bytep)row);
dmnsn_increment_progress(progress);
}
diff --git a/libdimension/prtree.c b/libdimension/prtree.c
index 04d8cc4..dc3ed38 100644
--- a/libdimension/prtree.c
+++ b/libdimension/prtree.c
@@ -430,10 +430,8 @@ dmnsn_pseudo_prtree_leaves(const dmnsn_pseudo_prtree *pseudo)
static void
dmnsn_precompute_objects(const dmnsn_array *objects)
{
- for (size_t i = 0; i < dmnsn_array_size(objects); ++i) {
- dmnsn_object *object;
- dmnsn_array_get(objects, i, &object);
- dmnsn_object_precompute(object);
+ DMNSN_ARRAY_FOREACH (dmnsn_object **, object, objects) {
+ dmnsn_object_precompute(*object);
}
}
@@ -555,12 +553,9 @@ dmnsn_prtree_search(const dmnsn_prtree *tree, dmnsn_line ray,
double t = -1.0;
/* Search the unbounded objects */
- for (size_t i = 0; i < dmnsn_array_size(tree->unbounded); ++i) {
- dmnsn_object *object;
- dmnsn_array_get(tree->unbounded, i, &object);
-
+ DMNSN_ARRAY_FOREACH (dmnsn_object **, object, tree->unbounded) {
dmnsn_intersection local_intersection;
- if ((*object->intersection_fn)(object, ray, &local_intersection)) {
+ if ((*(*object)->intersection_fn)(*object, ray, &local_intersection)) {
if (t < 0.0 || local_intersection.t < t) {
*intersection = local_intersection;
t = local_intersection.t;
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index f5d0885..0c3b738 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -315,17 +315,13 @@ dmnsn_raytrace_lighting(dmnsn_raytrace_state *state)
return;
}
- const dmnsn_light *light;
-
/* Iterate over each light */
- for (size_t i = 0; i < dmnsn_array_size(state->scene->lights); ++i) {
- dmnsn_array_get(state->scene->lights, i, &light);
-
- dmnsn_color light_color = dmnsn_raytrace_light_ray(state, light);
+ DMNSN_ARRAY_FOREACH (dmnsn_light **, light, state->scene->lights) {
+ dmnsn_color light_color = dmnsn_raytrace_light_ray(state, *light);
if (!dmnsn_color_is_black(light_color)) {
if (state->scene->quality & DMNSN_RENDER_FINISH) {
dmnsn_vector ray = dmnsn_vector_normalize(
- dmnsn_vector_sub(light->x0, state->r)
+ dmnsn_vector_sub((*light)->x0, state->r)
);
/* Get this light's color contribution to the object */
diff --git a/libdimension/scene.c b/libdimension/scene.c
index 177e7fe..58d2eda 100644
--- a/libdimension/scene.c
+++ b/libdimension/scene.c
@@ -50,17 +50,11 @@ void
dmnsn_delete_scene(dmnsn_scene *scene)
{
if (scene) {
- dmnsn_light *light;
- dmnsn_object *object;
-
- for (size_t i = 0; i < dmnsn_array_size(scene->lights); ++i) {
- dmnsn_array_get(scene->lights, i, &light);
- dmnsn_delete_light(light);
+ DMNSN_ARRAY_FOREACH (dmnsn_light **, light, scene->lights) {
+ dmnsn_delete_light(*light);
}
-
- for (size_t i = 0; i < dmnsn_array_size(scene->objects); ++i) {
- dmnsn_array_get(scene->objects, i, &object);
- dmnsn_delete_object(object);
+ DMNSN_ARRAY_FOREACH (dmnsn_object **, object, scene->objects) {
+ dmnsn_delete_object(*object);
}
dmnsn_delete_array(scene->lights);