LOTS OF CHANGES. was hoping to get revision 5000 perfect, but really that's never going to happen. this has gone on for too long now.

vulkan, wasapi, quake injector features added.
irc, avplug, cef plugins/drivers reworked/updated/added
openal reverb, doppler effects added.
'dir' console command now attempts to view clicked files.
lots of warning fixes, should now only be deprecation warnings for most targets (depending on compiler version anyway...).
SendEntity finally reworked to use flags properly.
effectinfo improved, other smc-targetted fixes.
mapcluster stuff now has support for linux.
.basebone+.baseframe now exist in ssqc.
qcc: -Fqccx supports qccx syntax, including qccx hacks. don't expect these to work in fteqw nor dp though.
qcc: rewrote function call handling to use refs rather than defs. this makes struct passing more efficient and makes the __out keyword usable with fields etc.
qccgui: can cope a little better with non-unicode files. can now represent most quake chars.
qcc: suppressed warnings from *extensions.qc

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5000 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2016-07-12 00:40:13 +00:00
parent 5920bf05fb
commit 27a59a0cbc
271 changed files with 101001 additions and 64352 deletions

View file

@ -0,0 +1,112 @@
!!cvarf r_glsl_turbscale=1
!!cvarf gl_maxdist=8192
!!cvarf gl_mindist=4
!!samps normalmap diffuse 4
!!argb reflect=0 //s_t1 is a reflection instead of diffusemap
!!argf strength=0.1 //0.1 = fairly gentle, 0.2 = big waves
!!argf fresnel=5.0 //water should be around 5
!!argf txscale=0.2 //wave strength
!!argb ripplemap=0 //s_t2 contains a ripplemap
!!arg3f tint=0.7 0.8 0.7 //some colour value
!!argb depth=0 //s_t3 is a depth image
!!arg3f fogtint=0.2 0.3 0.2 //tints as it gets deeper
#include "sys/defs.h"
layout(location=0) varying vec2 tc;
layout(location=1) varying vec4 tf;
layout(location=2) varying vec3 norm;
layout(location=3) varying vec3 eye;
#ifdef VERTEX_SHADER
void main (void)
{
tc = v_texcoord.st;
tf = ftetransform();
norm = v_normal;
eye = e_eyepos - v_position.xyz;
gl_Position = tf;
}
#endif
#ifdef FRAGMENT_SHADER
#define s_refract s_t0
#define s_reflect s_t1
#define s_ripplemap s_t2
#define s_refractdepth s_t3
void main (void)
{
vec2 stc, ntc;
vec3 n, refr, refl;
float fres;
float depth;
stc = (1.0 + (tf.xy / tf.w)) * 0.5;
//hack the texture coords slightly so that there are no obvious gaps
stc.t -= 1.5*norm.z/1080.0;
//apply q1-style warp, just for kicks
ntc.s = tc.s + sin(tc.t+e_time)*0.125;
ntc.t = tc.t + sin(tc.s+e_time)*0.125;
//generate the two wave patterns from the normalmap
n = (texture2D(s_normalmap, arg_txscale*tc + vec2(e_time*0.1, 0.0)).xyz);
n += (texture2D(s_normalmap, arg_txscale*tc - vec2(0, e_time*0.097)).xyz);
n -= 1.0 - 4.0/256.0;
if (arg_ripplemap)
n += texture2D(s_ripplemap, stc).rgb*3.0;
//the fresnel term decides how transparent the water should be
fres = pow(1.0-abs(dot(normalize(n), normalize(eye))), arg_fresnel);
if (arg_depth)
{
float far = cvar_gl_maxdist;
float near = cvar_gl_mindist;
//get depth value at the surface
float sdepth = gl_FragCoord.z;
sdepth = (2.0*near) / (far + near - sdepth * (far - near));
sdepth = mix(near, far, sdepth);
//get depth value at the ground beyond the surface.
float gdepth = texture2D(s_refractdepth, stc).x;
gdepth = (2.0*near) / (far + near - gdepth * (far - near));
if (gdepth >= 0.5)
{
gdepth = sdepth;
depth = 0.0;
}
else
{
gdepth = mix(near, far, gdepth);
depth = gdepth - sdepth;
}
//reduce the normals in shallow water (near walls, reduces the pain of linear sampling)
if (depth < 100.0)
n *= depth/100.0;
}
else
depth = 1.0;
//refraction image (and water fog, if possible)
refr = texture2D(s_refract, stc + n.st*arg_strength*cvar_r_glsl_turbscale).rgb * arg_tint;
if (arg_depth)
refr = mix(refr, arg_fogtint, min(depth/4096.0, 1.0));
//reflection/diffuse
if (arg_reflect)
refl = texture2D(s_reflect, stc - n.st*arg_strength*cvar_r_glsl_turbscale).rgb;
else
refl = texture2D(s_diffuse, ntc).xyz;
//FIXME: add specular tints
//interplate by fresnel
refr = mix(refr, refl, fres);
//done
gl_FragColor = vec4(refr, 1.0);
}
#endif

