cvar_t r_shadows_drawafterrtlighting = {CVAR_SAVE, "r_shadows_drawafterrtlighting", "0", "draw fake shadows AFTER realtime lightning is drawn. May be useful for simulating fast sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows."};
cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
-cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
+cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "0.25", "higher values increase shadowmap quality at a cost of area covered (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
cvar_t r_shadows_shadowmapbias = {CVAR_SAVE, "r_shadows_shadowmapbias", "-1", "sets shadowmap bias for fake shadows. -1 sets the value of r_shadow_shadowmapping_bias. Needs shadowmapping ON."};
cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
{CVAR_SAVE, "r_buffermegs_uniform", "0.25", "uniform buffer size for one frame"},
};
-extern cvar_t v_glslgamma;
extern cvar_t v_glslgamma_2d;
extern qboolean v_flipped_state;
permutation |= SHADERPERMUTATION_GLOW;
else if (texturemode == GL_DECAL)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
+ if (usegamma && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
permutation |= SHADERPERMUTATION_GAMMARAMPS;
if (suppresstexalpha)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
R_Mesh_TexBind(GL20TU_FIRST , first );
R_Mesh_TexBind(GL20TU_SECOND, second);
if (permutation & SHADERPERMUTATION_GAMMARAMPS)
- R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
+ R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps);
#endif
break;
case RENDERPATH_D3D10:
skinframe->loadsequence = r_skinframe.loadsequence;
}
+void R_SkinFrame_PurgeSkinFrame(skinframe_t *s)
+{
+ if (s->merged == s->base)
+ s->merged = NULL;
+ R_PurgeTexture(s->stain); s->stain = NULL;
+ R_PurgeTexture(s->merged); s->merged = NULL;
+ R_PurgeTexture(s->base); s->base = NULL;
+ R_PurgeTexture(s->pants); s->pants = NULL;
+ R_PurgeTexture(s->shirt); s->shirt = NULL;
+ R_PurgeTexture(s->nmap); s->nmap = NULL;
+ R_PurgeTexture(s->gloss); s->gloss = NULL;
+ R_PurgeTexture(s->glow); s->glow = NULL;
+ R_PurgeTexture(s->fog); s->fog = NULL;
+ R_PurgeTexture(s->reflect); s->reflect = NULL;
+ s->loadsequence = 0;
+}
+
void R_SkinFrame_Purge(void)
{
int i;
for (s = r_skinframe.hash[i];s;s = s->next)
{
if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
- {
- if (s->merged == s->base)
- s->merged = NULL;
- // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
- R_PurgeTexture(s->stain );s->stain = NULL;
- R_PurgeTexture(s->merged);s->merged = NULL;
- R_PurgeTexture(s->base );s->base = NULL;
- R_PurgeTexture(s->pants );s->pants = NULL;
- R_PurgeTexture(s->shirt );s->shirt = NULL;
- R_PurgeTexture(s->nmap );s->nmap = NULL;
- R_PurgeTexture(s->gloss );s->gloss = NULL;
- R_PurgeTexture(s->glow );s->glow = NULL;
- R_PurgeTexture(s->fog );s->fog = NULL;
- R_PurgeTexture(s->reflect);s->reflect = NULL;
- s->loadsequence = 0;
- }
+ R_SkinFrame_PurgeSkinFrame(s);
}
}
}
dyntexture = CL_GetDynTexture( basename );
if (!add && !dyntexture)
return NULL;
- if (item->merged == item->base)
- item->merged = NULL;
- // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
- R_PurgeTexture(item->stain );item->stain = NULL;
- R_PurgeTexture(item->merged);item->merged = NULL;
- R_PurgeTexture(item->base );item->base = NULL;
- R_PurgeTexture(item->pants );item->pants = NULL;
- R_PurgeTexture(item->shirt );item->shirt = NULL;
- R_PurgeTexture(item->nmap );item->nmap = NULL;
- R_PurgeTexture(item->gloss );item->gloss = NULL;
- R_PurgeTexture(item->glow );item->glow = NULL;
- R_PurgeTexture(item->fog );item->fog = NULL;
- R_PurgeTexture(item->reflect);item->reflect = NULL;
- item->loadsequence = 0;
+ R_SkinFrame_PurgeSkinFrame(item);
}
else if( item->base == NULL )
{
case RENDERPATH_GL11:
case RENDERPATH_GL13:
case RENDERPATH_GLES1:
+ return; // don't bother
case RENDERPATH_GLES2:
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
Cvar_SetValueQuick(&r_damageblur, 0);
}
- if (!((r_glsl_postprocess.integer || r_fxaa.integer) || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || (v_glslgamma.integer && !vid_gammatables_trivial))
+ if (!((r_glsl_postprocess.integer || r_fxaa.integer) || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || !vid_gammatables_trivial)
&& !r_bloom.integer
&& (R_Stereo_Active() || (r_motionblur.value <= 0 && r_damageblur.value <= 0))
&& !useviewfbo
permutation =
(r_fb.bloomtexture[r_fb.bloomindex] ? SHADERPERMUTATION_BLOOM : 0)
| (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VIEWTINT : 0)
- | ((v_glslgamma.value && !vid_gammatables_trivial) ? SHADERPERMUTATION_GAMMARAMPS : 0)
+ | (!vid_gammatables_trivial ? SHADERPERMUTATION_GAMMARAMPS : 0)
| (r_glsl_postprocess.integer ? SHADERPERMUTATION_POSTPROCESSING : 0)
| ((!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) ? SHADERPERMUTATION_SATURATION : 0);
case RENDERPATH_D3D11:
case RENDERPATH_SOFT:
case RENDERPATH_GLES2:
- if(v_glslgamma.integer && !vid_gammatables_trivial)
+ if(!vid_gammatables_trivial)
{
if(!r_texture_gammaramps || vid_gammatables_serial != r_texture_gammaramps_serial)
{
void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qboolean wantnormals, qboolean wanttangents)
{
rsurface.entity = r_refdef.scene.worldentity;
+ if (r != 1.0f || g != 1.0f || b != 1.0f || a != 1.0f) {
+ // HACK to provide a valid entity with modded colors to R_GetCurrentTexture.
+ // A better approach could be making this copy only once per frame.
+ static entity_render_t custom_entity;
+ int q;
+ custom_entity = *rsurface.entity;
+ for (q = 0; q < 3; ++q) {
+ float colormod = q == 0 ? r : q == 1 ? g : b;
+ custom_entity.render_fullbright[q] *= colormod;
+ custom_entity.render_modellight_ambient[q] *= colormod;
+ custom_entity.render_modellight_diffuse[q] *= colormod;
+ custom_entity.render_lightmap_ambient[q] *= colormod;
+ custom_entity.render_lightmap_diffuse[q] *= colormod;
+ custom_entity.render_rtlight_diffuse[q] *= colormod;
+ }
+ custom_entity.alpha *= a;
+ rsurface.entity = &custom_entity;
+ }
rsurface.skeleton = NULL;
rsurface.ent_skinnum = 0;
rsurface.ent_qwskin = -1;
static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_t **texturesurfacelist)
{
+ int i, j;
// transparent sky would be ridiculous
if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
return;
skyrenderlater = true;
RSurf_SetupDepthAndCulling();
GL_DepthMask(true);
- // LordHavoc: HalfLife maps have freaky skypolys so don't use
+
+ // add the vertices of the surfaces to a world bounding box so we can scissor the sky render later
+ if (r_sky_scissor.integer)
+ {
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
+ for (i = 0; i < texturenumsurfaces; i++)
+ {
+ const msurface_t *surf = texturesurfacelist[i];
+ const float *v;
+ float p[3];
+ float mins[3], maxs[3];
+ int scissor[4];
+ for (j = 0, v = rsurface.batchvertex3f + 3 * surf->num_firstvertex; j < surf->num_vertices; j++, v += 3)
+ {
+ Matrix4x4_Transform(&rsurface.matrix, v, p);
+ if (j > 0)
+ {
+ if (mins[0] > p[0]) mins[0] = p[0];
+ if (mins[1] > p[1]) mins[1] = p[1];
+ if (mins[2] > p[2]) mins[2] = p[2];
+ if (maxs[0] < p[0]) maxs[0] = p[0];
+ if (maxs[1] < p[1]) maxs[1] = p[1];
+ if (maxs[2] < p[2]) maxs[2] = p[2];
+ }
+ else
+ {
+ VectorCopy(p, mins);
+ VectorCopy(p, maxs);
+ }
+ }
+ if (!R_ScissorForBBox(mins, maxs, scissor))
+ {
+ if (skyscissor[2])
+ {
+ if (skyscissor[0] > scissor[0])
+ {
+ skyscissor[2] += skyscissor[0] - scissor[0];
+ skyscissor[0] = scissor[0];
+ }
+ if (skyscissor[1] > scissor[1])
+ {
+ skyscissor[3] += skyscissor[1] - scissor[1];
+ skyscissor[1] = scissor[1];
+ }
+ if (skyscissor[0] + skyscissor[2] < scissor[0] + scissor[2])
+ skyscissor[2] = scissor[0] + scissor[2] - skyscissor[0];
+ if (skyscissor[1] + skyscissor[3] < scissor[1] + scissor[3])
+ skyscissor[3] = scissor[1] + scissor[3] - skyscissor[1];
+ }
+ else
+ Vector4Copy(scissor, skyscissor);
+ }
+ }
+ }
+
+ // LadyHavoc: HalfLife maps have freaky skypolys so don't use
// skymasking on them, and Quake3 never did sky masking (unlike
// software Quake and software Quake2), so disable the sky masking
// in Quake3 maps as it causes problems with q3map2 sky tricks,
// and skymasking also looks very bad when noclipping outside the
// level, so don't use it then either.
- if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.skymasking && r_q1bsp_skymasking.integer && !r_refdef.viewcache.world_novis && !r_trippy.integer)
+ if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.skymasking && (r_refdef.scene.worldmodel->brush.isq3bsp ? r_q3bsp_renderskydepth.integer : r_q1bsp_skymasking.integer) && !r_refdef.viewcache.world_novis && !r_trippy.integer)
{
R_Mesh_ResetTextureState();
if (skyrendermasked)
{
R_SetupShader_DepthOrShadow(false, false, false);
// depth-only (masking)
- GL_ColorMask(0,0,0,0);
+ GL_ColorMask(0, 0, 0, 0);
// just to make sure that braindead drivers don't draw
// anything despite that colormask...
GL_BlendFunc(GL_ZERO, GL_ONE);
texture.specularscalemod = 1;
texture.specularpowermod = 1;
texture.transparentsort = TRANSPARENTSORT_DISTANCE;
- // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS
- // JUST GREP FOR "specularscalemod = 1".
-
- for (q = 0; q < 3; q++)
- {
- texture.render_glowmod[q] = r_refdef.view.colorscale * r_hdr_glowintensity.value;
- texture.render_modellight_lightdir[q] = q == 2;
- texture.render_modellight_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity;
- texture.render_modellight_diffuse[q] = r_refdef.view.colorscale;
- texture.render_modellight_specular[q] = r_refdef.view.colorscale;
- texture.render_lightmap_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity;
- texture.render_lightmap_diffuse[q] = r_refdef.view.colorscale * r_refdef.scene.lightmapintensity;
- texture.render_lightmap_specular[q] = r_refdef.view.colorscale;
- texture.render_rtlight_diffuse[q] = r_refdef.view.colorscale;
- texture.render_rtlight_specular[q] = r_refdef.view.colorscale;
- }
- texture.currentalpha = 1.0f;
- surface.texture = &texture;
- surface.num_triangles = numtriangles;
- surface.num_firsttriangle = firsttriangle;
- surface.num_vertices = numvertices;
- surface.num_firstvertex = firstvertex;
-
- // now render it
- rsurface.texture = R_GetCurrentTexture(surface.texture);
- rsurface.lightmaptexture = NULL;
- rsurface.deluxemaptexture = NULL;
- rsurface.uselightmaptexture = false;
- R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass);
+ R_DrawCustomSurface_Texture(&texture, texmatrix, materialflags, firstvertex, numvertices, firsttriangle, numtriangles, writedepth, prepass);
}
void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass)