#ifndef DEFOCUS_H #define DEFOCUS_H #include #ifdef __cplusplus #ifdef _MSC_VER #define DF_API extern "C" __declspec(dllexport) #else #define DF_API extern "C" #endif #else #ifdef _MSC_VER #define DF_API __declspec(dllexport) #else #define DF_API #endif #endif /* __cplusplus */ /* Useful constants */ #define DF_EPSF32 0.00001f #define DF_PIF32 3.1415926f #define DF_PI_OVER_4F32 (DF_PIF32 / 4.f) #define DF_PI_OVER_2F32 (DF_PIF32 / 2.f) #define DF_ARRAY_COUNT(A) (sizeof((A)) / sizeof((A)[0])) #define DF_UNUSED(x) ((void)sizeof((x))) /* Math stuff */ typedef struct { float x; float y; float z; } df_v3; typedef struct { float x; float y; } df_v2; typedef struct { int x; int y; } df_v2i; /* Images */ typedef unsigned int df_image_handle; DF_API df_image_handle df_load_image(const char *path, int *w, int *h); /* cameras */ typedef struct { df_v3 origin; df_v3 dir; } df_ray; /* A camera function takes the uv coordinates of the output pixel and generates a ray. * The sample index can be used to introduce some randomness for multi-sampling. */ typedef df_ray (*df_camera_fn)(float u, float v, unsigned int sample_idx, void *camera_data); typedef struct { df_v2 viewport_size; df_v3 lower_left; } df_pinhole_camera_data; DF_API df_pinhole_camera_data df_create_pinhole_camera_data(int image_width, int image_height, float focal_length); DF_API df_ray df_pinhole_camera(float u, float v, unsigned int sample_idx, void *camera_data); typedef struct { df_v2 viewport_size; df_v3 lower_left; float lens_radius; } df_thin_lense_camera_data; DF_API df_thin_lense_camera_data df_create_thin_lense_camera_data(int image_width, int image_height, float aperture, float focal_distance); DF_API df_ray df_thin_lense_camera(float u, float v, unsigned int sample_idx, void *camera_data); /* Settings for the basic ray tracing function. */ typedef struct { /* Width needs to be divisible by 4! */ int image_width; int image_height; int samples_per_pixel; df_camera_fn camera; void *camera_data; } df_trace_rays_settings; /* Sphere shape */ typedef struct { float center_x; float center_y; float center_z; float radius; } df_sphere; typedef struct { float base_x; float base_y; float base_z; float normal_x; float normal_y; float normal_z; /* Coordinates on the plane */ float img_p0_x; float img_p0_y; float img_p0_z; float img_w; float img_h; /* TODO(Kevin): These could be calculated from p0 and p1 (p0+wh)... */ float img_ax0_x; float img_ax0_y; float img_ax0_z; float img_ax1_x; float img_ax1_y; float img_ax1_z; df_image_handle image; } df_plane; DF_API float df_max_f32(const float *list, unsigned int count); /* Core function, implements raytracing. * * The result buffer receives RGB pixels, with 8 bits per channel stored in RGB order. * It is allocated via malloc(). * * Returns 1 on success, 0 if allocating the result image failed. */ DF_API int df_trace_rays(df_trace_rays_settings settings, const df_sphere *spheres, unsigned int sphere_count, const df_plane *planes, unsigned int plane_count, uint8_t **result); #endif