View file

@ -0,0 +1,23 @@
!!samps 1
//this shader is applies gamma/contrast/brightness to the source image, and dumps it out.
#include "sys/defs.h"
layout(location=0) varying vec2 tc;
layout(location=1) varying vec4 vc;
#ifdef VERTEX_SHADER
void main ()
{
tc = v_texcoord;
vc = v_colour;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
void main ()
{
gl_FragColor = pow(texture2D(s_t0, tc) * vc.g, vec4(vc.r)) + vc.b;
}
#endif

View file

@ -0,0 +1,101 @@
!!permu FULLBRIGHT
!!permu UPPERLOWER
//!!permu FRAMEBLEND
//!!permu SKELETAL
!!permu FOG
!!permu BUMP
!!cvarf r_glsl_offsetmapping=0
!!cvarf r_glsl_offsetmapping_scale=0.04
!!cvarf gl_specular=0
!!cvarb r_fog_exp2=true
!!samps diffuse normalmap upper lower specular fullbright
#include "sys/defs.h"
//standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
layout(location=0) varying vec2 tcbase;
layout(location=1) varying vec3 light;
#if defined(SPECULAR) || defined(OFFSETMAPPING)
layout(location=2) varying vec3 eyevector;
#endif
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
void main ()
{
vec3 n;
if (SPECULAR||OFFSETMAPPING)
{
vec3 s, t, w;
gl_Position = skeletaltransform_wnst(w,n,s,t);
vec3 eyeminusvertex = e_eyepos - w.xyz;
eyevector.x = dot(eyeminusvertex, s.xyz);
eyevector.y = dot(eyeminusvertex, t.xyz);
eyevector.z = dot(eyeminusvertex, n.xyz);
}
else
{
gl_Position = skeletaltransform_n(n);
}
float d = dot(n,e_light_dir);
if (d < 0.0) //vertex shader. this might get ugly, but I don't really want to make it per vertex.
d = 0.0; //this avoids the dark side going below the ambient level.
light = e_light_ambient + (dot(n,e_light_dir)*e_light_mul);
tcbase = v_texcoord;
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
#include "sys/offsetmapping.h"
void main ()
{
vec4 col, sp;
vec2 tc;
if (OFFSETMAPPING)
tc = offsetmap(s_normalmap, tcbase, eyevector);
else
tc = tcbase;
col = texture2D(s_diffuse, tc);
if (UPPERLOWER)
{
vec4 uc = texture2D(s_upper, tc);
col.rgb += uc.rgb*e_uppercolour*uc.a;
vec4 lc = texture2D(s_lower, tc);
col.rgb += lc.rgb*e_lowercolour*lc.a;
}
if (BUMP || SPECULAR)
{
vec3 bumps = normalize(vec3(texture2D(s_normalmap, tc)) - 0.5);
vec4 specs = texture2D(s_specular, tc);
vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0));
float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);
col.rgb += cvar_gl_specular * spec * specs.rgb;
}
col.rgb *= light;
if (FULLBRIGHT)
{
vec4 fb = texture2D(s_fullbright, tc);
// col.rgb = mix(col.rgb, fb.rgb, fb.a);
col.rgb += fb.rgb * fb.a;
}
gl_FragColor = fog4(col * e_colourident);
}
#endif

View file

