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_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"};
cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
cvar_t r_fog_clear = {0, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"};
cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"};
+cvar_t r_transparent_sortmindist = {CVAR_SAVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"};
cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
cvar_t r_glsl_offsetmapping_reliefmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_steps", "10", "relief mapping steps (note: too high values may be not supported by your GPU)"};
cvar_t r_glsl_offsetmapping_reliefmapping_refinesteps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_refinesteps", "5", "relief mapping refine steps (these are a binary search executed as the last step as given by r_glsl_offsetmapping_reliefmapping_steps)"};
cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
+cvar_t r_glsl_offsetmapping_lod = {CVAR_SAVE, "r_glsl_offsetmapping_lod", "0", "apply distance-based level-of-detail correction to number of offsetmappig steps, effectively making it render faster on large open-area maps"};
+cvar_t r_glsl_offsetmapping_lod_distance = {CVAR_SAVE, "r_glsl_offsetmapping_lod_distance", "32", "first LOD level distance, second level (-50% steps) is 2x of this, third (33%) - 3x etc."};
cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
cvar_t r_glsl_postprocess_uservec1 = {CVAR_SAVE, "r_glsl_postprocess_uservec1", "0 0 0 0", "a 4-component vector to pass as uservec1 to the postprocessing shader (only useful if default.glsl has been customized)"};
cvar_t r_glsl_postprocess_uservec2 = {CVAR_SAVE, "r_glsl_postprocess_uservec2", "0 0 0 0", "a 4-component vector to pass as uservec2 to the postprocessing shader (only useful if default.glsl has been customized)"};
data[2] = 128; // normal X
data[1] = 128; // normal Y
data[0] = 255; // normal Z
- data[3] = 128; // height
+ data[3] = 255; // height
r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
data[0] = 255;
data[1] = 255;
{"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
{"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
{"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
- {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
- {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
{"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
{"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
{"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
int loc_LightDir;
int loc_LightPosition;
int loc_OffsetMapping_ScaleSteps;
+ int loc_OffsetMapping_LodDistance;
+ int loc_OffsetMapping_Bias;
int loc_PixelSize;
int loc_ReflectColor;
int loc_ReflectFactor;
SHADERSTATICPARM_POSTPROCESS_USERVEC2 = 3, ///< postprocess uservec2 is enabled
SHADERSTATICPARM_POSTPROCESS_USERVEC3 = 4, ///< postprocess uservec3 is enabled
SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5, ///< postprocess uservec4 is enabled
- SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6 // use both alpha layers while blending materials, allows more advanced microblending
+ SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6, // use both alpha layers while blending materials, allows more advanced microblending
+ SHADERSTATICPARM_OFFSETMAPPING_USELOD = 7, ///< LOD for offsetmapping
};
-#define SHADERSTATICPARMS_COUNT 7
+#define SHADERSTATICPARMS_COUNT 8
static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
static int shaderstaticparms_count = 0;
if (r_glsl_postprocess_uservec4_enable.integer)
R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
}
+ if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD);
return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
}
R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC3, "USERVEC3");
R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS, "USEBOTHALPHAS");
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_OFFSETMAPPING_USELOD, "USEOFFSETMAPPING_LOD");
}
/// information about each possible shader permutation
p->loc_LightDir = qglGetUniformLocation(p->program, "LightDir");
p->loc_LightPosition = qglGetUniformLocation(p->program, "LightPosition");
p->loc_OffsetMapping_ScaleSteps = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
+ p->loc_OffsetMapping_LodDistance = qglGetUniformLocation(p->program, "OffsetMapping_LodDistance");
+ p->loc_OffsetMapping_Bias = qglGetUniformLocation(p->program, "OffsetMapping_Bias");
p->loc_PixelSize = qglGetUniformLocation(p->program, "PixelSize");
p->loc_ReflectColor = qglGetUniformLocation(p->program, "ReflectColor");
p->loc_ReflectFactor = qglGetUniformLocation(p->program, "ReflectFactor");
D3DPSREGISTER_ViewToLight = 44, // float4x4
D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
D3DPSREGISTER_NormalmapScrollBlend = 52,
- // next at 53
+ D3DPSREGISTER_OffsetMapping_LodDistance = 53,
+ D3DPSREGISTER_OffsetMapping_Bias = 54,
+ // next at 54
}
D3DPSREGISTER_t;
permutation |= SHADERPERMUTATION_SPECULAR;
if (texturemode == GL_MODULATE)
permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
- permutation |= SHADERPERMUTATION_GAMMARAMPS;
else if (texturemode == GL_ADD)
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)
+ permutation |= SHADERPERMUTATION_GAMMARAMPS;
if (!second)
texturemode = GL_MODULATE;
if (vid.allowalphatocoverage)
}
else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
{
- if (r_glsl_offsetmapping.integer)
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
{
switch(rsurface.texture->offsetmapping)
{
}
else if (rsurfacepass == RSURFPASS_RTLIGHT)
{
- if (r_glsl_offsetmapping.integer)
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
{
switch(rsurface.texture->offsetmapping)
{
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
{
- if (r_glsl_offsetmapping.integer)
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
{
switch(rsurface.texture->offsetmapping)
{
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
{
- if (r_glsl_offsetmapping.integer)
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
{
switch(rsurface.texture->offsetmapping)
{
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
{
- if (r_glsl_offsetmapping.integer)
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
{
switch(rsurface.texture->offsetmapping)
{
}
else
{
- if (r_glsl_offsetmapping.integer)
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
{
switch(rsurface.texture->offsetmapping)
{
// additive passes are only darkened by fog, not tinted
hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
- hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
}
else
{
hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
- hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
if (mode == SHADERMODE_WATER)
hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
}
1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
);
+ hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer);
+ hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
// additive passes are only darkened by fog, not tinted
if (r_glsl_permutation->loc_FogColor >= 0)
qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
}
else
{
if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
}
if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
);
+ if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer);
+ if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegridmatrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);}
// additive passes are only darkened by fog, not tinted
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
- DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
}
else
{
DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
- DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
}
{Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, rsurface.texture->offsetbias);
DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
- hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
if (r_glsl_permutation->loc_DeferredColor_Specular >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Specular , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f( r_glsl_permutation->loc_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f( r_glsl_permutation->loc_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f( r_glsl_permutation->loc_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f( r_glsl_permutation->loc_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height);
DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Specular , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
- DPSOFTRAST_Uniform1f( DPSOFTRAST_UNIFORM_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ DPSOFTRAST_Uniform1f( DPSOFTRAST_UNIFORM_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
for (item = r_skinframe.hash[hashindex];item;item = item->next)
- if (!strcmp(item->basename, basename) && item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)
+ if (!strcmp(item->basename, basename) && (comparecrc < 0 || (item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)))
break;
if (!item) {
memset(item, 0, sizeof(*item));
strlcpy(item->basename, basename, sizeof(item->basename));
item->base = dyntexture; // either NULL or dyntexture handle
- item->textureflags = textureflags;
+ item->textureflags = textureflags & ~TEXF_FORCE_RELOAD;
item->comparewidth = comparewidth;
item->compareheight = compareheight;
item->comparecrc = comparecrc;
item->next = r_skinframe.hash[hashindex];
r_skinframe.hash[hashindex] = item;
}
+ else if (textureflags & TEXF_FORCE_RELOAD)
+ {
+ rtexture_t *dyntexture;
+ // check whether its a dynamic texture
+ 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;
+ }
else if( item->base == NULL )
{
rtexture_t *dyntexture;
// we've got some pixels to store, so really allocate this new texture now
if (!skinframe)
skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, true);
+ textureflags &= ~TEXF_FORCE_RELOAD;
skinframe->stain = NULL;
skinframe->merged = NULL;
skinframe->base = NULL;
mymiplevel = savemiplevel;
if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, false, &mymiplevel)))
{
- skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_gloss.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+ skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (gl_texturecompression_gloss.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
#ifndef USE_GLES2
if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
return NULL;
// if already loaded just return it, otherwise make a new skinframe
- skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height*4) : 0, true);
+ skinframe = R_SkinFrame_Find(name, textureflags, width, height, (textureflags & TEXF_FORCE_RELOAD) ? -1 : skindata ? CRC_Block(skindata, width*height*4) : 0, true);
if (skinframe && skinframe->base)
return skinframe;
+ textureflags &= ~TEXF_FORCE_RELOAD;
skinframe->stain = NULL;
skinframe->merged = NULL;
skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
if (skinframe && skinframe->base)
return skinframe;
+ textureflags &= ~TEXF_FORCE_RELOAD;
skinframe->stain = NULL;
skinframe->merged = NULL;
skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
if (skinframe && skinframe->base)
return skinframe;
+ textureflags &= ~TEXF_FORCE_RELOAD;
skinframe->stain = NULL;
skinframe->merged = NULL;
Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
Cvar_RegisterVariable(&r_cullentities_trace_enlarge);
Cvar_RegisterVariable(&r_cullentities_trace_delay);
+ Cvar_RegisterVariable(&r_sortentities);
Cvar_RegisterVariable(&r_drawviewmodel);
Cvar_RegisterVariable(&r_drawexteriormodel);
Cvar_RegisterVariable(&r_speeds);
Cvar_RegisterVariable(&r_fog_clear);
Cvar_RegisterVariable(&r_drawfog);
Cvar_RegisterVariable(&r_transparentdepthmasking);
+ Cvar_RegisterVariable(&r_transparent_sortmindist);
Cvar_RegisterVariable(&r_transparent_sortmaxdist);
Cvar_RegisterVariable(&r_transparent_sortarraysize);
Cvar_RegisterVariable(&r_texture_dds_load);
Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping_steps);
Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping_refinesteps);
Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
+ Cvar_RegisterVariable(&r_glsl_offsetmapping_lod);
+ Cvar_RegisterVariable(&r_glsl_offsetmapping_lod_distance);
Cvar_RegisterVariable(&r_glsl_postprocess);
Cvar_RegisterVariable(&r_glsl_postprocess_uservec1);
Cvar_RegisterVariable(&r_glsl_postprocess_uservec2);
matrix4x4_t r_waterscrollmatrix;
-void R_UpdateFogColor(void) // needs to be called before HDR subrender too, as that changes colorscale!
+void R_UpdateFog(void) // needs to be called before HDR subrender too, as that changes colorscale!
{
- if (r_refdef.fog_density)
- {
- r_refdef.fogcolor[0] = r_refdef.fog_red;
- r_refdef.fogcolor[1] = r_refdef.fog_green;
- r_refdef.fogcolor[2] = r_refdef.fog_blue;
-
- Vector4Set(r_refdef.fogplane, 0, 0, 1, -r_refdef.fog_height);
- r_refdef.fogplaneviewdist = DotProduct(r_refdef.fogplane, r_refdef.view.origin) + r_refdef.fogplane[3];
- r_refdef.fogplaneviewabove = r_refdef.fogplaneviewdist >= 0;
- r_refdef.fogheightfade = -0.5f/max(0.125f, r_refdef.fog_fadedepth);
-
- {
- vec3_t fogvec;
- VectorCopy(r_refdef.fogcolor, fogvec);
- // color.rgb *= ContrastBoost * SceneBrightness;
- VectorScale(fogvec, r_refdef.view.colorscale, fogvec);
- r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
- r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
- r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
- }
- }
-}
-
-void R_UpdateVariables(void)
-{
- R_Textures_Frame();
-
- r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f);
-
- r_refdef.farclip = r_farclip_base.value;
- if (r_refdef.scene.worldmodel)
- r_refdef.farclip += r_refdef.scene.worldmodel->radius * r_farclip_world.value * 2;
- r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f);
-
- if (r_shadow_frontsidecasting.integer < 0 || r_shadow_frontsidecasting.integer > 1)
- Cvar_SetValueQuick(&r_shadow_frontsidecasting, 1);
- r_refdef.polygonfactor = 0;
- r_refdef.polygonoffset = 0;
- r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
- r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
-
- r_refdef.scene.rtworld = r_shadow_realtime_world.integer != 0;
- r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil;
- r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
- r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
- r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
- if (FAKELIGHT_ENABLED)
- {
- r_refdef.lightmapintensity *= r_fakelight_intensity.value;
- }
- if (r_showsurfaces.integer)
- {
- r_refdef.scene.rtworld = false;
- r_refdef.scene.rtworldshadows = false;
- r_refdef.scene.rtdlight = false;
- r_refdef.scene.rtdlightshadows = false;
- r_refdef.lightmapintensity = 0;
- }
-
+ // Nehahra fog
if (gamemode == GAME_NEHAHRA)
{
if (gl_fogenable.integer)
}
}
+ // fog parms
r_refdef.fog_alpha = bound(0, r_refdef.fog_alpha, 1);
r_refdef.fog_start = max(0, r_refdef.fog_start);
r_refdef.fog_end = max(r_refdef.fog_start + 0.01, r_refdef.fog_end);
- // R_UpdateFogColor(); // why? R_RenderScene does it anyway
-
if (r_refdef.fog_density && r_drawfog.integer)
{
r_refdef.fogenabled = true;
else
r_refdef.fogenabled = false;
+ // fog color
+ if (r_refdef.fog_density)
+ {
+ r_refdef.fogcolor[0] = r_refdef.fog_red;
+ r_refdef.fogcolor[1] = r_refdef.fog_green;
+ r_refdef.fogcolor[2] = r_refdef.fog_blue;
+
+ Vector4Set(r_refdef.fogplane, 0, 0, 1, -r_refdef.fog_height);
+ r_refdef.fogplaneviewdist = DotProduct(r_refdef.fogplane, r_refdef.view.origin) + r_refdef.fogplane[3];
+ r_refdef.fogplaneviewabove = r_refdef.fogplaneviewdist >= 0;
+ r_refdef.fogheightfade = -0.5f/max(0.125f, r_refdef.fog_fadedepth);
+
+ {
+ vec3_t fogvec;
+ VectorCopy(r_refdef.fogcolor, fogvec);
+ // color.rgb *= ContrastBoost * SceneBrightness;
+ VectorScale(fogvec, r_refdef.view.colorscale, fogvec);
+ r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
+ r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
+ r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
+ }
+ }
+}
+
+void R_UpdateVariables(void)
+{
+ R_Textures_Frame();
+
+ r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f);
+
+ r_refdef.farclip = r_farclip_base.value;
+ if (r_refdef.scene.worldmodel)
+ r_refdef.farclip += r_refdef.scene.worldmodel->radius * r_farclip_world.value * 2;
+ r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f);
+
+ if (r_shadow_frontsidecasting.integer < 0 || r_shadow_frontsidecasting.integer > 1)
+ Cvar_SetValueQuick(&r_shadow_frontsidecasting, 1);
+ r_refdef.polygonfactor = 0;
+ r_refdef.polygonoffset = 0;
+ r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
+ r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
+
+ r_refdef.scene.rtworld = r_shadow_realtime_world.integer != 0;
+ r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil;
+ r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
+ r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
+ r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+ if (FAKELIGHT_ENABLED)
+ {
+ r_refdef.lightmapintensity *= r_fakelight_intensity.value;
+ }
+ if (r_showsurfaces.integer)
+ {
+ r_refdef.scene.rtworld = false;
+ r_refdef.scene.rtworldshadows = false;
+ r_refdef.scene.rtdlight = false;
+ r_refdef.scene.rtdlightshadows = false;
+ r_refdef.lightmapintensity = 0;
+ }
+
switch(vid.renderpath)
{
case RENDERPATH_GL20:
}
}
+int R_SortEntities_Compare(const void *ap, const void *bp)
+{
+ const entity_render_t *a = *(const entity_render_t **)ap;
+ const entity_render_t *b = *(const entity_render_t **)bp;
+
+ // 1. compare model
+ if(a->model < b->model)
+ return -1;
+ if(a->model > b->model)
+ return +1;
+
+ // 2. compare skin
+ // TODO possibly calculate the REAL skinnum here first using
+ // skinscenes?
+ if(a->skinnum < b->skinnum)
+ return -1;
+ if(a->skinnum > b->skinnum)
+ return +1;
+
+ // everything we compared is equal
+ return 0;
+}
+void R_SortEntities(void)
+{
+ // below or equal 2 ents, sorting never gains anything
+ if(r_refdef.scene.numentities <= 2)
+ return;
+ // sort
+ qsort(r_refdef.scene.entities, r_refdef.scene.numentities, sizeof(*r_refdef.scene.entities), R_SortEntities_Compare);
+}
+
/*
================
R_RenderView
if (!r_drawentities.integer)
r_refdef.scene.numentities = 0;
+ else if (r_sortentities.integer)
+ R_SortEntities();
R_AnimCache_ClearCache();
R_FrameData_NewFrame();
r_refdef.stats.renders++;
- R_UpdateFogColor();
+ R_UpdateFog();
// don't let sound skip if going slow
if (r_refdef.scene.extraupdate)
}
t->specularscale *= t->specularscalemod;
t->specularpower *= t->specularpowermod;
+ t->rtlightambient = 0;
// lightmaps mode looks bad with dlights using actual texturing, so turn
// off the colormap and glossmap, but leave the normalmap on as it still