-static unsigned int intblocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*3]; // LordHavoc: *3 for colored lighting
-static float floatblocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*3]; // LordHavoc: *3 for colored lighting
-
-static qbyte templight[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*4];
-
-cvar_t r_ambient = {0, "r_ambient", "0"};
-cvar_t r_drawportals = {0, "r_drawportals", "0"};
-cvar_t r_testvis = {0, "r_testvis", "0"};
-cvar_t r_floatbuildlightmap = {0, "r_floatbuildlightmap", "0"};
-cvar_t r_detailtextures = {CVAR_SAVE, "r_detailtextures", "1"};
-cvar_t r_surfaceworldnode = {0, "r_surfaceworldnode", "0"};
-cvar_t r_drawcollisionbrushes_polygonfactor = {0, "r_drawcollisionbrushes_polygonfactor", "-1"};
-cvar_t r_drawcollisionbrushes_polygonoffset = {0, "r_drawcollisionbrushes_polygonoffset", "0"};
-cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0"};
-cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"};
-
-static int dlightdivtable[32768];
-
-static int R_IntAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surf)
-{
- int sdtable[256], lnum, td, maxdist, maxdist2, maxdist3, i, s, t, smax, tmax, smax3, red, green, blue, lit, dist2, impacts, impactt, subtract, k;
- unsigned int *bl;
- float dist, impact[3], local[3];
- dlight_t *light;
-
- lit = false;
-
- smax = (surf->extents[0] >> 4) + 1;
- tmax = (surf->extents[1] >> 4) + 1;
- smax3 = smax * 3;
-
- for (lnum = 0, light = r_dlight;lnum < r_numdlights;lnum++, light++)
- {
- if (!(surf->dlightbits[lnum >> 5] & (1 << (lnum & 31))))
- continue; // not lit by this light
-
- Matrix4x4_Transform(matrix, light->origin, local);
- dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
-
- // for comparisons to minimum acceptable light
- // compensate for LIGHTOFFSET
- maxdist = (int) light->rtlight.lightmap_cullradius2 + LIGHTOFFSET;
-
- dist2 = dist * dist;
- dist2 += LIGHTOFFSET;
- if (dist2 >= maxdist)
- continue;
-
- if (surf->plane->type < 3)
- {
- VectorCopy(local, impact);
- impact[surf->plane->type] -= dist;
- }
- else
- {
- impact[0] = local[0] - surf->plane->normal[0] * dist;
- impact[1] = local[1] - surf->plane->normal[1] * dist;
- impact[2] = local[2] - surf->plane->normal[2] * dist;
- }
-
- impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
- impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
-
- s = bound(0, impacts, smax * 16) - impacts;
- t = bound(0, impactt, tmax * 16) - impactt;
- i = s * s + t * t + dist2;
- if (i > maxdist)
- continue;
-
- // reduce calculations
- for (s = 0, i = impacts; s < smax; s++, i -= 16)
- sdtable[s] = i * i + dist2;
-
- maxdist3 = maxdist - dist2;
-
- // convert to 8.8 blocklights format
- red = light->rtlight.lightmap_light[0] * (1.0f / 128.0f);
- green = light->rtlight.lightmap_light[1] * (1.0f / 128.0f);
- blue = light->rtlight.lightmap_light[2] * (1.0f / 128.0f);
- subtract = (int) (light->rtlight.lightmap_subtract * 4194304.0f);
- bl = intblocklights;
-
- i = impactt;
- for (t = 0;t < tmax;t++, i -= 16)
- {
- td = i * i;
- // make sure some part of it is visible on this line
- if (td < maxdist3)
- {
- maxdist2 = maxdist - td;
- for (s = 0;s < smax;s++)
- {
- if (sdtable[s] < maxdist2)
- {
- k = dlightdivtable[(sdtable[s] + td) >> 7] - subtract;
- if (k > 0)
- {
- bl[0] += (red * k);
- bl[1] += (green * k);
- bl[2] += (blue * k);
- lit = true;
- }
- }
- bl += 3;
- }
- }
- else // skip line
- bl += smax3;
- }
- }
- return lit;
-}
-
-static int R_FloatAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surf)
-{
- int lnum, s, t, smax, tmax, smax3, lit, impacts, impactt;
- float sdtable[256], *bl, k, dist, dist2, maxdist, maxdist2, maxdist3, td1, td, red, green, blue, impact[3], local[3], subtract;
- dlight_t *light;
-
- lit = false;
-
- smax = (surf->extents[0] >> 4) + 1;
- tmax = (surf->extents[1] >> 4) + 1;
- smax3 = smax * 3;
-
- for (lnum = 0, light = r_dlight;lnum < r_numdlights;lnum++, light++)
- {
- if (!(surf->dlightbits[lnum >> 5] & (1 << (lnum & 31))))
- continue; // not lit by this light
-
- Matrix4x4_Transform(matrix, light->origin, local);
- dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
-
- // for comparisons to minimum acceptable light
- // compensate for LIGHTOFFSET
- maxdist = (int) light->rtlight.lightmap_cullradius2 + LIGHTOFFSET;
-
- dist2 = dist * dist;
- dist2 += LIGHTOFFSET;
- if (dist2 >= maxdist)
- continue;
-
- if (surf->plane->type < 3)
- {
- VectorCopy(local, impact);
- impact[surf->plane->type] -= dist;
- }
- else
- {
- impact[0] = local[0] - surf->plane->normal[0] * dist;
- impact[1] = local[1] - surf->plane->normal[1] * dist;
- impact[2] = local[2] - surf->plane->normal[2] * dist;
- }
-
- impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
- impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
-
- td = bound(0, impacts, smax * 16) - impacts;
- td1 = bound(0, impactt, tmax * 16) - impactt;
- td = td * td + td1 * td1 + dist2;
- if (td > maxdist)
- continue;
-
- // reduce calculations
- for (s = 0, td1 = impacts; s < smax; s++, td1 -= 16.0f)
- sdtable[s] = td1 * td1 + dist2;
-
- maxdist3 = maxdist - dist2;
-
- // convert to 8.8 blocklights format
- red = light->rtlight.lightmap_light[0];
- green = light->rtlight.lightmap_light[1];
- blue = light->rtlight.lightmap_light[2];
- subtract = light->rtlight.lightmap_subtract * 32768.0f;
- bl = floatblocklights;
-
- td1 = impactt;
- for (t = 0;t < tmax;t++, td1 -= 16.0f)
- {
- td = td1 * td1;
- // make sure some part of it is visible on this line
- if (td < maxdist3)
- {
- maxdist2 = maxdist - td;
- for (s = 0;s < smax;s++)
- {
- if (sdtable[s] < maxdist2)
- {
- k = (32768.0f / (sdtable[s] + td)) - subtract;
- bl[0] += red * k;
- bl[1] += green * k;
- bl[2] += blue * k;
- lit = true;
- }
- bl += 3;
- }
- }
- else // skip line
- bl += smax3;
- }
- }
- return lit;
-}
+cvar_t r_ambient = {0, "r_ambient", "0", "brighter world cheat (not allowed in multiplayer), value is 0-128"};
+cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
+cvar_t r_lockpvs = {0, "r_lockpvs", "0", "disables pvs switching, allows you to walk around and inspect what is visible from a given location in the map (anything not visible from your current location will not be drawn)"};
+cvar_t r_lockvisibility = {0, "r_lockvisibility", "0", "disables visibility updates, allows you to walk around and inspect what is visible from a given viewpoint in the map (anything offscreen at the moment this is enabled will not be drawn)"};
+cvar_t r_useportalculling = {0, "r_useportalculling", "1", "use advanced portal culling visibility method to improve performance over just Potentially Visible Set, provides an even more significant speed improvement in unvised maps"};
+cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0", "draws sky depth masking in q3 maps (as in q1 maps), this means for example that sky polygons can hide other things"};
+
+// flag arrays used for visibility checking on world model
+// (all other entities have no per-surface/per-leaf visibility checks)
+// TODO: dynamic resize according to r_refdef.worldmodel->brush.num_clusters
+unsigned char r_pvsbits[(32768+7)>>3];
+// TODO: dynamic resize according to r_refdef.worldmodel->brush.num_leafs
+unsigned char r_worldleafvisible[32768];
+// TODO: dynamic resize according to r_refdef.worldmodel->num_surfaces
+unsigned char r_worldsurfacevisible[262144];
+// if true, the view is currently in a leaf without pvs data
+qboolean r_worldnovis;