@ -0,0 +1,34 @@
!!permu FOG
!!samps 2
!!cvarb r_fog_exp2=true
#include "sys/defs.h"
#include "sys/fog.h"
//regular sky shader for scrolling q1 skies
//the sky surfaces are thrown through this as-is.
#ifdef VERTEX_SHADER
varying vec3 pos;
void main ()
{
pos = v_position.xyz;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
varying vec3 pos;
void main ()
{
vec2 tccoord;
vec3 dir = pos - e_eyepos;
dir.z *= 3.0;
dir.xy /= 0.5*length(dir);
tccoord = (dir.xy + e_time*0.03125);
vec3 solid = vec3(texture2D(s_t0, tccoord));
tccoord = (dir.xy + e_time*0.0625);
vec4 clouds = texture2D(s_t1, tccoord);
gl_FragColor.rgb = fog3((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb));
gl_FragColor.a = 1.0;
}
#endif

View file

@ -0,0 +1,194 @@
!!permu FULLBRIGHT
!!permu BUMP
!!permu REFLECTCUBEMASK
!!cvarf r_glsl_offsetmapping=0.0
!!cvarf r_glsl_offsetmapping_scale=0.04
!!cvarf gl_specular=0.3
!!cvarb r_fog_exp2=true
!!samps diffuse normalmap specular fullbright lightmap
!!samps deluxmap reflectmask reflectcube
!!argb vertexlit=0
!!samps paletted 1
!!argb eightbit=0
!!permu FOG
//!!permu DELUXE
//!!permu LIGHTSTYLED //this seems to be breaking nvidia drivers if set from the engine, despite us not using it...
const bool DELUXE = false;
#define SPECULAR (cvar_gl_specular>0)
#include "sys/defs.h"
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
#include "sys/fog.h"
layout(location=1) varying vec3 eyevector;
layout(location=2) varying vec2 basetc;
layout(location=3) varying vec4 vc;
layout(location=4) varying mat3 invsurface;
#ifdef LIGHTSTYLED
//we could use an offset, but that would still need to be per-surface which would break batches
//fixme: merge attributes?
varying vec2 lm0, lm1, lm2, lm3;
#else
layout(location=0) varying vec2 lm0;
#endif
#ifdef VERTEX_SHADER
void main ()
{
if (OFFSETMAPPING || SPECULAR || REFLECTCUBEMASK)
{
vec3 eyeminusvertex = e_eyepos - v_position.xyz;
eyevector.x = dot(eyeminusvertex, v_svector.xyz);
eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
eyevector.z = dot(eyeminusvertex, v_normal.xyz);
}
if (REFLECTCUBEMASK)
{
invsurface[0] = v_svector;
invsurface[1] = v_tvector;
invsurface[2] = v_normal;
}
basetc = v_texcoord;
lm0 = v_lmcoord;
#ifdef LIGHTSTYLED
lm1 = v_lmcoord2;
lm2 = v_lmcoord3;
lm3 = v_lmcoord4;
#endif
if (arg_vertexlit)
vc = v_colour;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
//samplers
//for 8bit
#define s_colourmap s_t0
#include "sys/offsetmapping.h"
void main ()
{
//adjust texture coords for offsetmapping
vec2 tc = basetc;
if (OFFSETMAPPING)
tc = offsetmap(s_normalmap, tc, eyevector);
//yay, regular texture!
gl_FragColor = texture2D(s_diffuse, tc);
vec3 norm;
if (BUMP && (DELUXE || SPECULAR || REFLECTCUBEMASK))
norm = normalize(texture2D(s_normalmap, tc).rgb - 0.5);
else if (SPECULAR || DELUXE || REFLECTCUBEMASK)
norm = vec3(0, 0, 1); //specular lighting expects this to exist.
vec3 lightmaps;
if (arg_vertexlit)
lightmaps = vc.rgb * e_lmscale[0].rgb;
else
{
//modulate that by the lightmap(s) including deluxemap(s)
#ifdef LIGHTSTYLED
if (DELUXE)
{
lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxmap0, lm0).rgb-0.5);
lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxmap1, lm1).rgb-0.5);
lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxmap2, lm2).rgb-0.5);
lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxmap3, lm3).rgb-0.5);
}
else
{
lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;
lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb;
lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb;
lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb;
}
#else
if (arg_eightbit)
{
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
vec2 nearestlm0 = floor(lm0 * 256.0*8.0)/(256.0*8.0);
lightmaps = (texture2D(s_lightmap, nearestlm0) * e_lmscale[0]).rgb;
}
else
lightmaps = (texture2D(s_lightmap, lm0) * e_lmscale[0]).rgb;
//modulate by the bumpmap dot light
if (DELUXE)
{
vec3 delux = 2.0*(texture2D(s_deluxmap, lm0).rgb-0.5);
lightmaps *= 1.0 / max(0.25, delux.z); //counter the darkening from deluxmaps
lightmaps *= dot(norm, delux);
}
#endif
}
//add in specular, if applicable.
if (SPECULAR)
{
vec4 specs = texture2D(s_specular, tc);
vec3 halfdir;
if (DELUXE)
{
//not lightstyled...
halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_deluxmap0, lm0).rgb-0.5)); //this norm should be the deluxemap info instead
}
else
{
halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead
}
float spec = pow(max(dot(halfdir, norm), 0.0), 32.0 * specs.a);
spec *= cvar_gl_specular;
//NOTE: rtlights tend to have a *4 scaler here to over-emphasise the effect because it looks cool.
//As not all maps will have deluxemapping, and the double-cos from the light util makes everything far too dark anyway,
//we default to something that is not garish when the light value is directly infront of every single pixel.
//we can justify this difference due to the rtlight editor etc showing the *4.
gl_FragColor.rgb += spec * specs.rgb;
}
if (REFLECTCUBEMASK)
{
vec3 rtc = reflect(-eyevector, norm);
rtc = rtc.x*invsurface[0] + rtc.y*invsurface[1] + rtc.z*invsurface[2];
rtc = (m_model * vec4(rtc.xyz,0.0)).xyz;
gl_FragColor.rgb += texture2D(s_reflectmask, tc).rgb * textureCube(s_reflectcube, rtc).rgb;
}
if (arg_eightbit)
{
//FIXME: with this extra flag, half the permutations are redundant.
lightmaps *= 0.5; //counter the fact that the colourmap contains overbright values and logically ranges from 0 to 2 intead of to 1.
float pal = texture2D(s_paletted, tc).r; //the palette index. hopefully not interpolated.
lightmaps -= 1.0 / 128.0; //software rendering appears to round down, so make sure we favour the lower values instead of rounding to the nearest
gl_FragColor.r = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.r)).r; //do 3 lookups. this is to cope with lit files, would be a waste to not support those.
gl_FragColor.g = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.g)).g; //its not very softwarey, but re-palettizing is ugly.
gl_FragColor.b = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.b)).b; //without lits, it should be identical.
}
else
{
//now we have our diffuse+specular terms, modulate by lightmap values.
gl_FragColor.rgb *= lightmaps.rgb;
//add on the fullbright
if (FULLBRIGHT)
gl_FragColor.rgb += texture2D(s_fullbright, tc).rgb;
}
//entity modifiers
gl_FragColor = gl_FragColor * e_colourident;
//and finally hide it all if we're fogged.
#ifdef FOG
gl_FragColor = fog4(gl_FragColor);
#endif
}
#endif

