cvar_t r_glsl_vertextextureblend_usebothalphas = {CF_CLIENT | CF_ARCHIVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer, requires mod_q3shader_force_terrain_alphaflag on."};
+// FIXME: This cvar would grow to a ridiculous size after several launches and clean exits when used during surface sorting.
cvar_t r_framedatasize = {CF_CLIENT | CF_ARCHIVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
cvar_t r_buffermegs[R_BUFFERDATA_COUNT] =
{
SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler
SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math)
SHADERSTATICPARM_CELOUTLINES = 12, ///< celoutline (depth buffer analysis to produce outlines)
- SHADERSTATICPARM_FXAA = 13 ///< fast approximate anti aliasing
+ SHADERSTATICPARM_FXAA = 13, ///< fast approximate anti aliasing
+ SHADERSTATICPARM_COLORFRINGE = 14 ///< colorfringe (chromatic aberration)
};
-#define SHADERSTATICPARMS_COUNT 14
+#define SHADERSTATICPARMS_COUNT 15
static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
static int shaderstaticparms_count = 0;
R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELSHADING);
if (r_celoutlines.integer)
R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELOUTLINES);
+ if (r_colorfringe.value)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_COLORFRINGE);
return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
}
R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING");
R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES");
R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_FXAA, "USEFXAA");
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_COLORFRINGE, "USECOLORFRINGE");
}
/// information about each possible shader permutation
r_texture_numcubemaps = 0;
//r_texture_fogintensity = NULL;
memset(&r_fb, 0, sizeof(r_fb));
- R_GLSL_Restart_f(&cmd_client);
+ R_GLSL_Restart_f(cmd_local);
r_glsl_permutation = NULL;
memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
Mod_RenderInit();
}
-int R_CullBox(const vec3_t mins, const vec3_t maxs)
+static void R_GetCornerOfBox(vec3_t out, const vec3_t mins, const vec3_t maxs, int signbits)
{
- int i;
- mplane_t *p;
- if (r_trippy.integer)
- return false;
- for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
- {
- p = r_refdef.view.frustum + i;
- switch(p->signbits)
- {
- default:
- case 0:
- if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
- return true;
- break;
- case 1:
- if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
- return true;
- break;
- case 2:
- if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
- return true;
- break;
- case 3:
- if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
- return true;
- break;
- case 4:
- if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
- return true;
- break;
- case 5:
- if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
- return true;
- break;
- case 6:
- if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
- return true;
- break;
- case 7:
- if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
- return true;
- break;
- }
- }
- return false;
+ out[0] = ((signbits & 1) ? mins : maxs)[0];
+ out[1] = ((signbits & 2) ? mins : maxs)[1];
+ out[2] = ((signbits & 4) ? mins : maxs)[2];
}
-int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
+static qbool _R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes, int ignore)
{
int i;
const mplane_t *p;
+ vec3_t corner;
if (r_trippy.integer)
return false;
for (i = 0;i < numplanes;i++)
{
+ if(i == ignore)
+ continue;
p = planes + i;
- switch(p->signbits)
- {
- default:
- case 0:
- if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
- return true;
- break;
- case 1:
- if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
- return true;
- break;
- case 2:
- if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
- return true;
- break;
- case 3:
- if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
- return true;
- break;
- case 4:
- if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
- return true;
- break;
- case 5:
- if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
- return true;
- break;
- case 6:
- if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
- return true;
- break;
- case 7:
- if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
- return true;
- break;
- }
+ R_GetCornerOfBox(corner, mins, maxs, p->signbits);
+ if (DotProduct(p->normal, corner) < p->dist)
+ return true;
}
return false;
}
+qbool R_CullFrustum(const vec3_t mins, const vec3_t maxs)
+{
+ // skip nearclip plane, it often culls portals when you are very close, and is almost never useful
+ return _R_CullBox(mins, maxs, r_refdef.view.numfrustumplanes, r_refdef.view.frustum, 4);
+}
+
+qbool R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
+{
+ // nothing to ignore
+ return _R_CullBox(mins, maxs, numplanes, planes, -1);
+}
+
//==================================================================================
// LadyHavoc: this stores temporary data used within the same frame
continue;
}
if (!(ent->flags & renderimask))
- if (!R_CullBox(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
+ if (!R_CullFrustum(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
if ((ent->flags & (RENDER_NODEPTHTEST | RENDER_WORLDOBJECT | RENDER_VIEWMODEL)) || r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, ent->mins, ent->maxs))
r_refdef.viewcache.entityvisible[i] = true;
}
{
ent = r_refdef.scene.entities[i];
if (!(ent->flags & renderimask))
- if (!R_CullBox(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
+ if (!R_CullFrustum(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
r_refdef.viewcache.entityvisible[i] = true;
}
}
rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
if(R_CompileShader_CheckStaticParms())
- R_GLSL_Restart_f(&cmd_client);
+ R_GLSL_Restart_f(cmd_local);
if (!r_drawentities.integer)
r_refdef.scene.numentities = 0;
for (i = 0; i < prog->num_edicts; i++)
{
edict = PRVM_EDICT_NUM(i);
- if (edict->priv.server->free)
+ if (edict->free)
continue;
// exclude the following for now, as they don't live in world coordinate space and can't be solid:
if (PRVM_gameedictedict(edict, tag_entity) != 0)
GL_PolygonOffset(r_refdef.polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_refdef.polygonoffset + r_showcollisionbrushes_polygonoffset.value);
for (bihleafindex = 0, bihleaf = bih->leafs;bihleafindex < bih->numleafs;bihleafindex++, bihleaf++)
{
- if (cullbox && R_CullBox(bihleaf->mins, bihleaf->maxs))
+ if (cullbox && R_CullFrustum(bihleaf->mins, bihleaf->maxs))
continue;
switch (bihleaf->type)
{
}
else if (ui)
{
- // for ui we have to preserve the order of surfaces (not using sortedmodelsurfaces)
+ // for ui we have to preserve the order of surfaces (not using modelsurfaces_sorted)
for (i = model->submodelsurfaces_start; i < model->submodelsurfaces_end; i++)
r_surfacelist[numsurfacelist++] = surfaces + i;
}