summaryrefslogtreecommitdiffstats
path: root/doc/libdimension.texi
diff options
context:
space:
mode:
Diffstat (limited to 'doc/libdimension.texi')
-rw-r--r--doc/libdimension.texi1032
1 files changed, 0 insertions, 1032 deletions
diff --git a/doc/libdimension.texi b/doc/libdimension.texi
deleted file mode 100644
index 5939a20..0000000
--- a/doc/libdimension.texi
+++ /dev/null
@@ -1,1032 +0,0 @@
-\input texinfo @c -*- Texinfo -*-
-@c %**start of header
-@setfilename libdimension.info
-@settitle The Dimension 3-D Rendering Library
-@c %**end of header
-
-@c Combine variable and function indicies
-@syncodeindex vr fn
-
-@c Wrap code examples at 72 chars, please
-
-@copying
-Copyright @copyright{} 2009-2010 Tavian Barnes
-@end copying
-
-@titlepage
-@title The Dimension Library
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@contents
-
-@ifnottex
-@node Top
-@top The Dimension Library
-
-@insertcopying
-@end ifnottex
-
-@menu
-* Introduction:: An introduction to the Dimension Library
-* Error Handling:: How libdimension handles warnings and errors
-* Arrays:: A generic interface for arrays of arbitrary objects
-* Lists:: A generic interface for lists of arbitrary objects
-* Asynchronicity:: An interface for controlling background tasks
-* Geometry:: Geometric types like vectors, transformation matricies, and lines
-* Color:: Correct color handling
-* Canvases:: Where the results of rendering are stored
-* Objects:: Physical objects in a scene
-* Cameras:: How a 3-D image is seen in 2-D
-* Scenes:: Scene objects which hold everything needed to render an image
-* Type Index::
-* Function and Constant Index::
-* Concept Index::
-@end menu
-
-
-@node Introduction
-@chapter Introduction
-
-@cindex introduction
-@cindex overview
-The Dimension Library is a C library for rendering photo-realistic 3-D scenes.
-It is the workhorse for the ``dimension'' program.
-The Dimension Library is currently in the very early stages of development, but does support rendering scenes with transparency and reflection.
-
-The C library is probably not the interface you want to use; the ``dimension'' program will render scenes specified in POV-Ray's Scene Description Language.
-This documentation gives a bottom-up overview of the Dimension Library, to allow readers to have a full and complete understanding of the library, rather than a simple top-down overview.
-
-@menu
-* Common Definitions:: Definitions used across the Dimension Library
-* Memory Allocation:: Wrappers for malloc() and friends
-@end menu
-
-@node Common Definitions
-@section Common Definitions
-
-@example
-@tindex dmnsn_free_fn
-typedef void dmnsn_free_fn(void *ptr);
-@end example
-
-@code{dmnsn_free_fn} is a type whose signature matches that of @code{free()}, and which is used as a destructor callback type across the Dimension Library.
-
-@node Memory Allocation
-@section Memory Allocation
-@example
-@findex dmnsn_malloc()
-void *dmnsn_malloc(size_t size);
-@findex dmnsn_realloc()
-void *dmnsn_realloc(void *ptr, size_t size);
-@findex dmnsn_strdup()
-char *dmnsn_strdup(const char *s);
-@end example
-
-@code{dmnsn_malloc()} is a wrapper for @code{malloc()} which is guaranteed to have succeeded if it returns, hence eliminating the need for checking its return value for @code{NULL}.
-If @code{malloc()} should fail, @code{dmnsn_malloc()} reports an error with @code{dmnsn_error()}, which cancels the calling thread (@pxref{Error Handling}).
-@code{dmnsn_realloc()} and @code{dmnsn_strdup()} behave similarly, wrapping @code{realloc()} and @code{strdup()} respectively.
-
-
-@node Error Handling
-@chapter Error Handling
-
-@example
-@tindex dmnsn_severity
-typedef enum @{
- @vindex DMNSN_SEVERITY_LOW
- DMNSN_SEVERITY_LOW, /* Only die on low resilience */
- @vindex DMNSN_SEVERITY_MEDIUM
- DMNSN_SEVERITY_MEDIUM, /* Die on low or medium resilience */
- @vindex DMNSN_SEVERITY_HIGH
- DMNSN_SEVERITY_HIGH /* Always die */
-@} dmnsn_severity;
-
-@findex dmnsn_error()
-#define dmnsn_error(severity, str) /* ... */
-
-@findex dmnsn_assert()
-#define dmnsn_assert(expression, str) /* ... */
-
-@findex dmnsn_get_resilience()
-dmnsn_severity dmnsn_get_resilience();
-@findex dmnsn_set_resilience()
-void dmnsn_set_resilience(dmnsn_severity resilience);
-@end example
-
-@cindex errors
-@cindex warnings
-When it makes sense, libdimension reports errors by returning error codes from its functions.
-However, when errors are not severe, when said function should not fail, or when the error is very serious, libdimension reports errors using the macro @code{dmnsn_error()}.
-@code{dmnsn_error()} takes two parameters: the severity of the error, and a string description of the error.
-The macro will conveniently report the description, as well as the function name and code line where the error occured, to standard error.
-The severity can be either @code{DMNSN_SEVERITY_LOW}, @code{DMNSN_SEVERITY_MEDIUM}, or @code{DMNSN_SEVERITY_HIGH}.
-
-@code{dmnsn_assert()} is used for checking invariants.
-Like @code{assert()}, when @code{NDEBUG} is defined, this macro generates no code.
-However, when @code{NDEBUG} is not defined and @code{expression} evaluates to @code{false}, @code{dmnsn_assert()} will terminate the current thread with @code{dmnsn_error(DMNSN_SEVERITY_HIGH, str)}.
-
-@cindex resilience
-The Dimension Library has also has a user-settable resilience.
-The resilience controls the minimum severity at which the library considers an error to be fatal, and terminates the calling thread.
-As such, errors of severity @code{DMNSN_SEVERITY_HIGH} are always fatal.
-libdimension's resilience defaults to @code{DMNSN_SEVERITY_MEDIUM}, but can be inspected or changed thread-safely by @code{dmnsn_get_resilience()} or @code{dmnsn_set_resilience()}, respectively.
-Warnings (non-fatal errors) are formatted like this:
-
-@example
-Dimension WARNING: <function>, <file>:<line>: <description>
-@end example
-
-@noindent while errors are formatted like this:
-
-@example
-Dimension ERROR: <function>, <file>:<line>: <description>
-@end example
-
-@noindent possibly followed by a backtrace.
-
-
-@node Arrays
-@chapter Arrays
-
-@example
-@tindex dmnsn_array *
-typedef struct @{
- /* ... */
-@} dmnsn_array;
-
-/* Array allocation */
-@findex dmnsn_new_array()
-dmnsn_array *dmnsn_new_array(size_t obj_size);
-@findex dmnsn_delete_array()
-void dmnsn_delete_array(dmnsn_array *array);
-
-@findex dmnsn_array_push()
-void dmnsn_array_push(dmnsn_array *array, const void *obj);
-@findex dmnsn_array_pop()
-void dmnsn_array_pop(dmnsn_array *array, void *obj);
-@findex dmnsn_array_get()
-void dmnsn_array_get(const dmnsn_array *array, size_t i, void *obj);
-@findex dmnsn_array_set()
-void dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj);
-
-@findex dmnsn_array_first()
-void *dmnsn_array_first(const dmnsn_array *array);
-@findex dmnsn_array_last()
-void *dmnsn_array_last(const dmnsn_array *array);
-@findex dmnsn_array_at()
-void *dmnsn_array_at(const dmnsn_array *array, size_t i);
-
-@findex dmnsn_array_insert()
-void dmnsn_array_insert(dmnsn_array *array, size_t i, const void *obj)
-@findex dmnsn_array_remove()
-void dmnsn_array_remove(dmnsn_array *array, size_t i)
-
-@findex dmnsn_array_size()
-size_t dmnsn_array_size(const dmnsn_array *array);
-@findex dmnsn_array_resize()
-void dmnsn_array_resize(dmnsn_array *array, size_t length);
-
-@findex DMNSN_ARRAY_FOREACH ()
-#define DMNSN_ARRAY_FOREACH (type, i, array) /* ... */
-@end example
-
-@cindex array
-The Dimension Library often has cause to work with adjustable-size arrays.
-It provides an interface for dynamically-allocated arrays of arbitrary objects.
-Arrays are allocated with the @code{dmnsn_new_array()} function, and freed with the @code{dmnsn_delete_array()} function, a pattern common in libdimension.
-@code{dmnsn_new_array()} takes the size of the new array's elements as its parameter.
-
-Arrays support the push, pop, get, set, insert, and remove operations for arrays, taking a pointer to an object to read or write as their last parameter, the array index (when applicable) as the second-last parameter, and the @code{dmnsn_array *} as the first parameter.
-The get, remove, and pop operations are bounds-checked; other operations dynamically resize the array as needed.
-The array's length may be queried with @code{dmnsn_array_size()}, or set with @code{dmnsn_array_resize()}.
-A pointer to the first object is returned by @code{dmnsn_array_first()}, the last object by @code{dmnsn_array_last()}, and a pointer to the @code{i}'th object may be obtained with @code{dmnsn_array_at()}.
-
-The @code{DMNSN_ARRAY_FOREACH ()} macro expands to an appropriate for loop iterating over an array.
-@code{type} should be a type that points to the type of objects in the array, @code{i} will be the name of the pointer which iterates over the array, and @code{array} is the array to iterate over. For example:
-
-@example
-DMNSN_ARRAY_FOREACH (int *, i, array) @{
- printf("%d\n", *i);
-@}
-@end example
-
-
-@node Lists
-@chapter Lists
-
-@example
-@tindex dmnsn_list *
-typedef struct @{
- /* ... */
-@} dmnsn_list;
-
-@tindex dmnsn_list_iterator *
-typedef struct @{
- /* ... */
-@} dmnsn_list_iterator;
-
-/* List allocation */
-@findex dmnsn_new_list()
-dmnsn_array *dmnsn_new_list(size_t obj_size);
-@findex dmnsn_delete_list()
-void dmnsn_delete_list(dmnsn_array *array);
-
-/* Construction to/from arrays */
-@findex dmnsn_list_from_array()
-dmnsn_list *dmnsn_list_from_array(const dmnsn_array *array);
-@findex dmnsn_array_from_list()
-dmnsn_array *dmnsn_array_from_list(const dmnsn_list *list);
-
-/* Iteration */
-
-@findex dmnsn_list_first()
-dmnsn_list_iterator *dmnsn_list_first(const dmnsn_list *list);
-@findex dmnsn_list_last()
-dmnsn_list_iterator *dmnsn_list_last(const dmnsn_list *list);
-@findex dmnsn_list_size()
-size_t dmnsn_list_size(const dmnsn_list *list);
-
-@findex dmnsn_list_prev()
-dmnsn_list_iterator *dmnsn_list_prev(const dmnsn_list_iterator *i);
-@findex dmnsn_list_next()
-dmnsn_list_iterator *dmnsn_list_next(const dmnsn_list_iterator *i);
-
-/* Element access */
-@findex dmnsn_list_get()
-void dmnsn_list_get(const dmnsn_list_iterator *i, void *obj);
-@findex dmnsn_list_set()
-void dmnsn_list_set(dmnsn_list_iterator *i, const void *obj);
-@findex dmnsn_list_swap()
-void dmnsn_list_swap(dmnsn_list_iterator *a, dmnsn_list_iterator *b);
-
-/* Insertion/removal */
-@findex dmnsn_list_push()
-void dmnsn_list_push(dmnsn_list *list, const void *obj);
-@findex dmnsn_list_pop()
-void dmnsn_list_pop(dmnsn_list *list, void *obj);
-@findex dmnsn_list_insert()
-void dmnsn_list_insert(dmnsn_list *list, dmnsn_list_iterator *i,
- const void *obj)
-@findex dmnsn_list_remove()
-void dmnsn_list_remove(dmnsn_list *list, dmnsn_list_iterator *i)
-
-/* Splits a list in half, and returns the second half */
-@findex dmnsn_list_split()
-dmnsn_list *dmnsn_list_split(dmnsn_list *list);
-
-/* Sort a list */
-@tindex dmnsn_list_comparator_fn
-typedef bool dmnsn_list_comparator_fn(dmnsn_list_iterator *l,
- dmnsn_list_iterator *r);
-@findex dmnsn_list_sort()
-void dmnsn_list_sort(dmnsn_list *list,
- dmnsn_list_comparator_fn *comparator);
-@end example
-
-@cindex list
-Generic doubly-linked lists are also provided by the Dimension Library.
-They are allocated and freed by @code{dmnsn_new_list()} and @code{dmnsn_delete_list()}, respectively.
-They can also be constructed from @code{dmnsn_array *}'s by @code{dmnsn_list_from_array()}, and converted to @code{dmnsn_array *}'s by @code{dmnsn_array_from_list()}.
-
-List elements are accessed with an iterator type, @code{dmnsn_list_iterator *}.
-The previous or next list element is found with @code{dmnsn_list_prev()} or @code{dmnsn_list_next()}, respectively.
-@code{NULL} indicates that you've fallen off the beginning or end of the list.
-An iterator to the first or last element of a list is obtained with @code{dmnsn_list_first()} or @code{dmnsn_list_last()}.
-The size of a list is given by @code{dmnsn_list_size()}.
-
-An object can be retrieved from a @code{dmnsn_list_iterator *} with @code{dmnsn_list_get()}, and set with @code{dmnsn_list_set()}. The objects of two list iterators can be swapped with @code{dmnsn_list_swap()}.
-
-Objects can be added or removed from the end of a list with @code{dmnsn_list_push()} and @code{dmnsn_list_pop()}.
-Elements can be added at arbitrary locations with @code{dmnsn_list_insert()}, which inserts the object before the iterator @code{i} (pass NULL to insert it at the end).
-The element at @code{i} can be removed with @code{dmnsn_list_remove()}.
-
-@code{dmnsn_list_split()} splits the given list in half, and returns the second, possibly smaller half.
-
-@code{dmnsn_list_sort()} sorts a given list, using a comparison function matching the signature of the @code{dmnsn_list_comparator_fn} type.
-
-
-@node Asynchronicity
-@chapter Asynchronicity
-
-@example
-@tindex dmnsn_progress *
-typedef struct @{
- /* ... */
-@} dmnsn_progress;
-
-/* Progress allocation */
-@findex dmnsn_new_progress()
-dmnsn_progress *dmnsn_new_progress();
-@findex dmnsn_delete_progress()
-void dmnsn_delete_progress(dmnsn_progress *progress);
-
-/* Ensures completion of the worker thread */
-@findex dmnsn_finish_progress()
-int dmnsn_finish_progress(dmnsn_progress *progress);
-
-/* Routines for users */
-@findex dmnsn_get_progress()
-double dmnsn_get_progress(const dmnsn_progress *progress);
-@findex dmnsn_wait_progress()
-void dmnsn_wait_progress(const dmnsn_progress *progress, double prog);
-
-/* Routines for worker threads */
-@findex dmnsn_new_progress_element()
-void dmnsn_new_progress_element(dmnsn_progress *progress,
- unsigned int total);
-@findex dmnsn_increment_progress()
-void dmnsn_increment_progress(dmnsn_progress *progress);
-@findex dmnsn_done_progress()
-void dmnsn_done_progress(dmnsn_progress *progress);
-@end example
-
-@cindex asynchronous task
-@cindex background task
-@cindex progress indicator
-As the Dimension Library is a raytracing engine, some routines are likely to take a long time.
-These routines may be run in a background thread, and controlled with a common interface.
-Routines supporting this interface end in @code{_async}, such as @code{dmnsn_raytrace_scene_async()}, and return a @code{dmnsn_progress *} object, so named because it allows an application to be query the progress of the background task.
-By necessity, all @code{dmnsn_progress *} operations are atomic and thread-safe.
-
-Progress objects are allocated and deallocated in the standard libdimension way, but also support a unique @code{dmnsn_finish_progress()} function.
-This function waits for the background thread to complete, and then destroys the @code{dmnsn_progress *} object.
-Never use the result of a background task before calling @code{dmnsn_finish_progress()}, even if the progress seems to be at 100%! @code{dmnsn_delete_progress()} should only be called from within failed @code{*_async()} functions, to deallocate a progress object before it is associated with a running thread.
-
-Users of these asynchronous tasks will mainly be interested in the functions @code{dmnsn_get_progress()} and @code{dmnsn_wait_progress()}.
-@code{dmnsn_get_progress()} returns the progress of the background task, a value between 0.0 and 1.0.
-@code{dmnsn_wait_progress()} simply waits for @code{dmnsn_get_progress()} to be >= @code{prog}, but in a much better way than spinlocking (internally, a condition variable is used).
-
-Background tasks themselves will be interested in three more functions.
-To indicate progress to the user, progress objects store one "element" for each level of loop nesting a task would like to report the progress of.
-Only the innermost loop need increment the progress counter, as in this example:
-
-@example
-dmnsn_new_progress_element(progress, i_max);
-for (i = 0; i < i_max; ++i) @{
- dmnsn_new_progress_element(progress, j_max);
- for (j = 0; j < j_max; ++j) @{
- /* Do stuff */
- dmnsn_increment_progress(progress);
- @}
-@}
-@end example
-
-For robustness, tasks should call @code{dmnsn_done_progress()} when they finish, even if they fail.
-This function immediately sets the progress to 100%, which wakes up all waiters.
-Otherwise, a user's application may hang calling @code{dmnsn_wait_progress()}.
-
-
-@node Geometry
-@chapter Geometry
-
-@example
-/* Vector and matrix types. */
-
-@tindex dmnsn_vector
-typedef struct @{
- double x, y, z;
-@} dmnsn_vector;
-
-@tindex dmnsn_matrix
-typedef struct @{
- double n[4][4];
-@} dmnsn_matrix;
-
-/* A line, or ray. */
-@tindex dmnsn_line
-typedef struct @{
- dmnsn_vector x0; /* A point on the line */
- dmnsn_vector n; /* A normal vector; the direction of the line */
-@} dmnsn_line;
-
-@tindex dmnsn_bounding_box
-typedef struct @{
- dmnsn_vector min;
- dmnsn_vector max;
-@} dmnsn_bounding_box;
-
-/* Vector/matrix construction */
-
-@findex dmnsn_new_vector()
-dmnsn_vector dmnsn_new_vector(double x, double y, double z);
-
-@findex dmnsn_new_matrix()
-dmnsn_matrix
-dmnsn_new_matrix(double a0, double a1, double a2, double a3,
- double b0, double b1, double b2, double b3,
- double c0, double c1, double c2, double c3,
- double d0, double d1, double d2, double d3);
-
-@findex dmnsn_identity_matrix()
-dmnsn_matrix dmnsn_identity_matrix();
-@findex dmnsn_scale_matrix()
-dmnsn_matrix dmnsn_scale_matrix(dmnsn_vector s);
-@findex dmnsn_translation_matrix()
-dmnsn_matrix dmnsn_translation_matrix(dmnsn_vector d);
-@findex dmnsn_rotation_matrix()
-dmnsn_matrix dmnsn_rotation_matrix(dmnsn_vector theta);
-
-@findex dmnsn_new_line()
-dmnsn_line dmnsn_new_line(dmnsn_vector x0, dmnsn_vector n);
-
-/* Vector and matrix arithmetic */
-
-@findex dmnsn_vector_add()
-dmnsn_vector dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs);
-@findex dmnsn_vector_sub()
-dmnsn_vector dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs);
-@findex dmnsn_vector_mul()
-dmnsn_vector dmnsn_vector_mul(double lhs, dmnsn_vector rhs);
-@findex dmnsn_vector_div()
-dmnsn_vector dmnsn_vector_div(dmnsn_vector lhs, double rhs);
-
-@findex dmnsn_vector_dot()
-double dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs);
-@findex dmnsn_vector_cross()
-dmnsn_vector dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs);
-
-@findex dmnsn_vector_norm()
-double dmnsn_vector_norm(dmnsn_vector n);
-@findex dmnsn_vector_normalize()
-dmnsn_vector dmnsn_vector_normalize(dmnsn_vector n);
-
-@findex dmnsn_matrix_inverse()
-dmnsn_matrix dmnsn_matrix_inverse(dmnsn_matrix A);
-@findex dmnsn_matrix_mul()
-dmnsn_matrix dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs);
-@findex dmnsn_transform_vector()
-dmnsn_vector dmnsn_transform_vector(dmnsn_matrix lhs,
- dmnsn_vector rhs);
-@findex dmnsn_transform_bounding_box()
-dmnsn_bounding_box dmnsn_transform_bounding_box(dmnsn_matrix lhs,
- dmnsn_bounding_box rhs);
-@findex dmnsn_transform_line()
-dmnsn_line dmnsn_transform_line(dmnsn_matrix lhs, dmnsn_line rhs);
-
-@findex dmnsn_line_point()
-dmnsn_vector dmnsn_line_point(dmnsn_line l, double t);
-@findex dmnsn_line_index()
-double dmnsn_line_index(dmnsn_line l, dmnsn_vector x);
-@end example
-
-@cindex scalar
-@cindex vector
-@cindex matrix
-@cindex line
-@cindex ray
-For performing 3-D computational geometry, the Dimension Library supports geometric types and many operations on these types.
-libdimension defines the @code{dmnsn_vector}, @code{dmnsn_matrix}, and @code{dmnsn_line} geometric types.
-They may be easily constructed by the self-explanatory @code{dmnsn_new_vector()}, @code{dmnsn_new_matrix()}, or @code{dmnsn_new_line()}.
-
-@cindex transformation
-@cindex norm
-@cindex normalization
-@cindex dot product
-@cindex cross product
-Vectors support addition and subtraction, multiplication and division by a scalar, the dot and cross products, the norm and normalization operations, and transformation by a matrix (@code{dmnsn_transform_vector()}).
-
-@cindex matrix inversion
-Matricies support matrix multiplication, and inversion.
-Inversion uses a very fast partitioning algorithm.
-As well, there are four special matrix constructors.
-@code{dmnsn_identity_matrix()} simply returns the identity matrix.
-@code{dmnsn_scale_matrix(s)} returns a matrix which scales each dimension by a factor of the corresponding dimension of the @code{s}.
-@code{dmnsn_translate_matrix(d)} returns a matrix which translates by @code{d}.
-Finally, @code{dmnsn_rotation_matrix(theta)} returns a matrix which rotates by an angle of @code{dmnsn_vector_norm(theta)}, about the axis @code{dmnsn_vector_normalize(theta)}.
-
-Lines support transformation by a matrix (@code{dmnsn_transform_line(A, l) = dmnsn_new_line(A*l.x0, A*(l.x0 + l.n) - A*l.x0)}).
-Also, @code{dmnsn_line_point(l, t) = l.x0 + t*l.n} gives the point @code{t} on the line, and @code{dmnsn_line_index(l, x)} gives the @code{t} value such that @code{dmnsn_line_point(l, t) == x}.
-
-@cindex bounding boxes
-@cindex axis-aligned bounding boxes
-Axis-aligned bounding boxes are represented by the @code{dmnsn_bounding_box} type, with their minimum extent in the @code{.min} field, and their maximum extent in the @code{.max} field.
-They may be transformed by a matrix with @code{dmnsn_transform_bounding_box()}.
-
-
-@node Color
-@chapter Color
-
-@example
-@tindex dmnsn_color
-typedef struct @{
- double filter, trans; /* Filter transparancy only lets light of this
- color through; regular transparancy lets all
- colors through. filter + trans should be
- <= 1.0. */
- /* ... */
-@} dmnsn_color;
-
-@tindex dmnsn_CIE_XYZ
-typedef struct @{
- double X, Y, Z; /* X, Y, and Z are tristimulus values, unbounded
- above zero.
-Diffuse white is (0.9505, 1,
- 1.089). */
-@} dmnsn_CIE_XYZ;
-
-@tindex dmnsn_CIE_xyY
-typedef struct @{
- double x, y, Y; /* x and y are chromaticity coordinates, and Y is
- luminance, in the CIE 1931 xyZ color space.
-We
- use an unlimited light model, so x,y in [0, 1] and
- Y >= 0, with 1 = diffuse white */
-@} dmnsn_CIE_xyY;
-
-@tindex dmnsn_CIE_Lab
-typedef struct @{
- double L, a, b; /* L is luminence (100 = diffuse white); a and b are
- color-opponent dimensions.
-This color space is
- used for color arithmetic. */
-@} dmnsn_CIE_Lab;
-
-@tindex dmnsn_CIE_Luv
-typedef struct @{
- double L, u, v; /* L is luminence (100 = diffuse white); u and v are
- chromaticity coordinates. */
-@} dmnsn_CIE_Luv;
-
-@tindex dmnsn_sRGB
-typedef struct @{
- double R, G, B; /* sRGB R, G, and B values */
-@} dmnsn_sRGB;
-
-/* Standard colors */
-@vindex dmnsn_black
-@vindex dmnsn_white
-@vindex dmnsn_red
-@vindex dmnsn_green
-@vindex dmnsn_blue
-@vindex dmnsn_magenta
-@vindex dmnsn_yellow
-@vindex dmnsn_cyan
-extern const dmnsn_color dmnsn_black, dmnsn_white, dmnsn_red,
- dmnsn_green, dmnsn_blue, dmnsn_magenta, dmnsn_yellow, dmnsn_cyan;
-
-/* Standard whitepoint, determined by the conversion of sRGB white to
- CIE XYZ */
-@vindex dmnsn_whitepoint
-extern const dmnsn_CIE_XYZ dmnsn_whitepoint;
-
-/* Color conversions */
-
-@findex dmnsn_color_from_XYZ()
-dmnsn_color dmnsn_color_from_XYZ(dmnsn_CIE_XYZ XYZ);
-@findex dmnsn_color_from_xyY()
-dmnsn_color dmnsn_color_from_xyY(dmnsn_CIE_xyY xyY);
-@findex dmnsn_color_from_Lab()
-dmnsn_color dmnsn_color_from_Lab(dmnsn_CIE_Lab Lab,
- dmnsn_CIE_XYZ white);
-@findex dmnsn_color_from_Luv()
-dmnsn_color dmnsn_color_from_Luv(dmnsn_CIE_Luv Luv,
- dmnsn_CIE_XYZ white);
-@findex dmnsn_color_from_sRGB()
-dmnsn_color dmnsn_color_from_sRGB(dmnsn_sRGB sRGB);
-
-@findex dmnsn_XYZ_from_color()
-dmnsn_CIE_XYZ dmnsn_XYZ_from_color(dmnsn_color color);
-@findex dmnsn_xyY_from_color()
-dmnsn_CIE_xyY dmnsn_xyY_from_color(dmnsn_color color);
-@findex dmnsn_Lab_from_color()
-dmnsn_CIE_Lab dmnsn_Lab_from_color(dmnsn_color color,
- dmnsn_CIE_XYZ white);
-@findex dmnsn_Luv_from_color()
-dmnsn_CIE_Luv dmnsn_Luv_from_color(dmnsn_color color,
- dmnsn_CIE_XYZ white);
-@findex dmnsn_sRGB_from_color()
-dmnsn_sRGB dmnsn_sRGB_from_color(dmnsn_color color);
-
-/* Is this color black? */
-@findex dmsnn_color_is_black()
-bool dmnsn_color_is_black(dmnsn_color color);
-
-/* Perceptual color manipulation */
-@findex dmnsn_color_add()
-dmnsn_color dmnsn_color_add(dmnsn_color color1, dmnsn_color color2);
-@findex dmnsn_color_mul()
-dmnsn_color dmnsn_color_mul(double n, dmnsn_color color);
-@findex dmnsn_color_gradient()
-dmnsn_color dmnsn_color_gradient(dmnsn_color c1, dmnsn_color c2,
- double n);
-@findex dmnsn_color_filter()
-dmnsn_color dmnsn_color_filter(dmnsn_color color, dmnsn_color filter);
-@findex dmnsn_color_illuminate()
-dmnsn_color dmnsn_color_illuminate(dmnsn_color light,
- dmnsn_color color);
-
-/* Perceptual color difference */
-@findex dmnsn_color_difference()
-double dmnsn_color_difference(dmnsn_color color1, dmnsn_color color2);
-@end example
-
-@cindex color
-@cindex CIE XYZ
-@cindex CIE xyY
-@cindex CIE L*a*b*
-@cindex CIE L*u*v*
-@cindex sRGB
-@cindex RGB
-The Dimension Library supports many different representations of color.
-The details of each representation are beyond the scope of this manual, but libdimension supports CIE XYZ, xyY, L*a*b*, L*u*v*, and sRGB color.
-CIE L*a*b* and L*u*v* are designed to be perceptually uniform, meaning changes in their color coordinates correspond to perceptual changes of equal magnitude.
-The @code{dmnsn_color} type is used by libdimension itself to represent colors, internally in the sRGB color space.
-The @code{.filter} field gives the color's filtered transparency, which lets same-colored light through, while the @code{.trans} field stores non-filtered transparency.
-
-The @code{dmnsn_color_from_*()} and @code{dmnsn_*_from_color()} functions are used to convert to and from the @code{dmnsn_color} type.
-The conversions to @code{dmnsn_color} set the @code{.filter} and @code{.trans} fields to zero, and those fields are ignored by the inverse conversions.
-Conversions to and from CIE L*a*b* and L*u*v* colors take an extra parameter, which specifies the absolute color value of the whitepoint the conversions are relative to.
-@code{dmnsn_whitepoint} is a good value for this parameter.
-
-@code{dmnsn_color_add()} adds two colors in a perceptually-correct way.
-@code{dmnsn_color_mul()} scales the brightness of a color.
-@code{dmnsn_color_gradient()} returns the color at point @code{n} on a gradient from @code{c1} at 0 to @code{c2} at 1.
-@code{dmnsn_color_filter()} returns the color obtained by filtering @code{color} through @code{filter}.
-@code{dmnsn_color_illuminate()} return the color obtained by illuminating @code{color} with @code{light}-colored light.
-@code{dmnsn_color_difference()} returns the magnatude of the perceptual difference between two colors.
-
-
-@node Canvases
-@chapter Canvases
-
-@example
-@tindex dmnsn_canvas *
-typedef struct @{
- /* width, height */
- unsigned int x, y;
-
- /* An array of dmnsn_canvas_optimizer's - see below */
- dmnsn_array *optimizers;
-
- /* ... */
-@} dmnsn_canvas;
-
-/* Allocate and free a canvas */
-@findex dmnsn_new_canvas()
-dmnsn_canvas *dmnsn_new_canvas(unsigned int x, unsigned int y);
-@findex dmnsn_delete_canvas()
-void dmnsn_delete_canvas(dmnsn_canvas *canvas);
-
-/* Pixel accessors */
-@findex dmnsn_get_pixel()
-dmnsn_color dmnsn_get_pixel(const dmnsn_canvas *canvas,
- unsigned int x, unsigned int y);
-@findex dmnsn_set_pixel()
-void dmnsn_set_pixel(dmnsn_canvas *canvas,
- unsigned int x, unsigned int y,
- dmnsn_color color);
-@end example
-
-@cindex canvas
-@cindex rendering target
-The target of a rendering operation in the Dimension Library is a canvas object, represented by the type @code{dmnsn_canvas *}.
-This type stores the dimensions of the canvas in the @code{->x} and @code{->y} fields.
-The pixel at (x,y) can be examined or set by the accessors @code{dmnsn_get_pixel()} and @code{dmnsn_set_pixel()}.
-
-Canvases may be imported from or exported to images.
-In the future, canvases will also be able to be treated as object textures, to support images as textures.
-
-@menu
-* PNG Import and Export:: Importing and exporting canvases to and from PNG files
-* OpenGL:: Drawing and reading canvases to and from OpenGL buffers
-* Canvas Optimization:: Optimizing a canvas for a later export
-@end menu
-
-@node PNG Import and Export
-@section PNG Import and Export
-
-@example
-/* Optimize canvas for PNG exporting */
-@findex dmnsn_png_optimize_canvas()
-int dmnsn_png_optimize_canvas(dmnsn_canvas *canvas);
-
-/* Write canvas to file in PNG format. Returns 0 on success, nonzero
- on failure */
-@findex dmnsn_png_write_canvas()
-int dmnsn_png_write_canvas(const dmnsn_canvas *canvas, FILE *file);
-@findex dmnsn_png_write_canvas_async()
-dmnsn_progress *
-dmnsn_png_write_canvas_async(const dmnsn_canvas *canvas, FILE *file);
-
-/* Read a canvas from a PNG file.
-Returns NULL on failure. */
-@findex dmnsn_png_read_canvas()
-dmnsn_canvas *dmnsn_png_read_canvas(FILE *file);
-@findex dmnsn_png_read_canvas_async()
-dmnsn_progress *dmnsn_png_read_canvas_async(dmnsn_canvas **canvas,
- FILE *file);
-@end example
-
-@cindex PNG
-The Dimension Library supports import and export of canvas to and from PNG files; this is currently the only supported image type.
-The interface is simple: @code{dmnsn_png_write_canvas()} writes the canvas in PNG format to the given file, at maximum quality; @code{dmnsn_png_read_canvas()} imports a PNG file to a canvas.
-The @code{*_async()} versions work as described in @ref{Asynchronicity}.
-If it is known in advance that a canvas will be exported to a PNG file, calling @code{dmnsn_png_optimize_canvas()} on it before it is written to will speed up the export process; see @ref{Canvas Optimization}.
-
-@node OpenGL
-@section OpenGL
-
-@example
-/* Optimize canvas for GL drawing */
-@findex dmnsn_gl_optimize_canvas()
-int dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas);
-
-/* Write canvas to GL framebuffer. Returns 0 on success, nonzero on
- failure. */
-@findex dmnsn_gl_write_canvas()
-int dmnsn_gl_write_canvas(const dmnsn_canvas *canvas);
-
-/* Read a canvas from a GL framebuffer.
-Returns NULL on failure. */
-@findex dmnsn_gl_read_canvas()
-dmnsn_canvas *dmnsn_gl_read_canvas(unsigned int x0, unsigned int y0,
- unsigned int width,
- unsigned int height);
-@end example
-
-@cindex GL
-@cindex OpenGL
-Canvases may be written to or read from an OpenGL buffer with the @code{dmnsn_gl_write_canvas()} and @code{dmnsn_gl_read_canvas()} functions, respectively.
-Writing uses the @code{glDrawPixels()} GL function, and reading uses the @code{glReadPixels()} function.
-@code{dmnsn_gl_read_canvas()} starts reading at (@code{x0}, @code{y0}), and reads a @code{width}*@code{height} sized image.
-These operations should be fast (especially if optimized), so no @code{..._async()} versions are supplied.
-If it is known in advance that a canvas will be drawn to an OpenGL buffer, calling @code{dmnsn_gl_optimize_canvas()} on it before it is written to will speed up the export process; see @ref{Canvas Optimization}.
-
-@node Canvas Optimization
-@section Canvas Optimization
-
-@example
-/* Canvas optimizer callback types */
-@tindex dmnsn_canvas_optimizer_fn
-typedef void dmnsn_canvas_optimizer_fn(dmnsn_canvas *canvas,
- dmnsn_canvas_optimizer optimizer,
- unsigned int x, unsigned int y);
-
-/* Canvas optimizer */
-@tindex dmnsn_canvas_optimizer
-typedef struct @{
- dmnsn_canvas_optimizer_fn *optimizer_fn;
- dmnsn_free_fn *free_fn;
- void *ptr;
-@} dmnsn_canvas_optimizer;
-
-/* Set a canvas optimizer */
-@findex dmnsn_optimize_canvas()
-int dmnsn_optimize_canvas(dmnsn_canvas *canvas,
- dmnsn_canvas_optimizer optimizer);
-@end example
-
-@cindex optimization, canvas
-@cindex optimization, export
-If a canvas is to be exported to a different format, the export process can be sped up if the pixels are stored in the target format as they are written to a canvas.
-This is what canvas optimizers do: they register callbacks that are triggered upon a @code{dmnsn_set_pixel()} call, generally storing the color in the appropriate format for the target (sRGB for PNG, for example) in some other buffer.
-Then the exporting process is a breeze, because the canvas doesn't have to be converted to another format.
-
-The @code{dmnsn_canvas_optimizer} type stores a pointer to a callback function to be executed upon calls to @code{dmnsn_set_pixel()} in its @code{.optimizer_fn} field.
-This function should match the signature of the @code{dmnsn_canvas_optimizer_fn} type.
-Its @code{.ptr} field stores a generic pointer to any type of data the optimizer may wish to store.
-This pointer will be provided to its @code{.free_fn} callback when @code{dmnsn_delete_canvas()} is called, and may simply point to the standard library @code{free} function.
-
-To register a new canvas optimizer, the program should first check that the same optimization hasn't already been applied by examining the @code{dmnsn_canvas *}'s @code{->optimizers} array, and testing each @code{dmnsn_canvas_optimizer}'s @code{.optimizer_fn} for equality with the address of the new callback.
-If the optimization hasn't yet been applied, the program should call @code{dmnsn_optimize_canvas()}, which returns 0 if it succeeded, and nonzero otherwise.
-Note that this function will fail if @code{dmnsn_set_pixel()} has ever been called on the target canvas, since pixels which have already been set would not be known to the optimizer.
-
-@node Objects
-@chapter Objects
-
-@example
-@tindex dmnsn_object *
-typedef struct @{
- /* Surface properties */
- dmnsn_texture *texture;
-
- /* Transformation matrix */
- dmnsn_matrix trans, trans_inv;
-
- /* Bounding box */
- dmnsn_vector min, max;
-
- /* Callback functions */
- dmnsn_object_intersection_fn *intersection_fn;
- dmnsn_object_inside_fn *inside_fn;
- dmnsn_free_fn *free_fn;
-
- /* Generic pointer for object info */
- void *ptr;
-@} dmnsn_object;
-
-/* Object callback types */
-@tindex dmnsn_object_intersections_fn
-typedef dmnsn_intersection *
-dmnsn_object_intersection_fn(const dmnsn_object *object,
- dmnsn_line line);
-@tindex dmnsn_object_inside_fn
-typedef bool dmnsn_object_inside_fn(const dmnsn_object *object,
- dmnsn_vector point);
-
-/* Allocate a dummy object */
-@findex dmnsn_new_object()
-dmnsn_object *dmnsn_new_object();
-@findex dmnsn_delete_object()
-void dmnsn_delete_object(dmnsn_object *object);
-@end example
-
-@cindex object
-The Dimension Library renders 3-D objects, represented by the @code{dmnsn_object *} type.
-This type has callback functions for determining if and where a ray intersects the object, and whether a point is inside the object.
-In the future, many more callbacks will be added.
-libdimension comes with a few simple object types like spheres and cubes, or you may create your own by customizing the object callbacks.
-The field @code{->ptr} is a void pointer which may be used to store additional information about an object.
-The @code{->trans} field is a transformation matrix, transforming the rays which intersect the object, rather than the object itself.
-Thus, @code{->trans} should be set to the inverse of the transformations you wish to apply to the object.
-
-@cindex object callbacks
-The @code{->intersection_fn} callback should point to a function with the same signature as the @code{dmnsn_object_intersection_fn} type.
-It should return a @code{dmnsn_intersection *} corresponding to the closest intersection, or @code{NULL} if the ray does not intersect the object.
-
-The @code{->inside_fn} callback should point to a function matching the signature of the @code{dmnsn_object_inside_fn} type.
-It should return 0 if the given @code{point} is outside the object, and nonzero when that point is inside the object.
-The callback is free to return any value in the case that the point lies directly on the surface of the object.
-
-@menu
-* Spheres:: Spheres
-* Cubes:: Cubes
-@end menu
-
-@node Spheres
-@section Spheres
-
-@example
-@findex dmnsn_new_sphere()
-dmnsn_object *dmnsn_new_sphere();
-@end example
-
-@cindex sphere
-The Dimension Library has a few built-in basic shape primitives.
-One of them is the sphere; @code{dmnsn_new_sphere()} returns a sphere of radius 1, centered at the origin.
-Use the object's transformation matrix to scale, translate, and/or rotate it.
-
-@node Cubes
-@section Cubes
-
-@example
-@findex dmnsn_new_cube()
-dmnsn_object *dmnsn_new_cube();
-@end example
-
-@cindex cube
-@code{dmnsn_new_cube()} returns a cube, axis-aligned, from (-1, -1, -1) to (1, 1, 1).
-Use its transformation matrix to scale, translate, and/or rotate it.
-
-
-@node Cameras
-@chapter Cameras
-
-@example
-@tindex dmnsn_camera *
-typedef struct @{
- /* Callback functions */
- dmnsn_camera_ray_fn *ray_fn;
- dmnsn_free_fn *free_fn;
-
- /* Generic pointer for camera info */
- void *ptr;
-@} dmnsn_camera;
-
-/* Camera callback types */
-@tindex dmnsn_camera_ray_fn
-typedef dmnsn_line dmnsn_camera_ray_fn(const dmnsn_camera *camera,
- double x, double y);
-
-@findex dmnsn_new_camera()
-dmnsn_camera *dmnsn_new_camera();
-@findex dmnsn_delete_camera()
-void dmnsn_delete_camera(dmnsn_camera *camera);
-@end example
-
-@cindex camera
-In order to project a 3-D scene onto a 2-D plane, the Dimension Library uses a generic camera type.
-A camera provides the Dimension Library the camera ray corresponding to each pixel in the canvas, by its @code{->ray_fn} callback.
-
-@code{->ray_fn} should point to a function matching the signature of the type @code{dmnsn_camera_ray_fn}, and should return the ray corresponding to the pixel at (@code{x}, @code{y}) in a hypothetical square canvas from (0, 0) to (1, 1).
-
-@menu
-* Perspective Cameras:: Simple perspective cameras
-@end menu
-
-@node Perspective Cameras
-@section Perspective Cameras
-
-@example
-@findex dmnsn_new_perspective_camera()
-dmnsn_camera *dmnsn_new_perspective_camera();
-
-/* Get or set the transformation matrix */
-dmnsn_matrix
-dmnsn_get_perspective_camera_trans(const dmnsn_camera *camera);
-void dmnsn_set_perspective_camera_trans(dmnsn_camera *camera,
- dmnsn_matrix T);
-@end example
-
-@cindex perspective
-The function @code{dmnsn_new_perspective_camera} creates a perspective camera, situated at the origin, looking toward (0, 0, 1), and aiming at a screen from (-0.5, -0.5) to (0.5, 0.5) on the z = 1 plane.
-Camera rays may be transformed by a matrix set by @code{dmnsn_set_perspective_camera_trans()} and retrieved by @code{dmnsn_get_perspective_camera_trans()}.
-
-
-@node Scenes
-@chapter Scenes
-
-@example
-
-enum @{
- DMNSN_RENDER_NONE = /* ... */,
- DMNSN_RENDER_PIGMENT = /* ... */,
- DMNSN_RENDER_LIGHTS = /* ... */,
- DMNSN_RENDER_FINISH = /* ... */,
- DMNSN_RENDER_TRANSLUCENCY = /* ... */,
- DMNSN_RENDER_REFLECTION = /* ... */,
- DMNSN_RENDER_FULL = ~DMNSN_RENDER_NONE
-@};
-
-@tindex dmnsn_quality
-typedef unsigned int dmnsn_quality;
-
-@tindex dmnsn_scene *
-typedef struct @{
- /* World attributes */
- dmnsn_color background;
- dmnsn_texture *default_texture;
-
- /* Camera */
- dmnsn_camera *camera;
-
- /* Canvas */
- dmnsn_canvas *canvas;
-
- /* Objects */
- dmnsn_array *objects;
-
- /* Lights */
- dmnsn_array *lights;
-
- /* Rendering quality */
- dmnsn_quality quality;
-
- /* Recursion limit */
- unsigned int limit;
-
- /* Number of paralell threads */
- unsigned int nthreads;
-@} dmnsn_scene;
-
-@findex dmnsn_new_scene()
-dmnsn_scene *dmnsn_new_scene();
-@findex dmnsn_delete_scene()
-void dmnsn_delete_scene(dmnsn_scene *scene);
-@end example
-
-@cindex scene
-The @code{dmnsn_scene *} type ties all the components of a 3-D world together.
-A scene stores a background color in its @code{->background} field, a @code{dmnsn_array *} of @code{const dmnsn_object *}'s in its @code{->objects} field, a @code{dmnsn_camera *} in its @code{->camera} field, and a @code{dmnsn_canvas *} in its @code{->canvas} field.
-Scenes can be rendered, producing an image in their canvas field.
-
-@menu
-* Raytracing:: Rendering a scene by raytracing
-@end menu
-
-@node Raytracing
-@section Raytracing
-
-@example
-@findex dmnsn_raytrace_scene()
-int dmnsn_raytrace_scene(dmnsn_scene *scene);
-@findex dmnsn_raytrace_scene_async()
-dmnsn_progress *dmnsn_raytrace_scene_async(dmnsn_scene *scene);
-@end example
-
-@cindex raytracing
-The @code{dmnsn_raytrace_scene()} function renders a scene by raytracing - casting rays from the camera to objects in its view.
-The @code{..._async()} version works as described in @ref{Asynchronicity}.
-
-
-@node Type Index
-@unnumbered Type Index
-
-@printindex tp
-
-
-@node Function and Constant Index
-@unnumbered Function and Constant Index
-
-@printindex fn
-
-
-@node Concept Index
-@unnumbered Concept Index
-
-@printindex cp
-
-@bye