View file

@ -0,0 +1,36 @@
!!permu FOG
!!cvarf r_wateralpha
!!cvarb r_fog_exp2=true
!!argf alpha=0
!!samps diffuse
#include "sys/defs.h"
//this is the shader that's responsible for drawing default q1 turbulant water surfaces
//this is expected to be moderately fast.
#include "sys/fog.h"
varying vec2 tc;
#ifdef VERTEX_SHADER
void main ()
{
tc = v_texcoord.st;
#ifdef FLOW
tc.s += e_time * -0.5;
#endif
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
void main ()
{
vec2 ntc;
ntc.s = tc.s + sin(tc.t+e_time)*0.125;
ntc.t = tc.t + sin(tc.s+e_time)*0.125;
vec3 ts = vec3(texture2D(s_diffuse, ntc));
if (arg_alpha != 0.0)
gl_FragColor = fog4(vec4(ts, arg_alpha));
else
gl_FragColor = fog4(vec4(ts, cvar_r_wateralpha));
}
#endif

View file

@ -0,0 +1,26 @@
//!!permu FRAMEBLEND
//!!permu SKELETAL
#include "sys/defs.h"
//standard shader used for drawing shadowmap depth.
//also used for masking off portals and other things that want depth and no colour.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
void main ()
{
gl_Position = skeletaltransform();
}
#endif
#ifdef FRAGMENT_SHADER
void main ()
{
//must always draw something, supposedly. It might as well be black.
gl_FragColor = vec4(0, 0, 0, 1);
}
#endif

View file

@ -0,0 +1,56 @@
!!argb constcolour=0
!!samps 1
layout(constant_id = 0) const int alphatest = 4;
layout(push_constant) uniform pushintf
{
vec4 colour;
} push;
//this shader is present for support for gles/gl3core contexts
//it is single-texture-with-vertex-colours, and doesn't do anything special.
//beware that a few things use this, including apparently fonts and bloom rescaling.
//its really not meant to do anything special.
#include "sys/defs.h"
layout(location=0) varying vec2 tc;
layout(location=1) varying vec4 vc;
#ifdef VERTEX_SHADER
void main ()
{
tc = v_texcoord;
if (arg_constcolour)
vc = push.colour;
else
vc = v_colour;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
void main ()
{
vec4 fc = texture2D(s_t0, tc) * vc;
if (alphatest == 4)
discard;
if (alphatest == 3)
{
if (fc.a < 0.5)
discard;
}
else if (alphatest == 2)
{
if (fc.a <= 0)
discard;
}
else if (alphatest == 1)
{
if (fc.a >= 0.5)
discard;
}
gl_FragColor = fc;
}
#endif

View file

@ -0,0 +1,34 @@
!!cvari r_menutint_inverse=0
!!cvar3f r_menutint=0.68 0.4 0.13
!!samps 1
#include "sys/defs.h"
const vec4 e_rendertexturescale = vec4(1,1,1,1);
layout(location=0) varying vec2 texcoord;
#ifdef VERTEX_SHADER
void main(void)
{
#ifdef VULKAN
texcoord.xy = v_texcoord.xy*e_rendertexturescale.xy;
#else
texcoord.x = v_texcoord.x*e_rendertexturescale.x;
texcoord.y = (1.0-v_texcoord.y)*e_rendertexturescale.y;
#endif
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
const vec3 lumfactors = vec3(0.299, 0.587, 0.114);
const vec3 invertvec = vec3(1.0, 1.0, 1.0);
void main(void)
{
vec3 texcolor = texture2D(s_t0, texcoord).rgb;
float luminance = dot(lumfactors, texcolor);
texcolor = vec3(luminance, luminance, luminance);
texcolor *= cvar_r_menutint;
texcolor = (cvar_r_menutint_inverse > 0) ? (invertvec - texcolor) : texcolor;
gl_FragColor = vec4(texcolor, 1.0);
}
#endif

View file

@ -0,0 +1,316 @@
!!samps diffuse normalmap specular shadowmap upper lower reflectmask reflectcube projectionmap
!!cvarf r_glsl_offsetmapping=0
!!cvarf gl_specular=0
!!cvarf r_glsl_offsetmapping_scale=0.04
!!cvari r_glsl_pcf=5
!!permu BUMP
!!permu UPPERLOWER
!!permu REFLECTCUBEMASK
!!argb pcf=0
!!argb spot=0
!!argb cube=0
!!permu FOG
!!cvarb r_fog_exp2=true
//!!permu FRAMEBLEND
//!!permu SKELETAL
#include "sys/defs.h"
//const bool UPPERLOWER = false;
//const bool REFLECTCUBEMASK = false;
//const bool BUMP = true;
//const float cvar_gl_specular = 1.0;
//const int cvar_r_glsl_pcf = 5;
//const float cvar_r_glsl_offsetmapping = 0.0;
//const float cvar_r_glsl_offsetmapping_scale = 0.04;
//layout(constant_id=1) const bool arg_pcf = true;
//layout(constant_id=2) const bool arg_spot = false;
//layout(constant_id=3) const bool arg_cube = false;
#define USE_ARB_SHADOW
#ifndef USE_ARB_SHADOW
//fall back on regular samplers if we must
#define sampler2DShadow sampler2D
#else
#define shadow2D texture
#endif
//this is the main shader responsible for realtime dlights.
//texture units:
//s0=diffuse, s1=normal, s2=specular, s3=shadowmap
//custom modifiers:
//PCF(shadowmap)
//CUBEPROJ(projected cubemap)
//SPOT(projected circle
//CUBESHADOW
#if 0 && defined(GL_ARB_texture_gather) && defined(PCF)
#extension GL_ARB_texture_gather : enable
#endif
//if there's no vertex normals known, disable some stuff.
//FIXME: this results in dupe permutations.
#ifdef NOBUMP
#undef SPECULAR
#undef BUMP
#undef OFFSETMAPPING
#endif
layout(location = 0) varying vec2 tc;
layout(location = 1) varying vec3 lightvector;
layout(location = 2) varying vec3 eyevector;
layout(location = 3) varying vec4 vtexprojcoord;
layout(location = 4) varying mat3 invsurface;
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
void main ()
{
vec3 n, s, t, w;
gl_Position = skeletaltransform_wnst(w,n,s,t);
tc = v_texcoord; //pass the texture coords straight through
vec3 lightminusvertex = (m_modelinv*vec4(l_lightposition,1.0)).xyz - w.xyz;
if (true)//BUMP || SPECULAR)
{
//the light direction relative to the surface normal, for bumpmapping.
lightvector.x = dot(lightminusvertex, s.xyz);
lightvector.y = dot(lightminusvertex, t.xyz);
lightvector.z = dot(lightminusvertex, n.xyz);
}
else
lightvector = lightminusvertex;
if (SPECULAR || OFFSETMAPPING || REFLECTCUBEMASK)
{
vec3 eyeminusvertex = e_eyepos - w.xyz;
eyevector.x = dot(eyeminusvertex, s.xyz);
eyevector.y = dot(eyeminusvertex, t.xyz);
eyevector.z = dot(eyeminusvertex, n.xyz);
}
if (REFLECTCUBEMASK)
{
invsurface[0] = v_svector;
invsurface[1] = v_tvector;
invsurface[2] = v_normal;
}
if (arg_pcf || arg_spot || arg_cube)
{
//for texture projections/shadowmapping on dlights
vtexprojcoord = l_cubematrix*m_model*vec4(w.xyz, 1.0);
}
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
//uniform vec4 l_shadowmapproj; //light projection matrix info
//uniform vec2 l_shadowmapscale; //xy are the texture scale, z is 1, w is the scale.
vec3 ShadowmapCoord(void)
{
if (arg_spot)
{
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
return ((vtexprojcoord.xyz-vec3(0.0,0.0,0.015))/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);
}
// else if (CUBESHADOW)
// {
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_shadowmap, shadowcoord + vec2(x,y)*texscale.xy).r
// }
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
vec3 dir = abs(vtexprojcoord.xyz);
//assume z is the major axis (ie: forward from the light)
vec3 t = vtexprojcoord.xyz;
float ma = dir.z;
vec3 axis = vec3(0.5/3.0, 0.5/2.0, 0.5);
if (dir.x > ma)
{
ma = dir.x;
t = vtexprojcoord.zyx;
axis.x = 0.5;
}
if (dir.y > ma)
{
ma = dir.y;
t = vtexprojcoord.xzy;
axis.x = 2.5/3.0;
}
//if the axis is negative, flip it.
if (t.z > 0.0)
{
axis.y = 1.5/2.0;
t.z = -t.z;
}
//we also need to pass the result through the light's projection matrix too
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
return axis + ((l_shadowmapproj.xyz*t.xyz + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z);
}
float ShadowmapFilter(void)
{
vec3 shadowcoord = ShadowmapCoord();
#if 0//def GL_ARB_texture_gather
vec2 ipart, fpart;
#define dosamp(x,y) textureGatherOffset(s_shadowmap, ipart.xy, vec2(x,y)))
vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));
vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0));
vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0));
vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0));
//we now have 4*4 results, woo
//we can just average them for 1/16th precision, but that's still limited graduations
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + //middle two rows are full strength
mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y); //top+bottom rows
return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.
#else
#ifdef USE_ARB_SHADOW
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
#define dosamp(x,y) shadow2D(s_shadowmap, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r
#else
//this will probably be a bit blocky.
#define dosamp(x,y) float(texture2D(s_shadowmap, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z)
#endif
float s = 0.0;
if (cvar_r_glsl_pcf < 5)
{
s += dosamp(0.0, 0.0);
return s;
}
else if (cvar_r_glsl_pcf < 9)
{
s += dosamp(-1.0, 0.0);
s += dosamp(0.0, -1.0);
s += dosamp(0.0, 0.0);
s += dosamp(0.0, 1.0);
s += dosamp(1.0, 0.0);
return s/5.0;
}
else
{
s += dosamp(-1.0, -1.0);
s += dosamp(-1.0, 0.0);
s += dosamp(-1.0, 1.0);
s += dosamp(0.0, -1.0);
s += dosamp(0.0, 0.0);
s += dosamp(0.0, 1.0);
s += dosamp(1.0, -1.0);
s += dosamp(1.0, 0.0);
s += dosamp(1.0, 1.0);
return s/9.0;
}
#endif
}
#include "sys/offsetmapping.h"
void main ()
{
//read raw texture samples (offsetmapping munges the tex coords first)
vec2 tcbase;
if (OFFSETMAPPING)
tcbase = offsetmap(s_normalmap, tc, eyevector);
else
tcbase = tc;
#if defined(FLAT)
vec3 bases = vec3(1.0);
#else
vec3 bases = vec3(texture2D(s_diffuse, tcbase));
#endif
if (UPPERLOWER)
{
vec4 uc = texture2D(s_upper, tcbase);
bases.rgb += uc.rgb*e_uppercolour*uc.a;
vec4 lc = texture2D(s_lower, tcbase);
bases.rgb += lc.rgb*e_lowercolour*lc.a;
}
vec3 bumps;
if (BUMP)
bumps = normalize(vec3(texture2D(s_normalmap, tcbase)) - 0.5);
else
bumps = vec3(0.0,0.0,1.0);
float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);
vec3 diff;
#ifdef NOBUMP
//surface can only support ambient lighting, even for lights that try to avoid it.
diff = bases * (l_lightcolourscale.x+l_lightcolourscale.y);
#else
vec3 nl = normalize(lightvector);
if (BUMP)
diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0));
else
{
//we still do bumpmapping even without bumps to ensure colours are always sane. light.exe does it too.
diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));
}
#endif
if (SPECULAR)
{
vec4 specs = texture2D(s_specular, tcbase);
vec3 halfdir = normalize(normalize(eyevector) + nl);
float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);
diff += l_lightcolourscale.z * spec * specs.rgb;
}
if (REFLECTCUBEMASK)
{
vec3 rtc = reflect(-eyevector, bumps);
rtc = rtc.x*invsurface[0] + rtc.y*invsurface[1] + rtc.z*invsurface[2];
rtc = (m_model * vec4(rtc.xyz,0.0)).xyz;
diff += texture2D(s_reflectmask, tcbase).rgb * textureCube(s_reflectcube, rtc).rgb;
}
if (arg_cube)
{
/*filter the colour by the cubemap projection*/
diff *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb;
}
if (arg_spot)
{
/*filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image*/
if (vtexprojcoord.w < 0.0) discard;
vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);
colorscale*=1.0-(dot(spot,spot));
}
if (arg_pcf)
{
/*filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows*/
//diff.rgb = (vtexprojcoord.xyz/vtexprojcoord.w) * 0.5 + 0.5;
colorscale *= ShadowmapFilter();
// diff = ShadowmapCoord();
}
#if defined(PROJECTION)
/*2d projection, not used*/
// diff *= texture2d(s_projectionmap, shadowcoord);
#endif
gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);
gl_FragColor.a = 1.0;
}
#endif

