Cvar_RegisterVariable(&r_shadow_worldshadows);
Cvar_RegisterVariable(&r_shadow_dlightshadows);
Cvar_RegisterVariable(&r_shadow_showtris);
+ if (gamemode == GAME_TENEBRAE)
+ {
+ Cvar_SetValue("r_shadow_gloss", 2);
+ Cvar_SetValue("r_shadow_bumpscale_basetexture", 4);
+ }
Cmd_AddCommand("r_shadow_help", R_Shadow_Help_f);
R_Shadow_EditLights_Init();
R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap);
R_Mesh_State_Texture(&m);
GL_Color(0, 0, 0, 1);
qglCullFace(GL_FRONT); // quake is backwards, this culls back faces
- qglDisable(GL_SCISSOR_TEST);
+ GL_Scissor(r_refdef.x, r_refdef.y, r_refdef.width, r_refdef.height);
r_shadowstage = SHADOWSTAGE_NONE;
c_rt_lights = c_rt_clears = c_rt_scissored = 0;
//qglDisable(GL_POLYGON_OFFSET_FILL);
GL_Color(1, 1, 1, 1);
qglColorMask(1, 1, 1, 1);
- qglDisable(GL_SCISSOR_TEST);
+ GL_Scissor(r_refdef.x, r_refdef.y, r_refdef.width, r_refdef.height);
qglDepthFunc(GL_LEQUAL);
qglCullFace(GL_FRONT); // quake is backwards, this culls back faces
qglDisable(GL_STENCIL_TEST);
// (?!? seems like a driver bug) so abort if gl_stencil is false
if (!gl_stencil || BoxesOverlap(r_vieworigin, r_vieworigin, mins, maxs))
{
- qglDisable(GL_SCISSOR_TEST);
+ GL_Scissor(r_refdef.x, r_refdef.y, r_refdef.width, r_refdef.height);
return false;
}
for (i = 0;i < 3;i++)
if (ix2 <= ix1 || iy2 <= iy1)
return true;
// set up the scissor rectangle
- qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1);
- qglEnable(GL_SCISSOR_TEST);
+ GL_Scissor(ix1, vid.realheight - iy2, ix2 - ix1, iy2 - iy1);
+ //qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1);
+ //qglEnable(GL_SCISSOR_TEST);
c_rt_scissored++;
return false;
}
static int lightpvsbytes;
static qbyte lightpvs[(MAX_MAP_LEAFS + 7)/ 8];
+static qbyte lightfullpvs[(MAX_MAP_LEAFS + 7)/ 8];
typedef struct cubemapinfo_s
{
e->meshchain_light = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, true, false, true);
if (cl.worldmodel)
{
+ lightpvsbytes = cl.worldmodel->brush.FatPVS(cl.worldmodel, origin, 0, lightfullpvs, sizeof(lightfullpvs));
+ memset(lightpvs, 0, lightpvsbytes);
if (cl.worldmodel->brushq3.num_leafs)
{
q3mleaf_t *leaf;
q3mface_t *face;
- lightpvsbytes = cl.worldmodel->brush.FatPVS(cl.worldmodel, origin, 0, lightpvs, sizeof(lightpvs));
+
+ // make a pvs that only includes things within the box
+ for (i = 0, leaf = cl.worldmodel->brushq3.data_leafs;i < cl.worldmodel->brushq3.num_leafs;i++, leaf++)
+ if (CHECKPVSBIT(lightfullpvs, leaf->clusterindex) && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
+ SETPVSBIT(lightpvs, leaf->clusterindex);
+
+ // make a cluster list for fast visibility checking during rendering
+ for (i = 0, e->numclusters = 0;i < cl.worldmodel->brush.num_pvsclusters;i++)
+ if (CHECKPVSBIT(lightpvs, i))
+ e->numclusters++;
+ e->clusterindices = Mem_Alloc(r_shadow_mempool, e->numclusters * sizeof(int));
+ for (i = 0, e->numclusters = 0;i < cl.worldmodel->brush.num_pvsclusters;i++)
+ if (CHECKPVSBIT(lightpvs, i))
+ e->clusterindices[e->numclusters++] = i;
+
VectorCopy(e->origin, e->mins);
VectorCopy(e->origin, e->maxs);
for (i = 0, face = cl.worldmodel->brushq3.data_thismodel->firstface;i < cl.worldmodel->brushq3.data_thismodel->numfaces;i++, face++)
face->lighttemp_castshadow = false;
for (i = 0, leaf = cl.worldmodel->brushq3.data_leafs;i < cl.worldmodel->brushq3.num_leafs;i++, leaf++)
{
- if ((leaf->clusterindex < 0 || lightpvs[leaf->clusterindex >> 3] & (1 << (leaf->clusterindex & 7))) && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
+ if (CHECKPVSBIT(lightpvs, leaf->clusterindex) && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
{
for (k = 0;k < 3;k++)
{
}
}
}
- else if (cl.worldmodel->brushq1.numleafs)
+ else if (cl.worldmodel->brushq1.num_leafs)
{
mleaf_t *leaf;
msurface_t *surf;
qbyte *byteleafpvs;
qbyte *bytesurfacepvs;
- byteleafpvs = Mem_Alloc(tempmempool, cl.worldmodel->brushq1.numleafs);
+ byteleafpvs = Mem_Alloc(tempmempool, cl.worldmodel->brushq1.num_leafs);
bytesurfacepvs = Mem_Alloc(tempmempool, cl.worldmodel->brushq1.numsurfaces);
Portal_Visibility(cl.worldmodel, e->origin, byteleafpvs, bytesurfacepvs, NULL, 0, true, mins, maxs, e->mins, e->maxs);
- for (i = 0, leaf = cl.worldmodel->brushq1.leafs;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
+ // make a pvs that only includes things within the box
+ for (i = 0, leaf = cl.worldmodel->brushq1.data_leafs;i < cl.worldmodel->brushq1.num_leafs;i++, leaf++)
{
if (byteleafpvs[i] && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
{
+ SETPVSBIT(lightpvs, leaf->clusterindex);
for (k = 0;k < 3;k++)
{
if (e->mins[k] > leaf->mins[k]) e->mins[k] = leaf->mins[k];
}
}
}
-
+
for (i = 0, surf = cl.worldmodel->brushq1.surfaces;i < cl.worldmodel->brushq1.numsurfaces;i++, surf++)
if (bytesurfacepvs[i] && BoxesOverlap(surf->poly_mins, surf->poly_maxs, mins, maxs))
surf->lighttemp_castshadow = true;
Mem_Free(byteleafpvs);
Mem_Free(bytesurfacepvs);
+
+ // make a cluster list for fast visibility checking during rendering
+ for (i = 0, e->numclusters = 0;i < cl.worldmodel->brush.num_pvsclusters;i++)
+ if (CHECKPVSBIT(lightpvs, i))
+ e->numclusters++;
+ e->clusterindices = Mem_Alloc(r_shadow_mempool, e->numclusters * sizeof(int));
+ for (i = 0, e->numclusters = 0;i < cl.worldmodel->brush.num_pvsclusters;i++)
+ if (CHECKPVSBIT(lightpvs, i))
+ e->clusterindices[e->numclusters++] = i;
}
else
{
- lightpvsbytes = cl.worldmodel->brush.FatPVS(cl.worldmodel, origin, 0, lightpvs, sizeof(lightpvs));
- for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.visleafs;i++, leaf++)
+ for (i = 0, leaf = cl.worldmodel->brushq1.data_leafs;i < cl.worldmodel->brushq1.num_leafs;i++, leaf++)
{
- if (lightpvs[i >> 3] & (1 << (i & 7)) && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
+ if (CHECKPVSBIT(lightfullpvs, leaf->clusterindex) && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
{
+ // make a pvs that only includes things within the box
+ SETPVSBIT(lightpvs, leaf->clusterindex);
for (k = 0;k < 3;k++)
{
if (e->mins[k] > leaf->mins[k]) e->mins[k] = leaf->mins[k];
}
}
}
+
+ // make a pvs that only includes things within the box
+ for (i = 0, leaf = cl.worldmodel->brushq1.data_leafs;i < cl.worldmodel->brushq1.num_leafs;i++, leaf++)
+ if (CHECKPVSBIT(lightfullpvs, leaf->clusterindex) && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
+ SETPVSBIT(lightpvs, leaf->clusterindex);
+
+ // make a cluster list for fast visibility checking during rendering
+ for (i = 0, e->numclusters = 0;i < cl.worldmodel->brush.num_pvsclusters;i++)
+ if (CHECKPVSBIT(lightpvs, i))
+ e->numclusters++;
+ e->clusterindices = Mem_Alloc(r_shadow_mempool, e->numclusters * sizeof(int));
+ for (i = 0, e->numclusters = 0;i < cl.worldmodel->brush.num_pvsclusters;i++)
+ if (CHECKPVSBIT(lightpvs, i))
+ e->clusterindices[e->numclusters++] = i;
}
// add surfaces to shadow casting mesh and light mesh
if (e->meshchain_light)
for (mesh = e->meshchain_light;mesh;mesh = mesh->next)
l += mesh->numtriangles;
- Con_Printf("static light built: %f %f %f : %f %f %f box, %i shadow volume triangles, %i light triangles\n", e->mins[0], e->mins[1], e->mins[2], e->maxs[0], e->maxs[1], e->maxs[2], k, l);
+ Con_DPrintf("static light built: %f %f %f : %f %f %f box, %i shadow volume triangles, %i light triangles\n", e->mins[0], e->mins[1], e->mins[2], e->maxs[0], e->maxs[1], e->maxs[2], k, l);
}
void R_Shadow_FreeWorldLight(worldlight_t *light)
void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
{
- int entnum, style, islight;
+ int entnum, style, islight, skin, pflags;
char key[256], value[1024];
- float origin[3], radius, color[3], light, fadescale, lightscale, originhack[3], overridecolor[3];
+ float origin[3], angles[3], radius, color[3], light, fadescale, lightscale, originhack[3], overridecolor[3];
const char *data;
if (cl.worldmodel == NULL)
light = 0;
origin[0] = origin[1] = origin[2] = 0;
originhack[0] = originhack[1] = originhack[2] = 0;
+ angles[0] = angles[1] = angles[2] = 0;
color[0] = color[1] = color[2] = 1;
overridecolor[0] = overridecolor[1] = overridecolor[2] = 1;
fadescale = 1;
lightscale = 1;
style = 0;
+ skin = 0;
+ pflags = 0;
islight = false;
while (1)
{
light = atof(value);
else if (!strcmp("origin", key))
sscanf(value, "%f %f %f", &origin[0], &origin[1], &origin[2]);
+ else if (!strcmp("angle", key))
+ angles[0] = 0, angles[1] = atof(value), angles[2] = 0;
+ else if (!strcmp("angles", key))
+ sscanf(value, "%f %f %f", &angles[0], &angles[1], &angles[2]);
else if (!strcmp("color", key))
sscanf(value, "%f %f %f", &color[0], &color[1], &color[2]);
else if (!strcmp("wait", key))
if (!strcmp("fade", key))
fadescale = atof(value);
}
+ else if (!strcmp("skin", key))
+ skin = (int)atof(value);
+ else if (!strcmp("pflags", key))
+ pflags = (int)atof(value);
}
if (light <= 0 && islight)
light = 300;
VectorScale(color, light, color);
VectorAdd(origin, originhack, origin);
if (radius >= 15)
- R_Shadow_NewWorldLight(origin, vec3_origin, color, radius, 0, style, true, NULL);
+ R_Shadow_NewWorldLight(origin, angles, color, radius, !!(pflags & 2), style, !(pflags & 1), skin >= 16 ? va("cubemaps/%i", skin) : NULL);
}
}