cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
-cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling"};
+cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling (in addition to center sample)"};
+cvar_t r_cullentities_trace_tempentitysamples = {0, "r_cullentities_trace_tempentitysamples", "-1", "number of samples to test for entity culling of temp entities (including all CSQC entities), -1 disables trace culling on these entities to prevent flicker (pvs still applies)"};
cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
unsigned int r_texture_gammaramps_serial;
//rtexture_t *r_texture_fogintensity;
-unsigned int r_queries[R_MAX_OCCLUSION_QUERIES];
+unsigned int r_queries[MAX_OCCLUSION_QUERIES];
unsigned int r_numqueries;
unsigned int r_maxqueries;
}
r_glsl_permutation_t;
-#define SHADERPERMUTATION_HASHSIZE 4096
+#define SHADERPERMUTATION_HASHSIZE 256
/// information about each possible shader permutation
r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
memset(&r_refdef.viewcache, 0, sizeof(r_refdef.viewcache));
}
-void R_Main_AllocViewCache(void)
+void R_Main_ResizeViewCache(void)
{
- memset(&r_refdef.viewcache, 0, sizeof(r_refdef.viewcache));
- r_refdef.viewcache.maxentities = r_refdef.scene.maxentities;
- if (r_refdef.viewcache.maxentities)
+ int numentities = r_refdef.scene.numentities;
+ int numclusters = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusters : 1;
+ int numclusterbytes = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusterbytes : 1;
+ int numleafs = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_leafs : 1;
+ int numsurfaces = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->num_surfaces : 1;
+ if (r_refdef.viewcache.maxentities < numentities)
+ {
+ r_refdef.viewcache.maxentities = numentities;
+ if (r_refdef.viewcache.entityvisible)
+ Mem_Free(r_refdef.viewcache.entityvisible);
r_refdef.viewcache.entityvisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.maxentities);
- if (cl.worldmodel)
- {
- r_refdef.viewcache.world_numclusters = cl.worldmodel->brush.num_pvsclusters;
- r_refdef.viewcache.world_numleafs = cl.worldmodel->brush.num_leafs;
- r_refdef.viewcache.world_numsurfaces = cl.worldmodel->num_surfaces;
- r_refdef.viewcache.world_pvsbits = Mem_Alloc(r_main_mempool, (r_refdef.viewcache.world_numclusters+7)>>3);
+ }
+ if (r_refdef.viewcache.world_numclusters != numclusters)
+ {
+ r_refdef.viewcache.world_numclusters = numclusters;
+ r_refdef.viewcache.world_numclusterbytes = numclusterbytes;
+ if (r_refdef.viewcache.world_pvsbits)
+ Mem_Free(r_refdef.viewcache.world_pvsbits);
+ r_refdef.viewcache.world_pvsbits = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numclusterbytes);
+ }
+ if (r_refdef.viewcache.world_numleafs != numleafs)
+ {
+ r_refdef.viewcache.world_numleafs = numleafs;
+ if (r_refdef.viewcache.world_leafvisible)
+ Mem_Free(r_refdef.viewcache.world_leafvisible);
r_refdef.viewcache.world_leafvisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numleafs);
+ }
+ if (r_refdef.viewcache.world_numsurfaces != numsurfaces)
+ {
+ r_refdef.viewcache.world_numsurfaces = numsurfaces;
+ if (r_refdef.viewcache.world_surfacevisible)
+ Mem_Free(r_refdef.viewcache.world_surfacevisible);
r_refdef.viewcache.world_surfacevisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numsurfaces);
}
}
void gl_main_start(void)
{
- R_Main_AllocViewCache();
-
r_numqueries = 0;
r_maxqueries = 0;
memset(r_queries, 0, sizeof(r_queries));
CL_ParseEntityLump(cl.worldmodel->brush.entities);
}
R_Main_FreeViewCache();
- R_Main_AllocViewCache();
}
void GL_Main_Init(void)
Cvar_RegisterVariable(&r_drawentities);
Cvar_RegisterVariable(&r_cullentities_trace);
Cvar_RegisterVariable(&r_cullentities_trace_samples);
+ Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
Cvar_RegisterVariable(&r_cullentities_trace_enlarge);
Cvar_RegisterVariable(&r_cullentities_trace_delay);
Cvar_RegisterVariable(&r_drawviewmodel);
typedef struct r_animcache_s
{
- r_animcache_entity_t entity[MAX_EDICTS*2];
+ r_animcache_entity_t entity[MAX_EDICTS];
int maxindex;
int currentindex;
}
static void R_View_UpdateEntityVisible (void)
{
- int i, renderimask;
+ int i;
+ int renderimask;
+ int samples;
entity_render_t *ent;
if (!r_drawentities.integer)
ent = r_refdef.scene.entities[i];
if(r_refdef.viewcache.entityvisible[i] && !(ent->flags & (RENDER_VIEWMODEL | RENDER_NOCULL | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*')))
{
- if(R_CanSeeBox(r_cullentities_trace_samples.integer, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs))
+ samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer;
+ if (samples < 0)
+ continue; // temp entities do pvs only
+ if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs))
ent->last_trace_visibility = realtime;
if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
r_refdef.viewcache.entityvisible[i] = 0;
void R_View_Update(void)
{
+ R_Main_ResizeViewCache();
R_View_SetFrustum();
R_View_WorldVisibility(r_refdef.view.useclipplane);
R_View_UpdateEntityVisible();
extern cvar_t cl_decals_bias;
extern cvar_t cl_decals_models;
+extern cvar_t cl_decals_newsystem_intensitymultiplier;
void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize)
{
matrix4x4_t projection;
continue;
if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
continue;
- if (texture->currentalpha < 1)
- continue;
if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
continue;
numvertices = surface->num_vertices;
tc[cornerindex][0] = (temp[1]+1.0f)*0.5f * (s2-s1) + s1;
tc[cornerindex][1] = (temp[2]+1.0f)*0.5f * (t2-t1) + t1;
// calculate distance fade from the projection origin
- f = a * (1.0f-fabs(temp[0]));
- f = max(0.0f, f);
+ f = a * (1.0f-fabs(temp[0])) * cl_decals_newsystem_intensitymultiplier.value;
+ f = bound(0.0f, f, 1.0f);
c[cornerindex][0] = r * f;
c[cornerindex][1] = g * f;
c[cornerindex][2] = b * f;
//VectorMA(v[cornerindex], cl_decals_bias.value, localnormal, v[cornerindex]);
}
if (dynamic)
- R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[1], v[2], tc[0], tc[1], tc[2], c[0], c[1], c[2], triangleindex);
+ R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[1], v[2], tc[0], tc[1], tc[2], c[0], c[1], c[2], triangleindex+surface->num_firsttriangle);
else
for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1);