View file

@ -0,0 +1,94 @@
#ifdef VERTEX_SHADER
#define attribute in
#define varying out
#else
#define varying in
#endif
layout(std140, binding=0) uniform entityblock
{
mat4 m_modelviewproj;
mat4 m_model;
mat4 m_modelinv;
vec3 e_eyepos;
float e_time;
vec3 e_light_ambient; float epad1;
vec3 e_light_dir; float epad2;
vec3 e_light_mul; float epad3;
vec4 e_lmscale[4];
vec3 e_uppercolour; float epad4;
vec3 e_lowercolour; float epad5;
vec4 e_colourident;
vec4 w_fogcolours;
float w_fogdensity; float w_fogdepthbias; vec2 epad6;
};
layout(std140, binding=1) uniform lightblock
{
mat4 l_cubematrix;
vec3 l_lightposition; float lpad1;
vec3 l_lightcolour; float lpad2;
vec3 l_lightcolourscale; float l_lightradius;
vec4 l_shadowmapproj;
vec2 l_shadowmapscale; vec2 lpad3;
};
#ifdef VERTEX_SHADER
layout(location=0) attribute vec3 v_position;
layout(location=1) attribute vec2 v_texcoord;
layout(location=2) attribute vec4 v_colour;
layout(location=3) attribute vec2 v_lmcoord;
layout(location=4) attribute vec3 v_normal;
layout(location=5) attribute vec3 v_svector;
layout(location=6) attribute vec3 v_tvector;
#endif
#ifdef FRAGMENT_SHADER
layout(location=0) out vec4 outcolour;
#define gl_FragColor outcolour
#endif
#define texture2D texture
#define textureCube texture
/*defined by front-end, with bindings that suit us
uniform sampler2D s_t0;
uniform sampler2D s_t1;
uniform sampler2D s_t2;
uniform sampler2D s_t3;
uniform sampler2D s_t4;
uniform sampler2D s_t5;
uniform sampler2D s_t6;
uniform sampler2D s_t7;
uniform sampler2D s_diffuse;
uniform sampler2D s_normalmap;
uniform sampler2D s_specular;
uniform sampler2D s_upper;
uniform sampler2D s_lower;
uniform sampler2D s_fullbright;
uniform sampler2D s_paletted;
uniform sampler2D s_shadowmap;
uniform samplerCube s_projectionmap;
uniform samplerCube s_reflectcube;
uniform sampler2D s_reflectmask;
uniform sampler2D s_lightmap;
#define s_lightmap0 s_lightmap
uniform sampler2D s_deluxmap;
#define s_deluxmap0 s_deluxmap
uniform sampler2D s_lightmap1;
uniform sampler2D s_lightmap2;
uniform sampler2D s_lightmap3;
uniform sampler2D s_deluxmap1;
uniform sampler2D s_deluxmap2
uniform sampler2D s_deluxmap3;
*/
#ifdef VERTEX_SHADER
vec4 ftetransform()
{
vec4 proj = (m_modelviewproj*vec4(v_position,1.0));
proj.y *= -1;
proj.z = (proj.z + proj.w) / 2.0;
return proj;
}
#endif

