X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=r_light.c;h=6a49a87fcf6fb8e88c10077e913ba3be9ec7a904;hp=0a3e27ff03eced79d4f817b43c99ed3f31905aad;hb=e24d834dcbcc61f28fdf0e2c1ba75693d9e23ed1;hpb=7e5eece842864c299b83206699693913cb5ca0b7 diff --git a/r_light.c b/r_light.c index 0a3e27ff..6a49a87f 100644 --- a/r_light.c +++ b/r_light.c @@ -151,7 +151,7 @@ void R_DrawCoronas(void) { rd = r_dlight + i; dist = (DotProduct(rd->origin, vpn) - viewdist); - if (dist >= 24.0f && CL_TraceLine(rd->origin, r_origin, NULL, NULL, 0, true, NULL) == 1) + if (dist >= 24.0f && CL_TraceLine(rd->origin, r_origin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1) { cscale = (1.0f / 131072.0f); scale = rd->cullradius * 0.25f; @@ -173,255 +173,111 @@ DYNAMIC LIGHTS ============================================================================= */ +static int lightpvsbytes; +static qbyte lightpvs[(MAX_MAP_LEAFS+7)>>3]; + /* ============= R_MarkLights ============= */ -static void R_OldMarkLights (entity_render_t *ent, vec3_t lightorigin, rdlight_t *rd, int bit, int bitindex, mnode_t *node) +static void R_RecursiveMarkLights(entity_render_t *ent, vec3_t lightorigin, rdlight_t *rd, int bit, int bitindex, mnode_t *node, qbyte *pvs, int pvsbits) { - float ndist, maxdist; - msurface_t *surf; - int i, *surfacepvsframes; - int d, impacts, impactt; - float dist, dist2, impact[3]; - - if (!r_dynamic.integer) - return; + int i; + mleaf_t *leaf; + float dist; // for comparisons to minimum acceptable light - maxdist = rd->cullradius2; - - surfacepvsframes = ent->model->brushq1.surfacepvsframes; -loc0: - if (node->contents < 0) - return; - - ndist = PlaneDiff(lightorigin, node->plane); - - if (ndist > rd->cullradius) - { - node = node->children[0]; - goto loc0; - } - if (ndist < -rd->cullradius) + while(node->contents >= 0) { - node = node->children[1]; - goto loc0; - } - -// mark the polygons - surf = ent->model->brushq1.surfaces + node->firstsurface; - for (i = 0;i < node->numsurfaces;i++, surf++) - { - if (surfacepvsframes[surf->number] != ent->model->brushq1.pvsframecount) - continue; - dist = ndist; - if (surf->flags & SURF_PLANEBACK) - dist = -dist; - - if (dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES)) - continue; - - dist2 = dist * dist; - if (dist2 >= maxdist) - continue; - - if (node->plane->type < 3) - { - VectorCopy(lightorigin, impact); - impact[node->plane->type] -= dist; - } + dist = PlaneDiff(lightorigin, node->plane); + if (dist > rd->cullradius) + node = node->children[0]; else { - impact[0] = lightorigin[0] - surf->plane->normal[0] * dist; - impact[1] = lightorigin[1] - surf->plane->normal[1] * dist; - impact[2] = lightorigin[2] - surf->plane->normal[2] * dist; - } - - impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; - - d = bound(0, impacts, surf->extents[0] + 16) - impacts; - dist2 += d * d; - if (dist2 > maxdist) - continue; - - impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; - - d = bound(0, impactt, surf->extents[1] + 16) - impactt; - dist2 += d * d; - if (dist2 > maxdist) - continue; - - if (surf->dlightframe != r_framecount) // not dynamic until now - { - surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; - surf->dlightframe = r_framecount; - if (r_dlightmap.integer) - surf->cached_dlight = true; + if (dist >= -rd->cullradius) + R_RecursiveMarkLights(ent, lightorigin, rd, bit, bitindex, node->children[0], pvs, pvsbits); + node = node->children[1]; } - surf->dlightbits[bitindex] |= bit; } - if (node->children[0]->contents >= 0) + // check if leaf is visible according to pvs + leaf = (mleaf_t *)node; + i = (leaf - ent->model->brushq1.leafs) - 1; + if (leaf->nummarksurfaces && (i >= pvsbits || pvs[i >> 3] & (1 << (i & 7)))) { - if (node->children[1]->contents >= 0) - { - R_OldMarkLights (ent, lightorigin, rd, bit, bitindex, node->children[0]); - node = node->children[1]; - goto loc0; - } - else + int *surfacepvsframes, d, impacts, impactt; + float sdist, maxdist, dist2, impact[3]; + msurface_t *surf; + // mark the polygons + maxdist = rd->cullradius2; + surfacepvsframes = ent->model->brushq1.surfacepvsframes; + for (i = 0;i < leaf->nummarksurfaces;i++) { - node = node->children[0]; - goto loc0; - } - } - else if (node->children[1]->contents >= 0) - { - node = node->children[1]; - goto loc0; - } -} - - -static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int bitindex) -{ - static int lightframe = 0; - mleaf_t *pvsleaf; - vec3_t lightorigin; - model_t *model; - int i, k, m, c, leafnum, *surfacepvsframes, *mark; - msurface_t *surf; - mleaf_t *leaf; - qbyte *in; - int row; - float low[3], high[3], dist, maxdist; - - if (!r_dynamic.integer || !ent->model) - return; + if (surfacepvsframes[leaf->firstmarksurface[i]] != ent->model->brushq1.pvsframecount) + continue; + surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[i]; + dist = sdist = PlaneDiff(lightorigin, surf->plane); + if (surf->flags & SURF_PLANEBACK) + dist = -dist; - Matrix4x4_Transform(&ent->inversematrix, rd->origin, lightorigin); + if (dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES)) + continue; - model = ent->model; - pvsleaf = model->brushq1.PointInLeaf(model, lightorigin); - if (pvsleaf == NULL) - return; + dist2 = dist * dist; + if (dist2 >= maxdist) + continue; - in = pvsleaf->compressed_vis; - if (!r_vismarklights.integer || !in) - { - // told not to use pvs, or there's no pvs to use - R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode); - return; - } + VectorCopy(lightorigin, impact); + if (surf->plane->type >= 3) + VectorMA(impact, -sdist, surf->plane->normal, impact); + else + impact[surf->plane->type] -= sdist; - lightframe++; + impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; - low[0] = lightorigin[0] - rd->cullradius;low[1] = lightorigin[1] - rd->cullradius;low[2] = lightorigin[2] - rd->cullradius; - high[0] = lightorigin[0] + rd->cullradius;high[1] = lightorigin[1] + rd->cullradius;high[2] = lightorigin[2] + rd->cullradius; + d = bound(0, impacts, surf->extents[0] + 16) - impacts; + dist2 += d * d; + if (dist2 > maxdist) + continue; - // for comparisons to minimum acceptable light - maxdist = rd->cullradius2; + impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; - row = (model->brushq1.numleafs+7)>>3; - surfacepvsframes = model->brushq1.surfacepvsframes; + d = bound(0, impactt, surf->extents[1] + 16) - impactt; + dist2 += d * d; + if (dist2 > maxdist) + continue; - k = 0; - while (k < row) - { - c = *in++; - if (c) - { - for (i = 0;i < 8;i++) + if (surf->dlightframe != r_framecount) // not dynamic until now { - if (c & (1< model->brushq1.numleafs) - return; - leaf = &model->brushq1.leafs[leafnum]; - if (leaf->mins[0] > high[0] || leaf->maxs[0] < low[0] - || leaf->mins[1] > high[1] || leaf->maxs[1] < low[1] - || leaf->mins[2] > high[2] || leaf->maxs[2] < low[2]) - continue; - if ((m = leaf->nummarksurfaces)) - { - mark = leaf->firstmarksurface; - do - { - surf = model->brushq1.surfaces + *mark++; - // if not visible in current frame, or already marked because it was in another leaf we passed, skip - if (surf->lightframe == lightframe) - continue; - surf->lightframe = lightframe; - if (surfacepvsframes[surf->number] != model->brushq1.pvsframecount) - continue; - dist = PlaneDiff(lightorigin, surf->plane); - if (surf->flags & SURF_PLANEBACK) - dist = -dist; - // LordHavoc: make sure it is infront of the surface and not too far away - if (dist < rd->cullradius && (dist > -0.25f || ((surf->flags & SURF_LIGHTBOTHSIDES) && dist > -rd->cullradius))) - { - int d; - int impacts, impactt; - float dist2, impact[3]; - - dist2 = dist * dist; - - if (surf->plane->type < 3) - { - VectorCopy(lightorigin, impact); - impact[surf->plane->type] -= dist; - } - else - { - impact[0] = lightorigin[0] - surf->plane->normal[0] * dist; - impact[1] = lightorigin[1] - surf->plane->normal[1] * dist; - impact[2] = lightorigin[2] - surf->plane->normal[2] * dist; - } - - impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; - d = bound(0, impacts, surf->extents[0] + 16) - impacts; - dist2 += d * d; - if (dist2 > maxdist) - continue; - - impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; - d = bound(0, impactt, surf->extents[1] + 16) - impactt; - dist2 += d * d; - if (dist2 > maxdist) - continue; - - if (surf->dlightframe != r_framecount) // not dynamic until now - { - surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; - surf->dlightframe = r_framecount; - if (r_dlightmap.integer) - surf->cached_dlight = true; - } - surf->dlightbits[bitindex] |= bit; - } - } - while (--m); - } - } + surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; + surf->dlightframe = r_framecount; + if (r_dlightmap.integer) + surf->cached_dlight = true; } - k++; - continue; + surf->dlightbits[bitindex] |= bit; } - - k += *in++; } } void R_MarkLights(entity_render_t *ent) { - int i; - if (!gl_flashblend.integer) - for (i = 0;i < r_numdlights;i++) - R_VisMarkLights (ent, r_dlight + i, 1 << (i & 31), i >> 5); + int i, bit, bitindex; + rdlight_t *rd; + vec3_t lightorigin; + if (!gl_flashblend.integer && r_dynamic.integer && ent->model && ent->model->brushq1.numleafs) + { + for (i = 0, rd = r_dlight;i < r_numdlights;i++, rd++) + { + bit = 1 << (i & 31); + bitindex = i >> 5; + Matrix4x4_Transform(&ent->inversematrix, rd->origin, lightorigin); + lightpvsbytes = 0; + if (r_vismarklights.integer && ent->model->brush.FatPVS) + lightpvsbytes = ent->model->brush.FatPVS(ent->model, lightorigin, 0, lightpvs, sizeof(lightpvs)); + R_RecursiveMarkLights(ent, lightorigin, rd, bit, bitindex, ent->model->brushq1.nodes + ent->model->brushq1.hulls[0].firstclipnode, lightpvs, min(lightpvsbytes * 8, ent->model->brushq1.visleafs)); + } + } } /* @@ -445,16 +301,6 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu else VectorSet(ambientcolor, 1, 1, 1); - /* - if (leaf == NULL && cl.worldmodel != NULL) - leaf = cl.worldmodel->brushq1.PointInLeaf(cl.worldmodel, p); - if (!leaf || leaf->contents == CONTENTS_SOLID || !cl.worldmodel->brushq1.lightdata) - { - VectorSet(ambientcolor, 1, 1, 1); - return; - } - */ - // FIXME: this .lights related stuff needs to be ported into the Mod_Q1BSP code if (cl.worldmodel->brushq1.numlights) { @@ -469,7 +315,7 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu { VectorSubtract (p, sl->origin, v); f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract); - if (f > 0 && CL_TraceLine(p, sl->origin, NULL, NULL, 0, false, NULL) == 1) + if (f > 0 && CL_TraceLine(p, sl->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) == 1) { f *= d_lightstylevalue[sl->style] * (1.0f / 65536.0f); VectorMA(ambientcolor, f, sl->light, ambientcolor); @@ -489,7 +335,7 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu rd = r_dlight + i; VectorSubtract(p, rd->origin, v); f = DotProduct(v, v); - if (f < rd->cullradius2 && CL_TraceLine(p, rd->origin, NULL, NULL, 0, false, NULL) == 1) + if (f < rd->cullradius2 && CL_TraceLine(p, rd->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) == 1) { f = (1.0f / (f + LIGHTOFFSET)) - rd->subtract; VectorMA(ambientcolor, f, rd->light, ambientcolor); @@ -612,7 +458,7 @@ int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, co VectorSubtract (v, rd->origin, v); if (DotProduct(v, v) < rd->cullradius2) { - if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, 0, false, NULL) != 1) + if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) != 1) continue; VectorSubtract (ent->origin, rd->origin, v); f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract); @@ -749,7 +595,7 @@ void R_UpdateEntLights(entity_render_t *ent) ent->numentlights = 0; if (cl.worldmodel) for (i = 0, sl = cl.worldmodel->brushq1.lights;i < cl.worldmodel->brushq1.numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++) - if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, 0, false, NULL) == 1) + if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) == 1) ent->entlights[ent->numentlights++] = i; } ent->entlightsframe = r_framecount;