/** * @brief Adds the specified static light source after first ensuring that it * can not be merged with any known sources. */ static void R_AddBspLight(r_bsp_model_t *bsp, vec3_t origin, vec3_t color, vec_t radius) { if (radius <= 0.0) { Com_Debug(DEBUG_RENDERER, "Bad radius: %f\n", radius); return; } if (r_lighting->value) { // scale by r_lighting->value, if enabled radius *= r_lighting->value; } r_bsp_light_t *bl = NULL; GSList *e = r_bsp_light_state.lights; while (e) { vec3_t delta; bl = (r_bsp_light_t *) e->data; VectorSubtract(origin, bl->light.origin, delta); if (VectorLength(delta) <= BSP_LIGHT_MERGE_THRESHOLD) { // merge them break; } bl = NULL; e = e->next; } if (!bl) { // or allocate a new one bl = Mem_LinkMalloc(sizeof(*bl), bsp); r_bsp_light_state.lights = g_slist_prepend(r_bsp_light_state.lights, bl); VectorCopy(origin, bl->light.origin); bl->leaf = R_LeafForPoint(bl->light.origin, bsp); } bl->count++; bl->light.radius = ((bl->light.radius * (bl->count - 1)) + radius) / bl->count; VectorMix(bl->light.color, color, 1.0 / bl->count, bl->light.color); bl->debug.type = PARTICLE_CORONA; bl->debug.color[3] = 1.0; bl->debug.blend = GL_ONE; }
/* * @brief Copies the specified particle into the view structure, provided it * passes a basic visibility test. */ void R_AddParticle(const r_particle_t *p) { static r_element_t e; if (r_view.num_particles >= MAX_PARTICLES) return; if (p->type != PARTICLE_BEAM) { if (R_LeafForPoint(p->org, NULL)->vis_frame != r_locals.vis_frame) { return; } } r_view.particles[r_view.num_particles++] = *p; e.type = ELEMENT_PARTICLE; e.element = (const void *) p; e.origin = (const vec_t *) p->org; R_AddElement(&e); }
/** * @brief Developer tool for viewing static BSP light sources. */ void R_DrawBspLights(void) { if (!r_draw_bsp_lights->value) { return; } r_bsp_light_t *bl = r_model_state.world->bsp->bsp_lights; for (uint16_t i = 0; i < r_model_state.world->bsp->num_bsp_lights; i++, bl++) { const r_bsp_leaf_t *l = R_LeafForPoint(bl->light.origin, NULL); if (l->vis_frame != r_locals.vis_frame) { continue; } VectorCopy(bl->light.origin, bl->debug.org); VectorCopy(bl->light.color, bl->debug.color); bl->debug.scale = bl->light.radius * r_draw_bsp_lights->value; R_AddParticle(&bl->debug); } }
/* * R_AddBspLight * * Adds the specified static light source to the world model, after first * ensuring that it can not be merged with any known sources. */ static void R_AddBspLight(vec3_t org, float radius, vec3_t color) { r_bsp_light_t *l; vec3_t delta; int i; if (radius <= 0.0) { Com_Debug("R_AddBspLight: Bad radius: %f\n", radius); return; } l = r_load_model->bsp_lights; for (i = 0; i < r_load_model->num_bsp_lights; i++, l++) { VectorSubtract(org, l->origin, delta); if (VectorLength(delta) <= 32.0) // merge them break; } if (i == r_load_model->num_bsp_lights) { // or allocate a new one l = (r_bsp_light_t *) R_HunkAlloc(sizeof(*l)); if (!r_load_model->bsp_lights) // first source r_load_model->bsp_lights = l; VectorCopy(org, l->origin); l->leaf = R_LeafForPoint(l->origin, r_load_model); r_load_model->num_bsp_lights++; } l->count++; l->radius = ((l->radius * (l->count - 1)) + radius) / l->count; VectorMix(l->color, color, 1.0 / l->count, l->color); }
il.type = type; il.light = *light; il.diffuse = diffuse / lengthof(r_lighting_points); R_AddIllumination(&il); return true; } /** * @brief Adds illuminations for static (BSP) light sources. */ static void R_StaticIlluminations(r_lighting_t *l) { byte pvs[MAX_BSP_LEAFS >> 3]; const r_bsp_leaf_t *leaf = R_LeafForPoint(l->origin, NULL); Cm_ClusterPVS(leaf->cluster, pvs); const r_bsp_light_t *bl = r_model_state.world->bsp->bsp_lights; for (uint16_t i = 0; i < r_model_state.world->bsp->num_bsp_lights; i++, bl++) { const int16_t cluster = bl->leaf->cluster; if (cluster != -1) { if ((pvs[cluster >> 3] & (1 << (cluster & 7))) == 0) { continue; } } R_PositionalIllumination(l, ILLUM_STATIC, (const r_light_t *) & (bl->light)); }