View file

@ -0,0 +1,59 @@
#ifdef FRAGMENT_SHADER
#define w_fogcolour w_fogcolours.rgb
#define w_fogalpha w_fogcolours.a
vec3 fog3(in vec3 regularcolour)
{
if (!FOG)
return regularcolour;
float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
float fac = exp2(-(z * 1.442695));
fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);
return mix(w_fogcolour, regularcolour, fac);
}
vec3 fog3additive(in vec3 regularcolour)
{
if (!FOG)
return regularcolour;
float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
float fac = exp2(-(z * 1.442695));
fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);
return regularcolour * fac;
}
vec4 fog4(in vec4 regularcolour)
{
if (!FOG)
return regularcolour;
return vec4(fog3(regularcolour.rgb), 1.0) * regularcolour.a;
}
vec4 fog4additive(in vec4 regularcolour)
{
if (!FOG)
return regularcolour;
float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
float fac = exp2(-(z * 1.442695));
fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);
return regularcolour * vec4(fac, fac, fac, 1.0);
}
vec4 fog4blend(in vec4 regularcolour)
{
if (!FOG)
return regularcolour;
float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
float fac = exp2(-(z * 1.442695));
fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);
return regularcolour * vec4(1.0, 1.0, 1.0, fac);
}
#endif

