#ifndef LIGHT_H #define LIGHT_H #include "Algorithm/BVH.h" #include "Algorithm/Sobol.h" #include "Geometry/Triangle.h" #include "Rendering/Texture.h" #include "cglm/struct/vec3.h" struct scene_t; typedef struct { vec3s position; vec3s normal; vec3s geometric_normal; vec3s tangent; vec2s uv; vec3s wo; uint16_t bounce_depth; const struct scene_t* scene; const bvh_tree_t* bvh_tree; const texture_collection_t* textures; float spread_angle; } light_shading_context_t; typedef path_output (*evaluate_bsdf_sky_f) (const void* data, const light_shading_context_t* context, vec3s throughput, uint32_t sample_index); typedef void (*sky_free_f) (void* data); typedef struct { uint16_t data_size; void* data; evaluate_bsdf_sky_f evaluate_bsdf_sky; sky_free_f free_sky_data; } sky_light_t; typedef enum { LIGHT_TYPE_POINT, LIGHT_TYPE_SPOT, LIGHT_TYPE_AREA, } punctual_light_type_e; typedef struct { vec3s position; vec3s color; float intensity; punctual_light_type_e type; } punctual_light_t; typedef struct { vec3s direction; vec3s color; float intensity; float angular_diameter; } directional_light_t; typedef struct { uint32_t punctual_light_count; uint32_t directional_light_count; uint32_t max_punctual_lights; uint32_t max_directional_lights; sky_light_t sky_light; punctual_light_t* punctual_lights; directional_light_t* directional_lights; } light_collection_t; typedef struct { uint32_t id; bool is_punctual; } light_entity_t; inline bool light_collection_create(uint32_t max_punctual_lights, uint32_t max_directional_lights, light_collection_t* collection) { if (max_punctual_lights == 0 || max_directional_lights == 0) { return false; } collection->max_punctual_lights = max_punctual_lights; collection->max_directional_lights = max_directional_lights; collection->punctual_light_count = 0; collection->directional_light_count = 0; collection->punctual_lights = (punctual_light_t*)malloc(max_punctual_lights * sizeof(punctual_light_t)); if (collection->punctual_lights == NULL) { return false; } collection->directional_lights = (directional_light_t*)malloc(max_directional_lights * sizeof(directional_light_t)); if (collection->directional_lights == NULL) { free(collection->punctual_lights); return false; } return true; } inline light_entity_t light_create_punctual_light(light_collection_t* collection) { if (collection->punctual_light_count >= collection->max_punctual_lights) { return (light_entity_t){0}; } punctual_light_t light = {0}; collection->punctual_lights[collection->punctual_light_count] = light; light_entity_t entity = {.id = collection->punctual_light_count, .is_punctual = true}; collection->punctual_light_count++; return entity; } inline light_entity_t light_create_directional_light(light_collection_t* collection) { if (collection->directional_light_count >= collection->max_directional_lights) { return (light_entity_t){0}; } directional_light_t light = {0}; collection->directional_lights[collection->directional_light_count] = light; light_entity_t entity = {.id = collection->directional_light_count, .is_punctual = false}; collection->directional_light_count++; return entity; } inline void light_collection_free(light_collection_t* collection) { free(collection->punctual_lights); free(collection->directional_lights); if (collection->sky_light.free_sky_data != NULL) { collection->sky_light.free_sky_data(collection->sky_light.data); } free(collection->sky_light.data); collection->max_punctual_lights = 0; collection->max_directional_lights = 0; collection->punctual_light_count = 0; collection->directional_light_count = 0; collection->punctual_lights = NULL; collection->directional_lights = NULL; collection->sky_light.data = NULL; } #endif // LIGHT_H