View file

@ -0,0 +1,30 @@
vec2 offsetmap(sampler2D normtex, vec2 base, vec3 eyevector)
{
#if !defined(OFFSETMAPPING_SCALE)
#define OFFSETMAPPING_SCALE 1.0
#endif
if (false)//(RELIEFMAPPING)
{
float i, f;
vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * OFFSETMAPPING_SCALE * vec2(-1.0, 1.0), -1.0);
vec3 RT = vec3(vec2(base.xy/* - OffsetVector.xy*OffsetMapping_Bias*/), 1.0);
OffsetVector /= 10.0;
for(i = 1.0; i < 10.0; ++i)
RT += OffsetVector * step(texture2D(normtex, RT.xy).a, RT.z);
for(i = 0.0, f = 1.0; i < 5.0; ++i, f *= 0.5)
RT += OffsetVector * (step(texture2D(normtex, RT.xy).a, RT.z) * f - 0.5 * f);
return RT.xy;
}
else if (OFFSETMAPPING)
{
vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * OFFSETMAPPING_SCALE * vec2(-1.0, 1.0);
vec2 tc = base;
tc += OffsetVector;
OffsetVector *= 0.333;
tc -= OffsetVector * texture2D(normtex, tc).w;
tc -= OffsetVector * texture2D(normtex, tc).w;
tc -= OffsetVector * texture2D(normtex, tc).w;
return tc;
}
return base;
}

View file

@ -0,0 +1,68 @@
#ifdef SKELETAL
vec4 skeletaltransform()
{
mat3x4 wmat;
wmat = m_bones[int(v_bone.x)] * v_weight.x;
wmat += m_bones[int(v_bone.y)] * v_weight.y;
wmat += m_bones[int(v_bone.z)] * v_weight.z;
wmat += m_bones[int(v_bone.w)] * v_weight.w;
return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);
}
vec4 skeletaltransform_nst(out vec3 n, out vec3 t, out vec3 b)
{
mat3x4 wmat;
wmat = m_bones[int(v_bone.x)] * v_weight.x;
wmat += m_bones[int(v_bone.y)] * v_weight.y;
wmat += m_bones[int(v_bone.z)] * v_weight.z;
wmat += m_bones[int(v_bone.w)] * v_weight.w;
n = vec4(v_normal.xyz, 0.0) * wmat;
t = vec4(v_svector.xyz, 0.0) * wmat;
b = vec4(v_tvector.xyz, 0.0) * wmat;
return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);
}
vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b)
{
mat3x4 wmat;
wmat = m_bones[int(v_bone.x)] * v_weight.x;
wmat += m_bones[int(v_bone.y)] * v_weight.y;
wmat += m_bones[int(v_bone.z)] * v_weight.z;
wmat += m_bones[int(v_bone.w)] * v_weight.w;
n = vec4(v_normal.xyz, 0.0) * wmat;
t = vec4(v_svector.xyz, 0.0) * wmat;
b = vec4(v_tvector.xyz, 0.0) * wmat;
w = vec4(v_position.xyz, 1.0) * wmat;
return m_modelviewprojection * vec4(w, 1.0);
}
vec4 skeletaltransform_n(out vec3 n)
{
mat3x4 wmat;
wmat = m_bones[int(v_bone.x)] * v_weight.x;
wmat += m_bones[int(v_bone.y)] * v_weight.y;
wmat += m_bones[int(v_bone.z)] * v_weight.z;
wmat += m_bones[int(v_bone.w)] * v_weight.w;
n = vec4(v_normal.xyz, 0.0) * wmat;
return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);
}
#else
#define skeletaltransform ftetransform
vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b)
{
n = v_normal;
t = v_svector;
b = v_tvector;
w = v_position.xyz;
return ftetransform();
}
vec4 skeletaltransform_nst(out vec3 n, out vec3 t, out vec3 b)
{
n = v_normal;
t = v_svector;
b = v_tvector;
return ftetransform();
}
vec4 skeletaltransform_n(out vec3 n)
{
n = v_normal;
return ftetransform();
}
#endif

View file

@ -0,0 +1,37 @@
!!cvarf r_waterwarp
!!samps 3
#include "sys/defs.h"
//this is a post processing shader that is drawn fullscreen whenever the view is underwater.
//its generally expected to warp the view a little.
varying vec2 v_stc;
varying vec2 v_warp;
varying vec2 v_edge;
#ifdef VERTEX_SHADER
void main ()
{
gl_Position = ftetransform();
v_stc = vec2(v_texcoord.x, 1.0-v_texcoord.y);
v_warp.s = e_time * 0.25 + v_texcoord.s;
v_warp.t = e_time * 0.25 + v_texcoord.t;
v_edge = v_texcoord.xy;
}
#endif
#ifdef FRAGMENT_SHADER
//uniform sampler2D s_t0;/*$currentrender*/
//uniform sampler2D s_t1;/*warp image*/
//uniform sampler2D s_t2;/*edge image*/
//uniform vec4 e_rendertexturescale;
//uniform float cvar_r_waterwarp;
#define e_rendertexturescale vec4(1.0,1.0,0.0,0.0)
void main ()
{
vec2 amp = (0.010 / 0.625) * cvar_r_waterwarp * texture2D(s_t2, v_edge).rg;
vec3 offset = (texture2D(s_t1, v_warp).rgb - 0.5) * 2.0;
vec2 temp = v_stc + offset.xy * amp;
gl_FragColor = texture2D(s_t0, temp*e_rendertexturescale.st);
}
#endif